直播系统如何设计高并发推流与拉流架构?

554 阅读4分钟

直播系统如何设计高并发推流与拉流架构?

作者:Java后端开发 · 8年实战经验
日期:2025 年 6 月


一、前言

短视频与直播正深刻改变内容传播方式,实时直播系统成为电商、教育、游戏、社交等场景的核心能力。
但其技术挑战也非常大,尤其在推流(主播上传视频)拉流(观众获取视频)环节,如何支撑百万级并发用户,并保障低延迟、高可用,是系统架构设计的核心课题。

作为一名 Java 开发工程师,本文将从业务需求出发,结合架构设计和关键代码实现,逐步剖析直播系统的推流与拉流关键技术。


二、业务需求分析

1. 基本流程

  • 推流:主播端通过 RTMP、SRT、WebRTC 上传音视频流。
  • 转码/转协议:将视频转为 HLS、FLV、WebRTC 等适合不同终端的格式。
  • 拉流:观众从 CDN 或边缘节点获取直播流播放。
  • 控制面:如房间管理、鉴权、在线人数统计、弹幕互动等。

2. 技术挑战

挑战点描述
高并发上百万观众同时在线拉流
低延迟对直播互动、游戏非常关键(WebRTC 一般 < 1s)
稳定性网络抖动、节点故障不能影响体验
协议支持支持 RTMP、HLS、FLV、WebRTC 等多协议接入和播放
弹性扩展突发流量下如何自动扩缩容

三、整体架构设计

架构总览图

主播端
   ↓ (RTMP/SRT/WebRTC)
推流网关 (Nginx-RTMP / Media Server)
   ↓
转码/转协议处理
   ↓
内容分发网络 (CDN/边缘节点)
   ↓
观众端 (H5/APP/小程序)

核心组件说明

组件说明
推流网关入口服务,接收主播端上传的音视频流
转码器将视频转为不同分辨率、码流,适应不同网络
协议转换器支持 RTMP → HLS/FLV/WebRTC 等协议转换
CDN/边缘加速缓存热点流,降低主服务器压力
控制服务(Java 实现)鉴权、房间管理、用户统计、互动控制等

四、Java 控制面服务设计

1. 推流鉴权接口

主播推流前需要鉴权,防止非法推流。

请求示例:
POST /api/stream/start
{
  "roomId": "1001",
  "userId": "u123",
  "token": "xxx"
}
鉴权逻辑实现:
@PostMapping("/stream/start")
public ResponseEntity<?> startPush(@RequestBody StreamRequest request) {
    if (!authService.isValidToken(request.getUserId(), request.getToken())) {
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("非法推流请求");
    }

    String streamKey = streamService.generateStreamKey(request.getRoomId(), request.getUserId());
    return ResponseEntity.ok(Map.of("streamKey", streamKey));
}

推流地址一般为:rtmp://push.live.com/live/<streamKey>


2. 拉流地址生成接口

观众进入直播间时,需要获取拉流地址。

@GetMapping("/stream/play")
public ResponseEntity<?> getPlayUrl(@RequestParam String roomId) {
    StreamInfo info = streamService.getStreamInfo(roomId);

    Map<String, String> urls = Map.of(
        "flv", "https://cdn.live.com/live/" + info.getStreamKey() + ".flv",
        "hls", "https://cdn.live.com/live/" + info.getStreamKey() + ".m3u8",
        "webrtc", "webrtc://cdn.live.com/live/" + info.getStreamKey()
    );

    return ResponseEntity.ok(urls);
}

3. 在线人数统计(高并发)

使用 Redis 实现实时在线统计:

public void userJoinRoom(String roomId, String userId) {
    String key = "live:room:" + roomId + ":online";
    redisTemplate.opsForSet().add(key, userId);
    redisTemplate.expire(key, Duration.ofHours(1));
}

public int getOnlineUserCount(String roomId) {
    String key = "live:room:" + roomId + ":online";
    return redisTemplate.opsForSet().size(key).intValue();
}

五、推流与拉流的技术选型

协议对比

协议延迟支持平台使用场景
RTMP1~3sPC/移动端主播推流
HLS5~10s全平台大规模分发
FLV1~3sPC/H5互动直播
WebRTC<1s浏览器实时连麦/互动场景

一般策略:推流用 RTMP,拉流根据终端选择 HLS、FLV 或 WebRTC


六、高并发优化策略

1. CDN 边缘分发

  • 利用阿里云、腾讯云、七牛等 CDN 进行拉流加速。
  • 热门房间使用边缘缓存,减少源站压力。

2. 主播推流入口负载均衡

  • 多个推流节点(Nginx + RTMP Module)
  • 使用 DNS 轮询或 LVS 做入口负载均衡

3. 分布式房间服务

  • 每个直播间作为一个微服务单元部署(如使用 Kubernetes)
  • 热门房间可独立扩容(房间维度的水平伸缩)

七、未来拓展方向

1. 连麦互动支持

  • WebRTC + SFU 架构
  • Java 控制信令服务(SDP 协议协商)

2. 云端录制 + 回放

  • 推流同时录制 TS 文件
  • Java 生成 m3u8 索引,支持时移播放

3. 弹幕系统

  • Kafka + WebSocket 构建高并发弹幕管道
  • Redis 做弹幕缓存、限速控制

八、总结

直播系统的推流和拉流是典型的高并发实时系统,对带宽、延迟、稳定性要求极高。Java 在控制面服务中依然扮演着关键角色,负责:

  • 接入鉴权
  • 房间管理
  • 用户控制
  • 拉流分发
  • 数据上报与统计

而在流媒体处理方面,则需结合 C/C++、FFmpeg、Nginx-RTMP、Media Server 等高性能组件构建混合架构。