nginx负载均衡支撑hls高效分发的核心是构建可感知切片生命周期、缓存策略与地域特征的智能调度层:lb仅精准路由请求至边缘节点,边缘节点独立分级缓存(m3u8缓1秒、ts缓60分钟),源站输出固定文件名、序号化分片及显式cache-control头,并通过日志变量定位缓存失效根因。

要让 Nginx 负载均衡真正支撑 HLS 视频流的高效就近分发与边缘缓存,核心不是“把请求平均甩给后端”,而是构建一层可感知切片生命周期、缓存行为和地域特征的调度层——它得懂 m3u8 为什么只能缓 1 秒、ts 为什么能缓 60 秒、用户来自哪、最近的边缘节点有没有热切片。
明确角色分工:LB 不做内容处理,只做智能路由
负载均衡器(LB)本身不存储或生成任何 .ts 或 .m3u8 文件,也不执行切片逻辑。它的唯一职责是:根据请求路径、客户端 IP 地理位置(GeoIP)、后端节点负载(active conn / response time),把 /live/xxx.m3u8 或 /live/xxx/seg-123.ts 请求精准转发到最合适的边缘 Nginx 节点。
- 用
upstream定义边缘集群,启用least_conn或ip_hash(保障同一观众连续请求落到同一边缘,利于本地缓存复用) - 配合
geo模块或第三方模块(如 nginx-module-geoip2)识别用户大区,再用map将区域映射为 upstream 组(如 “cn-east → edge-east”) - 禁用 LB 上所有缓存、日志、重写、鉴权等非路由逻辑——它越轻量,吞吐越高,延迟越稳
边缘节点必须自带缓存能力,且策略严格区分文件类型
每台边缘 Nginx 都要配置独立的 proxy_cache,并针对 m3u8 和 ts 设置不同 TTL 和键值规则,这是就近响应的关键。
-
m3u8 缓存:设置
proxy_cache_valid 200 302 1s,proxy_cache_key "$scheme$host$uri"(不带 $args,避免动态参数污染缓存) -
ts 缓存:设为
proxy_cache_valid 200 302 60m,proxy_cache_key "$scheme$host$uri"(ts 文件名固定、不可变,适合长缓存) - 缓存路径建议用 SSD,例如:
proxy_cache_path /ssd/cache/hls levels=1:2 keys_zone=hls_cache:200m max_size=200g inactive=1h use_temp_path=off;
源站协同:SRS 或 Nginx+mp4_module 提供稳定、无参、序号化输出
边缘缓存能否生效,源头输出是否“友好”决定成败。源站(如 SRS 或 Nginx 动态切片服务)必须满足:
- m3u8 文件名固定(如
stream.m3u8),不拼 query(如?t=1718923456),鉴权改用 Header 或 Cookie - ts 分片严格按递增序号命名(
seg-1.ts,seg-2.ts),EXT-X-MEDIA-SEQUENCE连续不跳变 - 响应头显式声明缓存策略:
add_header Cache-Control "public, max-age=1";(m3u8)、add_header Cache-Control "public, max-age=60";(ts)
链路可观测:通过变量日志定位缓存失效根因
仅靠命中率数字无法判断问题出在 LB 路由不准、边缘缓存未生效,还是源站返回了不可缓存响应。需在边缘节点开启精细化日志:
- 记录
$upstream_cache_status(HIT / MISS / EXPIRED / BYPASS) - 记录
$upstream_http_cache_control和$upstream_http_expires,确认源站是否真返回了预期缓存头 - 结合
$request_time与$upstream_response_time判断延迟瓶颈在路由、网络,还是回源慢
这套结构不依赖商业模块,纯靠 Nginx 原生功能即可落地。关键在于每个环节都围绕 HLS 的“时效性+局部热点”特性设计,而不是套用通用 Web 负载均衡模板。











