如何确保在源集群模式下访问正确的后端 M3U8 文件

Posted

技术标签:

【中文标题】如何确保在源集群模式下访问正确的后端 M3U8 文件【英文标题】:How to ensure access the right backend M3U8 file in origin cluster mode 【发布时间】:2022-01-21 01:52:08 【问题描述】:

从SRS如何transmux HLSwiki,我们知道SRS在hls_path中生成对应的M3U8播放列表,这是我的配置文件:

http_server 
    enabled         on;
    listen          8080;
    dir             ./objs/nginx/html;

vhost __defaultVhost__ 
    hls 
        enabled         on;
        hls_path        /data/hls-records;
        hls_fragment    10;
        hls_window      60;
    

在一个 SRS 服务器的情况下,每个播放 HLS 流的客户端都访问同一个推送 SRS 服务器,这没关系。但是在 origin 集群模式下,有很多 SRS 服务器,每个流都在其中一个。当客户端播放此 HLS 流时,我们无法保护它可以访问正确的源 SRS 服务器(如果不存在则导致 404 http 状态代码)。与 RTMP 和 HTTP-FLV 流不同,SRS 使用 coworker by HTTP-API 功能来重定向正确的源 SRS。

为了解决这个问题,我认为有以下两种解决方案:

使用专门的后端 HLS 段 SRS 服务器: 不要在源 SRS 服务器中生成 M3U8,每个流都转发到此 SRS 服务器,所有 M3U8 都在此服务器中生成,所有 HLS 请求都是此服务器的代理(使用 nginx)。缺点。此解决方案仅限于一个实例,没有扩展能力和单节点风险。

源 srs.conf 转发配置如下:

vhost same.vhost.forward.srs.com 
    # forward stream to other servers.
    forward 

        enabled on;

        destination 192.168.1.120:1935;
    

其中 192.168.1.120 是后端 hls 段 SRS 服务器。

使用 NFS/K8S PV/分布式文件系统等云存储: 将云存储作为本地文件夹挂载在每个 SRS 服务器中,无论 SRS 服务器、M3U8 文件和 ts 段传输到同一个大存储中的流,因此在 HLS 请求后,http 服务器将它们作为静态文件提供。从我的测试来看,如果云存储写入速度可靠,是一个很好的解决方案。但如果网络抖动或写入速度不如接收速度快,则会阻塞其他协程,从而导致 SRS 异常。

hls_path 配置如下:

vhost __defaultVhost__ 
    hls 
        enabled         on;
        hls_path        /shared_storage/hls-records;
        hls_fragment    10;
        hls_window      60;
    

这里的“shared_stoarge”是指一个 nfs/cephfs/pv 挂载点。

在我看来,以上解决方案并没有从根本上解决访问问题,我期待为这种情况找到更好的可靠产品解决方案?

【问题讨论】:

【参考方案1】:

当您使用 OriginCluster 时,您必须获得大量的流来提供服务,有很多编码器可以将流发布到您的媒体服务器。解决问题的关键:

    永远不要使用单服务器,使用集群来获得弹性能力,因为将来您可能会获得更多的流。所以转发不好,因为你必须配置一组特殊的流来转发,类似于手动哈希算法。 除了带宽,磁盘 IO 也是瓶颈。你肯定需要一个高性能的网络存储集群。但要注意,千万不要让 SRS 直接写入存储,会阻塞 SRS 协程。

因此,据我所知,最好的解决方案是:

    使用 SRS Origin Cluster,将 HLS 写入本地磁盘,或者 RAM 磁盘更好,以确保磁盘 IO 不会阻塞 SRS 协程(由状态线程网络 IO 驱动)。 使用网络存储集群来存储 HLS 文件,例如 AWS S3 等云存储,或 NFS/K8S PV/分布式文件系统等。使用 nginx 或 CDN 交付 HLS。

现在的问题是:如何将数据从内存/磁盘移动到网络存储集群?

您必须使用 Python 或 Go 构建服务:

使用on_hls 回调,通知您的服务移动 HLS 文件。 使用on_publish回调,通知你的服务启动FFmpeg,将RTMP转为HLS。

请注意,FFmpeg 应该从 SRS 边缘提取流,而不是直接从源服务器提取。

【讨论】:

移动 HLS ts 文件是可以的,但是如何处理 M3U8 文件呢?我需要自己生成实时 m3u8 文件还是将此文件移动(替换)到网络存储集群? m3u8 不在此解决方案中,请对其进行一些研究。移动它还是重新生成它?我认为两者都可以。

以上是关于如何确保在源集群模式下访问正确的后端 M3U8 文件的主要内容,如果未能解决你的问题,请参考以下文章

当流体页面导致后端和前端出现错误时,如何重新访问 TYPO3 的后端?

通过URL参数请求不同的后端服务器

如何使用我的后端中使用的前端反应中的 Auth0 访问令牌

Next.js 10.2正式发布,React应用的后端渲染

集群中的session共享问题解决方案

ckeditor - 在源模式下禁用ENTER键