十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SRS Proxy 能力全解析:无状态媒体流反向代理与内置负载均衡

SRS Proxy 能力全解析:无状态媒体流反向代理与内置负载均衡 SRS Proxy 能力全解析无状态媒体流反向代理与内置负载均衡【免费下载链接】srsSRS is a simple, high-performance, AI-driven real-time media server supporting RTMP, WebRTC, HLS, HTTP-FLV, HTTP-TS, SRT, MPEG-DASH, and GB28181, with codec support for H.264, H.265, AV1, VP9, AAC, Opus, and G.711.项目地址: https://gitcode.com/GitHub_Trending/sr/srsSRS ProxyGo 实现签名SRSX当前版本 SRS 8.0.x是一个无状态stateless媒体流反向代理它接收客户端连接只解析协议中足以提取流 URL 的最小信息通过内置负载均衡器挑选后端 Origin 源站然后双向转发字节。本文以 proxy/features.md 为骨架结合 proxy-design.md、proxy-protocol.md、proxy-usage.md 与源码系统梳理六大协议代理、HTTP API、负载均衡、后端注册、部署模式、配置与运维生命周期并指出当前已知限制帮助你在生产环境中正确部署与排障。核心定位一句话代理只转发字节不做缓存、不做转码——真正推流、转封装、出 HLS/FLV/WebRTC 的工作全部由后端 Origin 完成代理的职责是把每个协议的请求路由到能服务它的源站。一、总体架构与设计哲学1.1 为什么是无状态从 features.md 的定义看代理是stateless media-streaming reverse proxy with built-in load balancing接收客户端连接 → 解析出流 URL → 经负载均衡器挑选后端 → 转发字节。它不缓存流、不转码因此所有路由状态都活在客户端请求里多个代理之间无需任何状态同步即可各自独立工作RTMP 场景。在 proxy-design.md 中给出的一级链路为Client → Proxy (with Load Balancer) → Backend Origin Servers因为无状态可以横向扩展多个代理前面挂一个四层负载均衡器如 AWS NLBClient → AWS NLB → Proxy Servers → Backend Origin Servers1.2 六大并行服务器由 internal/bootstrap/proxy.go 的startServers可见启动顺序依次为RTMP 代理、WebRTC 代理、HTTP API、SRT 代理、System API、HTTP Stream 代理全部在同一个进程内并行监听共享同一个OriginLoadBalancer实例。六个监听端口默认值来自 internal/env/env.go 的setEnvDefault服务器默认端口协议RTMP 代理11935TCPHTTP API11985HTTPHTTP StreamHTTP-FLV/TS/HLS/静态文件18080HTTPWebRTCWHIP/WHEP18000UDPSRT20080UDPSystem API后端注册12025HTTP二、六大协议代理逐一拆解2.1 RTMP 代理internal/proxy/rtmp.goRTMP 代理是六个服务器中最典型的最小解析 字节转发实现TCP 监听 握手客户端侧与后端侧都做简单的 RTMP 握手C0/C1/C2解析路由信息解析connecttcUrl、createStream、publish/play从而判断客户端是推流者publisher还是播放者viewer并提取流名回放握手与后端建立连接后把 publish/play 握手回放给后端双向拷贝之后 RTMP 消息在客户端与后端之间双向复制完全无状态所有路由状态都在客户端请求里无需跨代理同步。从源码结构看rtmpProxyServer通过newConnection工厂方法创建rtmpConnection每个连接持有loadBalancerRun中使用net.ListenConfig.Listen打开 TCP 监听并逐连接Accept后go func处理。工厂函数使用显式接口名NewRTMPProxyServer(...)这也是 proxy-usage.md 中Code Conventions强调的规范——避免泛化的New()让调用点类型一目了然。2.2 HTTP-FLV / HTTP-TS 代理internal/proxy/http.go服务.flv与.ts伪流媒体pseudo-streaming请求反向代理到后端 HTTP 端口将响应体流式回传给客户端无状态CORS 永远允许Always allowed便于浏览器直连播放。2.3 HLS 代理与 spbhid 会话粘滞internal/proxy/http.goHLS 是多请求会话先请求.m3u8播放列表再逐个请求.ts分片必须保证整个会话钉在同一个后端代理.m3u8播放列表时把 TS 分片 URL 重写追加spbhid查询参数SRS Proxy Backend HLS ID后续携带spbhid的.ts分片请求被路由回同一个后端会话状态在负载均衡器中双索引按流 URL 索引 按spbhid索引。源码佐证internal/proxy/http.go第 265 行读取r.URL.Query().Get(spbhid)并据此LoadHLSBySPBHID第 552–554 行对 m3u8 内容做strings.ReplaceAll把.ts重写为.ts?spbhid...。测试 internal/proxy/http_test.go 第 352、468 行断言了live-0.ts?spbhidspb-1这类重写结果验证了该行为的正确性。注意spbhid会话粘滞在memory 负载均衡器下完整可用使用Redis 负载均衡器时存在已知限制见文末已知限制。2.4 静态文件服务器internal/proxy/http.go可选地服务静态 Web 目录PROXY_STATIC_FILES默认./trunk/research用于承载播放器页面如 srs-player 等未设置该环境变量时直接返回 404fall through to 404。2.5 WebRTC WHIP/WHEP 代理internal/proxy/rtc.goWebRTC 代理是两阶段架构信令阶段signaling把 WHIP/WHEP 的 SDP 交换转发给后端 HTTP API并把后端 SDP answer 中的 WebRTC UDP 端口改写为代理自己的端口这样媒体流会先到代理媒体阶段mediaUDP 包双向中继relay。关键机制——按 ICE ufrag 识别连接从 STUN binding 请求解析出 ufrag作为连接标识。因此即使客户端迁移到新的 UDP 地址也会被重新关联到同一代理上的同一流。ufrag→连接 的映射存储在负载均衡器中并本地缓存以加速查找。源码佐证internal/proxy/rtc.go 第 335、354 行STUN binding 请求中解析pkt.Username即 ufrag后调用LoadWebRTCByUfrag找到connection。向后兼容兼容 SRS 旧版/rtc/v1/publish/与/rtc/v1/play/API会先解包{sdp:...}JSON 信封再解析 ICE 属性。每个 WebRTC 连接是有状态的与 RTMP 的无状态形成对比所以需要 ufrag 映射的本地缓存与跨代理共享设计跨代理重关联通过共享负载均衡器设计但 Redis LB 下尚不可用见文末。2.6 SRT 代理internal/proxy/srt.goSRT 使用 UDP且握手机制与 RTMP/HTTP 完全不同代理采取本地拦截握手策略本地应答 induction 阶段handshake 0→1从 conclusion 阶段handshake 2解析出stream ID对后端完整回放握手并把结果中继回客户端之后按连接双向中继 UDP以 SRT socket ID 为键维护连接映射。stream ID 解析规则例如#!::rapp/stream,mpublish|requesth可选 vhost缺省为localhost用于路由rapp/stream用于路由与挑选后端m忽略不参与路由。源码佐证internal/proxy/srt.gosrsSRTProxyServer用sync.Map[uint32, *SRTConnection]以 socket ID 索引连接listenUDP通过net.ResolveUDPAddrnet.ListenUDP打开 UDP socket。限制SRT不支持客户端地址迁移与 WebRTC 不同——连接一旦建立就固定绑定到初始客户端地址。三、HTTP API 与后端注册3.1 两个 API 服务器internal/proxy/api.goHTTP API 服务器默认端口 11985路由作用/api/v1/versions版本 / 健康检查/rtc/v1/whip/WebRTC WHIP 信令委托给 WebRTC 代理服务器/rtc/v1/whep/WebRTC WHEP 信令委托给 WebRTC 代理服务器/rtc/v1/publish/、/rtc/v1/play/兼容 SRS 旧版 WebRTC 信令srs-bench 使用委托给同一处理器System API 服务器默认端口 12025路由作用/api/v1/srs/register后端 Origin 在此注册负载均衡器据此学习各协议的监听端点/api/v1/versions版本 / 健康检查3.2 三种后端注册方式详见 proxy-protocol.md共三种① 自动注册SRS 5.0 心跳生产推荐SRS 通过心跳特性向代理的 System API 上报。例如 trunk/conf/origin1-for-proxy.conf 风格heartbeat { enabled on; interval 9; url http://127.0.0.1:12025/api/v1/srs/register; device_id origin1; ports on; }SRS 启动时自动注册随后周期性心跳文档建议约每 30 秒一次保活心跳停止超过PROXY_ORIGIN_SERVER_TTL默认300s后代理将该服务器标记为不可用完全自动化、自愈代理重启后源站会自动重新注册。多代理部署时每个代理配置同一个共享 Redis源站只需把心跳发给一个代理该代理把注册写入共享 Redis所有代理都能读到。但 SRS 只接受一个heartbeat.url因此该 URL 应指向高可用前端NLB/VIP避免单点代理故障导致注册过期。② 手动注册 API适用于非 SRS 后端如 nginx-rtmp、Node-Media-Servercurl -X POST http://127.0.0.1:12025/api/v1/srs/register \ -H Connection: Close \ -H Content-Type: application/json \ -H User-Agent: curl \ -d { device_id: origin2, ip: 10.78.122.184, server: vid-46p14mm, service: z2s3w865, pid: 42583, rtmp: [19352], http: [8082], api: [19853], srt: [10082], rtc: [udp://0.0.0.0:8001] } #{code:0,pid:53783}单次请求只在 TTL 内有效自定义集成必须周期性重复请求以维持心跳。③ 默认后端仅开发/测试PROXY_DEFAULT_BACKEND_ENABLEDon PROXY_DEFAULT_BACKEND_IP127.0.0.1 PROXY_DEFAULT_BACKEND_RTMP1935 PROXY_DEFAULT_BACKEND_HTTP8080 # 可选 PROXY_DEFAULT_BACKEND_API1985 # 可选 PROXY_DEFAULT_BACKEND_RTC8000 # 可选 (UDP) PROXY_DEFAULT_BACKEND_SRT10080 # 可选 (UDP)启用后代理在启动时自动注册该默认后端并每 30 秒发一次心跳保活适合快速联调、开发调试与单服务器部署。3.3 注册字段与监听端点格式从 internal/lb/lb.go 的OriginServer结构体可见完整字段JSON 标签与文档一致字段必填说明ip是后端 IP须保证代理可达server是SRS 服务器 ID存于文件、通常不变service是服务 ID重启即变pid是进程 ID用于识别进程是否重启rtmp是RTMP 监听端点代理按此端口连后端http否HTTP-FLV / HTTP-TS 监听端点api否HTTP API 监听端点WHIP/WHEP 用srt否SRT 监听端点rtc否WebRTC 监听端点device_id否设备 ID作为后端标签监听端点格式为port、proto://ip:port或proto://:port1935任意 IP 上的 TCP 1935 端口tcp://:1935同上tcp://0.0.0.0:1935同上显式写法tcp://192.168.3.10:1935指定 IP 上的 1935 端口。OriginServer.ID()返回server-service-pid组合标识Format方法在%v时打印全部端点与更新时间便于日志排障。四、负载均衡接口、两种实现与键设计4.1 可插拔接口internal/lb/lb.goOriginLoadBalancer接口组合了三个子接口OriginServiceUpdate(ctx, server)记录注册/心跳Pick(ctx, streamURL)为流挑选后端HLSServiceLoadOrStoreHLS按流 URL、LoadHLSBySPBHID按 spbhidRTCServiceStoreWebRTC按流 URL、LoadWebRTCByUfrag按 ICE ufrag。数据模型包括OriginServer源站、HLSPlayStreamHLS 会话GetSPBHID()、RTCConnectionWebRTC 连接GetUfrag()。启动时由PROXY_LOAD_BALANCER_TYPE决定实现internal/bootstrap/proxy.go 的initializeLoadBalancerredis走NewRedisLoadBalancer其余默认NewMemoryLoadBalancer。4.2 Memory 负载均衡器internal/lb/mem.go进程内sync.Map状态无外部依赖时延最低适用单代理、中等流量的部署无健康服务器时回退到所有已注册服务器fallback to all registered servers。4.3 Redis 负载均衡器internal/lb/redis.go共享 Redis 状态 TTL 过期自动清理供多代理在 NLB 后水平扩展JSON 序列化做跨进程通信死服务器通过 TTL 过期自动剔除。4.4 Redis 键设计PROXY_REDIS_KEY_PREFIX可选前缀PROXY_REDIS_KEY_PREFIX默认为空向后兼容设置为xxx时键形如xxx:srs-proxy-...。同一逻辑集群内的每个代理必须使用相同前缀。具体键见 proxy-load-balancer.md键含义过期srs-proxy-server:{serverID}服务器注册PROXY_ORIGIN_SERVER_TTL默认 300ssrs-proxy-all-servers服务器列表索引不过期srs-proxy-url:{streamURL}流→服务器映射不过期srs-proxy-hls:{streamURL}HLS 按 URL120ssrs-proxy-spbhid:{spbhid}HLS 按 spbhid120ssrs-proxy-rtc:{streamURL}WebRTC 按 URL120ssrs-proxy-ufrag:{ufrag}WebRTC 按 ufrag120s4.5 选择策略与过期清理流级粘滞Stream-Level Stickiness流 URL 第一次请求时挑选后端此后该流的所有请求都路由到同一后端流→服务器映射永不失效保证长流路由一致仅在后端死亡或映射被显式清除时重置。健康度选择优先选择最近心跳在PROXY_ORIGIN_SERVER_TTL默认 300s内的服务器在健康服务器中随机选择以均匀分布。Memory LB 在无健康服务器时回退到全部已注册服务器Redis LB 则靠 TTL 过期剔除死服务器。TTL 校验parseOriginServerTTLinternal/lb/lb.go接受 Go duration 语法如45s、2m必须为正数且必须大于源站心跳间隔并留有裕量源码常量serverAliveDuration 300s。会话状态HLS 与 WebRTC 会话 120 秒不活动即过期源码常量HLSAliveDuration 120 * time.Second、RTCAliveDuration 120 * time.Second每次请求都会续期Redis 靠 TTL 自动清理Memory 靠进程内 GC。4.6 Memory vs Redis 对比proxy-load-balancer.md维度Memory 负载均衡器Redis 负载均衡器部署单代理多代理状态存储本地内存共享 Redis时延最低进程内网络 序列化扩展性单实例水平扩展依赖无需要 Redis复杂度简单中等容错单点故障多代理高可用适用场景中等流量高流量、高可用配置示例# Memory PROXY_LOAD_BALANCER_TYPEmemory # Redis PROXY_LOAD_BALANCER_TYPEredis PROXY_REDIS_HOST127.0.0.1 PROXY_REDIS_PORT6379 PROXY_REDIS_PASSWORD PROXY_REDIS_DB0五、三种部署模式proxy-design.md5.1 单代理模式Single Proxy适用流数量中等、需要多个源站每流观看者少单个代理即可承载全部流。使用Memory LB无需 Redis。----------------------- -------------------- Proxy Server ------------- Origin Server B (Memory LB) -------------------- ----------------------- -------------------- ------- Origin Server C --------------------5.2 多代理模式可水平扩展适用单个代理成为瓶颈时大量流分布在众多源站、每流观看者有限。需要 Redis做代理间状态同步。----------------- | ---------------------- | AWS NLB -- | ----------------- | (Redis Sync) Origin Servers | ---------------------- --- Proxy Server B ------ -----------------------5.3 完整集群Edge Proxy Origin未来适用流数量与观看者数量都很大。Edge 服务器聚合上游连接——从上游拉一次流服务多个观众大幅降低代理与源站负载。Edge Servers → Proxy Servers → Origin Servers (Proxy Cache) (Proxy) (SRS/Media)未来 Edge 将实现为启用缓存的代理同一套代码库同时扮演代理与边缘角色边缘缓存聚合观众连接数千观众看同一流时仅向上游请求一次。六、配置体系纯环境变量驱动internal/env/env.go完全没有配置文件所有设置启动时填充合理默认值内置.env解析器无第三方依赖支持注释、export前缀、带引号的值双引号支持转义序列、单引号为字面量、行内注释绝不覆盖进程已有的环境变量。完整环境变量一览默认值来自 internal/env/env.go 的setEnvDefault环境变量默认值说明PROXY_RTMP_SERVER11935RTMP 监听端口PROXY_HTTP_API11985HTTP API 端口PROXY_HTTP_SERVER18080HTTP Stream 端口PROXY_WEBRTC_SERVER18000WebRTC UDP 端口PROXY_SRT_SERVER20080SRT UDP 端口PROXY_SYSTEM_API12025System API 端口PROXY_LOAD_BALANCER_TYPEmemorymemory或redisPROXY_REDIS_HOST127.0.0.1Redis 主机PROXY_REDIS_PORT6379Redis 端口PROXY_REDIS_PASSWORD空Redis 密码PROXY_REDIS_DB0Redis DBPROXY_REDIS_KEY_PREFIX空Redis 键前缀隔离集群PROXY_ORIGIN_SERVER_TTL300s源站注册/心跳生命周期Go durationPROXY_GRACE_QUIT_TIMEOUT20s优雅退出 HTTP 排空上限PROXY_FORCE_QUIT_TIMEOUT30s强制退出兜底PROXY_STATIC_FILES./trunk/research静态 Web 目录PROXY_DEFAULT_BACKEND_ENABLEDoff启用默认后端PROXY_DEFAULT_BACKEND_IP127.0.0.1默认后端 IPPROXY_DEFAULT_BACKEND_RTMP1935默认后端 RTMPPROXY_DEFAULT_BACKEND_HTTP空默认后端 HTTPPROXY_DEFAULT_BACKEND_API1985默认后端 APIPROXY_DEFAULT_BACKEND_RTC8000默认后端 RTCUDPPROXY_DEFAULT_BACKEND_SRT10080默认后端 SRTUDPGO_PPROF空启用 pprof见 internal/debug/pprof.goPROXY_HTTP_API_AUTH_ENABLED/TYPE/TOKENoff/ 空 / 空HTTP API 鉴权bearer/basic 等七、运维与生命周期优雅关闭internal/bootstrap、internal/signalSIGINT/SIGTERM 取消根 context各服务器依次关闭PROXY_GRACE_QUIT_TIMEOUT默认 20s约束 HTTP 服务器排空。强制退出兜底PROXY_FORCE_QUIT_TIMEOUT默认 30s的强制定时器保证即使优雅关闭卡死进程也必然退出见 internal/bootstrap/proxy.goInstallForceQuit注释主线程可能被阻塞因此需要强制退出保障。结构化日志internal/loggerlog/slog输出 JSON携带pid、version及每连接 7 位十六进制上下文 IDcid用于关联排障。性能剖析internal/debugGO_PPROF环境变量可选的net/http/pprof服务器参考 perf/proxy-whep.md。版本/健康端点/api/v1/versions同时暴露在 HTTP API、System API、HTTP Stream 服务器上兼作健康检查。八、快速上手5 步跑通proxy-usage.mdStep 1构建并启动代理make env PROXY_RTMP_SERVER1935 PROXY_HTTP_SERVER8080 \ PROXY_HTTP_API1985 PROXY_WEBRTC_SERVER8000 PROXY_SRT_SERVER10080 \ PROXY_SYSTEM_API12025 PROXY_LOAD_BALANCER_TYPEmemory ./bin/srs-proxyStep 2启动 SRS Origin 源站可能需要提高文件描述符上限并使用 bash 显式执行ulimit -n 10000 bash -c cd ~/git/srs/trunk ./objs/srs -c conf/origin1-for-proxy.confStep 3验证 SRS 已注册查看代理控制台日志出现 Register SRS media server 消息即注册成功该日志由 internal/proxy/api.go 第 351 行打印。Step 4用 FFmpeg 推测试流ffmpeg -stream_loop -1 -re -i ~/git/srs/trunk/doc/source.flv -c copy -f flv rtmp://localhost/live/livestream-stream_loop -1让 FFmpeg 无限循环输入文件保证推流不会因文件播完而退出。Step 5用 ffprobe 验证# RTMP ffprobe rtmp://localhost/live/livestream # HTTP-FLV ffprobe http://localhost:8080/live/livestream.flv两条命令均应成功探测到流并显示音视频编码信息说明代理工作正常。多源站场景可参考 proxy-origin-cluster.md先启动代理同样环境变量再并行启动三个源站./objs/srs -c conf/origin1-for-proxy.conf、origin2-for-proxy.conf、origin3-for-proxy.conf它们通过 12025 端口向代理注册。关于历史SRS 7.0 起新 Origin Cluster 基于 proxy 构建取代了旧的 MESH 方案如需旧式 Origin Cluster 可切换到 SRS 6.0。九、已知限制Notes代理只转发字节跨协议转封装例如把 RTMP 推流以 HLS/HTTP-FLV/WebRTC 播放由后端 Origin完成代理仅负责把各协议请求路由到能服务的源站。Redis LB 的 HLS/WebRTC 会话反序列化限制Redis 负载均衡器尚不能从 Redis 反序列化 HLS 与 WebRTC 会话对象LoadHLSBySPBHID与LoadWebRTCByUfrag返回错误。因此PROXY_LOAD_BALANCER_TYPEredis时HLS 播放会在 TS 分片请求时失败WebRTC 客户端只能被处理其信令的那个代理识别无法跨代理迁移。RTMP、HTTP-FLV/TS、SRT 不受影响。SRT 不支持客户端地址迁移区别于 WebRTC 的 ufrag 重关联机制。当前版本为 SRS8.0.x下一代 Go 服务器签名SRSXspbhid的 HLS 会话粘滞依赖 memory LB 才能完整工作。十、推荐阅读能力清单——本文骨架跟踪已实现能力设计文档——架构与三种部署模式负载均衡文档——LB 接口、Redis 键设计与对比注册协议文档——三种注册方式与字段说明运行测试指南——5 步跑通与代码规范Origin Cluster 指南——构建 RTMP Origin Cluster关键源码internal/bootstrap/proxy.go六服务器启动编排、internal/lb/lb.goLB 接口与数据模型、internal/proxy/http.goHLS spbhid 重写、internal/proxy/rtc.goufrag 关联、internal/proxy/srt.goSRT 握手拦截、internal/env/env.go全部环境变量与默认值、internal/proxy/api.go注册 API【免费下载链接】srsSRS is a simple, high-performance, AI-driven real-time media server supporting RTMP, WebRTC, HLS, HTTP-FLV, HTTP-TS, SRT, MPEG-DASH, and GB28181, with codec support for H.264, H.265, AV1, VP9, AAC, Opus, and G.711.项目地址: https://gitcode.com/GitHub_Trending/sr/srs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表