成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

直播必備!Spring Boot 實現高并發觀眾統計功能的技術方案揭秘

開發 前端
通過 Redis 的高并發處理能力,結合 Spring Boot 提供的 REST 接口和 WebSocket 推送機制,我們可以實現一個既輕量又高效的直播觀眾統計系統。

隨著直播平臺用戶數量激增,實時觀眾統計功能成為衡量直播間熱度和服務質量的核心指標之一。然而,在高并發場景下,如何保證統計數據的準確性與系統性能,是一個關鍵技術挑戰。本文將深入探討如何基于 Spring Boot 框架,構建一個支持高并發、低延遲、可擴展的觀眾統計系統。

系統需求分析

功能需求

  • 實時統計每個直播間的在線觀眾人數。
  • 支持觀眾進入、退出時的即時更新。
  • 提供 REST API 接口供前端定時拉取或后端推送使用。
  • 支持 WebSocket 實時推送觀眾人數變化。

技術挑戰

  • 并發量高:直播高峰期間同一直播間可能存在上萬并發連接。
  • 數據一致性:進入、退出直播間事件頻繁,需精準計算。
  • 系統性能:避免頻繁操作數據庫導致性能瓶頸。

系統架構設計

+----------------+         +------------------+         +------------------+
|  Web Frontend  | <-----> |  Spring Boot API | <-----> | Redis In-Memory  |
|  (WebSocket)   |         |  + WebSocket     |         |    Store         |
+----------------+         +------------------+         +------------------+
                                                              |
                                                              v
                                                      +---------------+
                                                      |  MySQL (持久化) |
                                                      +---------------+

核心組件

  • Spring Boot API:提供 REST 接口與 WebSocket 服務。
  • Redis:作為高性能計數器,用于記錄各直播間實時觀眾數。
  • MySQL:作為歷史數據的持久化存儲。

技術實現方案(含代碼)

Redis 結構設計

  • 使用 Hash + Set 結構保存直播間觀眾信息。
Key: live:room:{roomId}:viewers
Type: Set
Value: 用戶唯一標識(userId 或 sessionId)


Key: live:room:{roomId}:viewerCount
Type: String
Value: 當前觀眾人數

用戶進入/退出直播間邏輯

我們通過 Redis 的 Set 來記錄唯一用戶 ID,同時通過計數器確保人數準確。

@Service
public class LiveViewerService {


    @Autowired
    private StringRedisTemplate redisTemplate;


    private static final String VIEWER_SET_KEY = "live:room:%s:viewers";
    private static final String COUNT_KEY = "live:room:%s:viewerCount";


    /**
     * 用戶進入直播間
     */
    public void userEnter(String roomId, String userId) {
        String viewerSetKey = String.format(VIEWER_SET_KEY, roomId);
        String countKey = String.format(COUNT_KEY, roomId);


        // 添加用戶到觀眾集合
        Boolean isNew = redisTemplate.opsForSet().add(viewerSetKey, userId) == 1;
        if (isNew) {
            // 若是新用戶,人數 +1
            redisTemplate.opsForValue().increment(countKey);
        }
    }


    /**
     * 用戶退出直播間
     */
    public void userExit(String roomId, String userId) {
        String viewerSetKey = String.format(VIEWER_SET_KEY, roomId);
        String countKey = String.format(COUNT_KEY, roomId);


        // 移除用戶
        Boolean removed = redisTemplate.opsForSet().remove(viewerSetKey, userId) == 1;
        if (removed) {
            redisTemplate.opsForValue().decrement(countKey);
        }
    }


    /**
     * 獲取直播間當前觀眾人數
     */
    public Long getViewerCount(String roomId) {
        String countKey = String.format(COUNT_KEY, roomId);
        String count = redisTemplate.opsForValue().get(countKey);
        return count == null ? 0 : Long.parseLong(count);
    }
}
REST 接口示例
@RestController
@RequestMapping("/api/live")
public class LiveController {


    @Autowired
    private LiveViewerService viewerService;


    @PostMapping("/enter")
    public ResponseEntity<String> enter(@RequestParam String roomId, @RequestParam String userId) {
        viewerService.userEnter(roomId, userId);
        return ResponseEntity.ok("entered");
    }


    @PostMapping("/exit")
    public ResponseEntity<String> exit(@RequestParam String roomId, @RequestParam String userId) {
        viewerService.userExit(roomId, userId);
        return ResponseEntity.ok("exited");
    }


    @GetMapping("/count")
    public ResponseEntity<Long> getCount(@RequestParam String roomId) {
        return ResponseEntity.ok(viewerService.getViewerCount(roomId));
    }
}

WebSocket 實時推送實現

@ServerEndpoint("/ws/viewerCount/{roomId}")
@Component
public class ViewerCountWebSocket {


    private static Map<String, Set<Session>> roomSessions = new ConcurrentHashMap<>();


    @OnOpen
    public void onOpen(Session session, @PathParam("roomId") String roomId) {
        roomSessions.computeIfAbsent(roomId, k -> ConcurrentHashMap.newKeySet()).add(session);
    }


    @OnClose
    public void onClose(Session session, @PathParam("roomId") String roomId) {
        Set<Session> sessions = roomSessions.get(roomId);
        if (sessions != null) {
            sessions.remove(session);
        }
    }


    public static void broadcastViewerCount(String roomId, Long count) {
        Set<Session> sessions = roomSessions.get(roomId);
        if (sessions != null) {
            for (Session session : sessions) {
                session.getAsyncRemote().sendText(count.toString());
            }
        }
    }
}

在 LiveViewerService 中用戶每次進入或退出后,調用:

ViewerCountWebSocket.broadcastViewerCount(roomId, getViewerCount(roomId));

即可實時推送更新。

前端集成示例 (Thymeleaf + JavaScript)

<script>
  const roomId = "10001";
  const socket = new WebSocket("ws://localhost:8080/ws/viewerCount/" + roomId);


  socket.onmessage = function(event) {
    document.getElementById("viewerCount").innerText = event.data;
  };
</script>
<span>當前觀眾人數:<strong id="viewerCount">0</strong></span>

系統優化建議

  • Redis 原子性保障:使用 Lua 腳本處理計數與集合操作,避免競態。
  • 斷開連接處理:使用心跳機制或定時任務清理無效連接。
  • Redis 過期策略:為每個 Set 設置過期時間,避免垃圾數據堆積。
  • 數據持久化:定期將統計數據寫入數據庫,供歷史分析使用。

總結

通過 Redis 的高并發處理能力,結合 Spring Boot 提供的 REST 接口和 WebSocket 推送機制,我們可以實現一個既輕量又高效的直播觀眾統計系統。該方案不僅能應對大量用戶同時在線的場景,還具備良好的可擴展性與實時性,是現代直播平臺不可或缺的基礎能力。

責任編輯:武曉燕 來源: 路條編程
相關推薦

2025-02-10 08:20:09

2024-08-01 11:38:40

2022-03-31 17:38:09

高并發系統架構設計負載均衡

2024-03-14 08:57:04

高并發緩存更新

2025-05-14 04:00:00

2024-10-31 09:04:20

Spring高并發

2025-06-12 02:00:00

Spring簽到打卡

2024-01-04 18:01:55

高并發SpringBoot

2024-10-15 16:01:19

SpringBoot緩存預熱

2022-02-08 17:07:54

Spring BooSpring Aop日志記錄

2023-04-17 23:49:09

開發代碼Java

2019-12-25 09:49:12

WebKitWindowsChrome

2019-01-24 09:42:55

系統高并發面試

2025-06-19 07:33:40

Springresources讀取

2025-05-27 03:33:00

Spring高并發接口

2012-04-24 09:30:57

淘寶開發

2022-01-26 07:01:00

開源社區項目

2021-07-19 09:25:19

數據庫MySQL技術

2024-08-29 09:01:39

2024-09-10 10:42:27

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文在线一区二区 | 久草免费在线视频 | av中文字幕在线播放 | 99re在线视频观看 | 成人欧美一区二区三区1314 | 久久国品片 | 一区二区三区免费 | 久久久久久999 | 91精品国产一区二区在线观看 | 欧美日韩专区 | 午夜精| 国产精品永久免费视频 | 精品视频一区二区三区在线观看 | 一区二区三区在线播放 | 久久久精品久久久 | 亚洲欧美中文字幕 | 国产成人午夜电影网 | 亚洲一区二区三区高清 | 国产午夜亚洲精品不卡 | 一区二区三区在线观看免费视频 | 国产精品99久久久久久久vr | 久久国产精品亚洲 | 成人深夜福利 | 精品一区久久 | 成人精品国产免费网站 | 国产视频一区二区三区四区五区 | 亚洲精品一区二区网址 | 久久精品福利视频 | 天堂成人国产精品一区 | 超级黄色一级片 | 精品精品 | 日韩精品成人 | 日屁网站 | 欧美精品福利 | 亚洲麻豆 | 人人玩人人添人人澡欧美 | 国产一区二区中文字幕 | 毛片区| 精品成人免费视频 | 美日韩免费视频 | 久久99精品国产 |