SRS流媒体服务器——Forward集群搭建和源码分析

这篇具有很好参考价值的文章主要介绍了SRS流媒体服务器——Forward集群搭建和源码分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

  1. Forward集群原理
  2. RTMP流转发(Forward)部署实例
  3. Forward集群源码分析

1. Forward集群原理

Forward 表示向前、前头的、发送等意思。

在SRS中可以理解为把Master节点获得直播流⼴播(转发)给所有的Slave节点,master节点由多少路直播流,那么在每个slave节点也会多少路直播流。

注:在SRS中还有另外⼀种集群⽅式,edge⽅式。注意两种⽅式的⽤词不同。

a. 在Forward模式中,中⼼节点叫Master,边缘节点叫Slave。

b. 在edge模式中,中⼼节点叫origin(源站),边缘节点叫做edge。

1. 适用场景SRS流媒体服务器——Forward集群搭建和源码分析

Forward适合与搭建小型集群。

推流者推流给master,那么master就会Forward到每一个Slave,那么在slave节点上不论需不需要都会有master过来的流。

如果推流者的数量为10,那么master到slave之间的带宽就是:带宽=10 *slave的个数 *直播流码率,随着slave的增多,master的出口带宽会不断提高。

而现实是,在某些slave节点其实没有人看,这样就造成了master到slave之间的带宽浪费。

所以说Forward适合与搭建小型集群。

2. RTMP流转发(Forward)部署实例

SRS可以将送到SRS的流转发给其他RTMP服务器,实现简单集群/热备功能,也可以实现一路流热备

a. 如编码器由于带宽限制,只能送一路流到RTMP服务器,要求RTMP服务器能将这路流也转发给其他RTMP备用服务器,实现主备容错集群

假设服务器的IP是:8.141.75.248

Forward就是SRS将流拷贝输出给其他的RTMP服务器,以SRS转发给SRS为例:

  • 主SRS:Master, 编码器推流到主SRS,主SRS将流处理的同时,将流转发到备SRS

  • 备SRS:Slave, 主SRS转发流到备SRS,就像编码器推送流到备用SRS一样。 我们的部署实例中,主SRS侦听1935端口,备SRS侦听19350端口。

1. 编写主SRS配置⽂件

  1. vim conf/forward.master.conf
# the config for srs to forward
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleForward
# @see full.conf for detail config.

listen              1935;
max_connections     1000;
pid                 ./objs/srs.master.pid;
vhost __defaultVhost__ {
    forward {
        enabled on;
        destination 127.0.0.1:19350 127.0.0.1:19351; #forward目的地址,增加一个19351端口
    }
}

2.启动srs服务器。

./objs/srs -c conf/forward.master.conf

监听日志信息:tail -f ./objs/srs.log

2. 编写从SRS配置文件

  1. 复制conf/forward.slave.conf到conf/forward.slave1.conf,conf/forward.slave2.conf。
cp conf/forward.slave.conf conf/forward.slave1.conf
cp conf/forward.slave.conf conf/forward.slave2.conf

2.修改conf/forward.slave1.conf配置文件。

# the config for srs to forward
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleForward
# @see full.conf for detail config.

listen              19350; #注意端口
max_connections     1000;
pid                 ./objs/srs.slave1.pid;  #./objs/srs.slave.pid改为./objs/srs.slave1.pid
srs_log_tank 		file;
srs_log_file 		./objs/srs.slave1.log;
vhost __defaultVhost__ {
}

3.修改conf/forward.slave2.conf配置文件。

# the config for srs to forward
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleForward
# @see full.conf for detail config.

listen              19351;
max_connections     1000;
pid                 ./objs/srs.slave2.pid;
srs_log_tank 		file;
srs_log_file 		./objs/srs.slave2.log;
vhost __defaultVhost__ {
}

4.启动slave1和slave2

./objs/srs -c conf/forward.slave1.conf
./objs/srs -c conf/forward.slave2.conf


监听日志信息:tail -f ./objs/srs.log

5.启动srs后查看srs是否启动成功:netstat -anp|grep srs

本文福利, 免费领取C++音视频学习资料包、技术视频/代码,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,编解码,推拉流,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓

3. 验证是否部署成功

1. 启动推流编码器

  1. 使用FFmpeg进行推流
ffmpeg -re -i source.200kbps.768x320.flv -vcodec copy -acodec copy -f flv -y rtmp://8.141.75.248/live/livestream

2.涉及到的流包括:

编码器推送的流:rtmp://8.141.75.248/live/livestream

主SRS转发的流:rtmp://8.141.75.248:19350/live/livestream
主SRS转发的流:rtmp://8.141.75.248:19351/live/livestream

观看主SRS的流:rtmp://8.141.75.248/live/livestream
观看从1 SRS的流:rtmp://8.141.75.248:19350/live/livestream
观看从2 SRS的流:rtmp://8.141.75.248:19351/live/livestream

2. 观看主从SRS的RTMP流

主RTMP流地址为:rtmp://8.141.75.248/live/livestream

从1 SRS的流:rtmp://8.141.75.248:19350/live/livestream

从2 SRS的流:rtmp://8.141.75.248:19351/live/livestream

可以使用VLC观看或者SRS播放器播放:srs播放器

注意:19350和19351端口需要在服务器开放,不然从节点无法拉流

3. Forward集群源码分析

  1. 从原理上来分析,要实现forward功能:

  2. 读取配置⽂件获取forward server的地址

  3. 创建RTMP推流客户端

  4. 从source⾥⾯拉取消息,然后推送给forward server

1. 从配置文件开始分析

  1. 打开 conf/forward.master.conf 配置文件。
listen              1935;
max_connections     1000;
pid                 ./objs/srs.master.pid;
srs_log_tank        file;
srs_log_file        ./objs/srs.master.log;
vhost __defaultVhost__ {
    forward {
        enabled on;
        destination 127.0.0.1:19350 127.0.0.1:19351;
    }
}

日志打印在终端设置方法:
#srs_log_tank        file;
#srs_log_file        ./objs/srs.log;
daemon              off;
srs_log_tank        console;

2.在srs_app_config.cpp中搜索“forward”即可发现读取“forward”的代码。

bool SrsConfig::get_forward_enabled(string vhost)
{
    static bool DEFAULT = false;
    
    SrsConfDirective* conf = get_vhost(vhost);
    if (!conf) {
        return DEFAULT;
    }
    
    conf = conf->get("forward");
    if (!conf) {
        return DEFAULT;
    }
    
    conf = conf->get("enabled");
    if (!conf || conf->arg0().empty()) {
        return DEFAULT;
    }
    
    return SRS_CONF_PERFER_FALSE(conf->arg0());
}

SrsConfDirective* SrsConfig::get_forwards(string vhost)
{
    SrsConfDirective* conf = get_vhost(vhost);
    if (!conf) {
        return NULL;
    }
    
    conf = conf->get("forward");
    if (!conf) {
        return NULL;
    }
    
    return conf->get("destination");
}

2. 使用gdb打断点进行分析:

  1. 使用gdb打断点进行分析:
gdb ./objs/srs

(gdb) set args -c conf/forward.master.conf
(gdb) b SrsConfig::get_forward_enabled(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
Breakpoint 1 at 0x53701d: file src/app/srs_app_config.cpp, line 4837.
(gdb) b SrsConfig::get_forwards(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
Breakpoint 2 at 0x5372df: file src/app/srs_app_config.cpp, line 4859.

2.推流后才能进行调试:

ffmpeg -re -i source.200kbps.768x320.flv -vcodec copy -acodec copy -f flv -y rtmp://8.141.75.248/live/livestream

3.SrsConfig::get_forward_enabled 对应调试信息:

Breakpoint 1, SrsConfig::get_forward_enabled (this=0xa0fcf0, vhost="__defaultVhost__") at src/app/srs_app_config.cpp:4837
4837	{
(gdb) bt
#0  SrsConfig::get_forward_enabled (this=0xa0fcf0, vhost="__defaultVhost__") at src/app/srs_app_config.cpp:4837
#1  0x00000000004e277a in SrsOriginHub::create_forwarders (this=0xab8000) at src/app/srs_app_source.cpp:1467
#2  0x00000000004e1214 in SrsOriginHub::on_publish (this=0xab8000) at src/app/srs_app_source.cpp:1120
#3  0x00000000004e76ce in SrsSource::on_publish (this=0xab7cd0) at src/app/srs_app_source.cpp:2457
#4  0x00000000004d96ca in SrsRtmpConn::acquire_publish (this=0xa9be50, source=0xab7cd0) at src/app/srs_app_rtmp_conn.cpp:940
#5  0x00000000004d874c in SrsRtmpConn::publishing (this=0xa9be50, source=0xab7cd0) at src/app/srs_app_rtmp_conn.cpp:822
#6  0x00000000004d5ee7 in SrsRtmpConn::stream_service_cycle (this=0xa9be50) at src/app/srs_app_rtmp_conn.cpp:534
#7  0x00000000004d4ddf in SrsRtmpConn::service_cycle (this=0xa9be50) at src/app/srs_app_rtmp_conn.cpp:388
#8  0x00000000004d3ba7 in SrsRtmpConn::do_cycle (this=0xa9be50) at src/app/srs_app_rtmp_conn.cpp:209
#9  0x00000000004d1d99 in SrsConnection::cycle (this=0xa9bec8) at src/app/srs_app_conn.cpp:171
#10 0x000000000050ab08 in SrsSTCoroutine::cycle (this=0xa9c130) at src/app/srs_app_st.cpp:198
#11 0x000000000050ab7d in SrsSTCoroutine::pfn (arg=0xa9c130) at src/app/srs_app_st.cpp:213
#12 0x00000000005bed1a in _st_thread_main () at sched.c:337
#13 0x00000000005bf492 in st_thread_create (start=0x5be696 <_st_vp_schedule+170>, arg=0x700000001, joinable=1, stk_size=1) at sched.c:616
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

4.forward metadata,video,audio数据。

b SrsForwarder::on_meta_data(SrsSharedPtrMessage*)

(gdb) bt
#0  SrsForwarder::on_meta_data (this=0xab9e60, shared_metadata=0xb28490) at src/app/srs_app_forward.cpp:114
#1  0x00000000004df741 in SrsOriginHub::on_meta_data (this=0xab8000, shared_metadata=0xb28490, packet=0xb283f0) at src/app/srs_app_source.cpp:924
#2  0x00000000004e5e23 in SrsSource::on_meta_data (this=0xab7cd0, msg=0xb28210, metadata=0xb283f0) at src/app/srs_app_source.cpp:2113
#3  0x00000000004d9e93 in SrsRtmpConn::process_publish_message (this=0xa9be50, source=0xab7cd0, msg=0xb28210) at src/app/srs_app_rtmp_conn.cpp:1045
#4  0x00000000004d9aa6 in SrsRtmpConn::handle_publish_message (this=0xa9be50, source=0xab7cd0, msg=0xb28210) at src/app/srs_app_rtmp_conn.cpp:993
#5  0x0000000000582720 in SrsPublishRecvThread::consume (this=0xab6480, msg=0xb28210) at src/app/srs_app_recv_thread.cpp:389
#6  0x000000000058123e in SrsRecvThread::do_cycle (this=0xab6488) at src/app/srs_app_recv_thread.cpp:146
#7  0x000000000058108f in SrsRecvThread::cycle (this=0xab6488) at src/app/srs_app_recv_thread.cpp:115
#8  0x000000000050ab08 in SrsSTCoroutine::cycle (this=0xb024f0) at src/app/srs_app_st.cpp:198
#9  0x000000000050ab7d in SrsSTCoroutine::pfn (arg=0xb024f0) at src/app/srs_app_st.cpp:213
#10 0x00000000005bed1a in _st_thread_main () at sched.c:337
#11 0x00000000005bf492 in st_thread_create (start=0xab8290, arg=0xab61b0, joinable=0, stk_size=11231648) at sched.c:616
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
b SrsForwarder::on_video(SrsSharedPtrMessage*)
    
(gdb) bt
#0  SrsForwarder::on_video (this=0xab9e60, shared_video=0xb13080) at src/app/srs_app_forward.cpp:155
#1  0x00000000004e1037 in SrsOriginHub::on_video (this=0xab8000, shared_video=0xb13080, is_sequence_header=true) at src/app/srs_app_source.cpp:1106
#2  0x00000000004e6c59 in SrsSource::on_video_imp (this=0xab7cd0, msg=0xb13080) at src/app/srs_app_source.cpp:2303
#3  0x00000000004e68ad in SrsSource::on_video (this=0xab7cd0, shared_video=0xb28210) at src/app/srs_app_source.cpp:2258
#4  0x00000000004d9c7f in SrsRtmpConn::process_publish_message (this=0xa9be50, source=0xab7cd0, msg=0xb28210) at src/app/srs_app_rtmp_conn.cpp:1021
#5  0x00000000004d9aa6 in SrsRtmpConn::handle_publish_message (this=0xa9be50, source=0xab7cd0, msg=0xb28210) at src/app/srs_app_rtmp_conn.cpp:993
#6  0x0000000000582720 in SrsPublishRecvThread::consume (this=0xab6480, msg=0xb28210) at src/app/srs_app_recv_thread.cpp:389
#7  0x000000000058123e in SrsRecvThread::do_cycle (this=0xab6488) at src/app/srs_app_recv_thread.cpp:146
#8  0x000000000058108f in SrsRecvThread::cycle (this=0xab6488) at src/app/srs_app_recv_thread.cpp:115
#9  0x000000000050ab08 in SrsSTCoroutine::cycle (this=0xb024f0) at src/app/srs_app_st.cpp:198
#10 0x000000000050ab7d in SrsSTCoroutine::pfn (arg=0xb024f0) at src/app/srs_app_st.cpp:213
#11 0x00000000005bed1a in _st_thread_main () at sched.c:337
#12 0x00000000005bf492 in st_thread_create (start=0xab8290, arg=0xab61b0, joinable=0, stk_size=11231648) at sched.c:616
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
b SrsForwarder::on_audio(SrsSharedPtrMessage*)
    
(gdb) bt
#0  SrsForwarder::on_audio (this=0xab9e60, shared_audio=0xb13090) at src/app/srs_app_forward.cpp:132
#1  0x00000000004e02d9 in SrsOriginHub::on_audio (this=0xab8000, shared_audio=0xb13090) at src/app/srs_app_source.cpp:1013
#2  0x00000000004e644e in SrsSource::on_audio_imp (this=0xab7cd0, msg=0xb13090) at src/app/srs_app_source.cpp:2188
#3  0x00000000004e6051 in SrsSource::on_audio (this=0xab7cd0, shared_audio=0xb28210) at src/app/srs_app_source.cpp:2138
#4  0x00000000004d9c00 in SrsRtmpConn::process_publish_message (this=0xa9be50, source=0xab7cd0, msg=0xb28210) at src/app/srs_app_rtmp_conn.cpp:1014
#5  0x00000000004d9aa6 in SrsRtmpConn::handle_publish_message (this=0xa9be50, source=0xab7cd0, msg=0xb28210) at src/app/srs_app_rtmp_conn.cpp:993
#6  0x0000000000582720 in SrsPublishRecvThread::consume (this=0xab6480, msg=0xb28210) at src/app/srs_app_recv_thread.cpp:389
#7  0x000000000058123e in SrsRecvThread::do_cycle (this=0xab6488) at src/app/srs_app_recv_thread.cpp:146
#8  0x000000000058108f in SrsRecvThread::cycle (this=0xab6488) at src/app/srs_app_recv_thread.cpp:115
#9  0x000000000050ab08 in SrsSTCoroutine::cycle (this=0xb024f0) at src/app/srs_app_st.cpp:198
#10 0x000000000050ab7d in SrsSTCoroutine::pfn (arg=0xb024f0) at src/app/srs_app_st.cpp:213
#11 0x00000000005bed1a in _st_thread_main () at sched.c:337
#12 0x00000000005bf492 in st_thread_create (start=0xab8290, arg=0xab61b0, joinable=0, stk_size=11231648) at sched.c:616
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

5.SrsForwarder::do_cycle() 完成建联,推流到slave操作。

  1. 主要逻辑在:SrsForwarder::forward()

b SrsForwarder::forward()

(gdb) bt
#0  SrsForwarder::forward (this=0xab9e60) at src/app/srs_app_forward.cpp:248
#1  0x00000000004f8648 in SrsForwarder::do_cycle (this=0xab9e60) at src/app/srs_app_forward.cpp:237
#2  0x00000000004f7fd7 in SrsForwarder::cycle (this=0xab9e60) at src/app/srs_app_forward.cpp:190
#3  0x000000000050ab08 in SrsSTCoroutine::cycle (this=0xab9c20) at src/app/srs_app_st.cpp:198
#4  0x000000000050ab7d in SrsSTCoroutine::pfn (arg=0xab9c20) at src/app/srs_app_st.cpp:213
#5  0x00000000005bed1a in _st_thread_main () at sched.c:337
#6  0x00000000005bf492 in st_thread_create (start=0xab8290, arg=0xab61b0, joinable=0, stk_size=11231648) at sched.c:616
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

本文福利, 免费领取C++音视频学习资料包、技术视频/代码,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,编解码,推拉流,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓文章来源地址https://www.toymoban.com/news/detail-410805.html

到了这里,关于SRS流媒体服务器——Forward集群搭建和源码分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Qt6.5.1+WebRTC学习笔记(十二)环境搭建流媒体服务器(ubuntu22.04+SRS)

    若只是实现一对一通信,仅使用webrtc就足够了。但有时间需要进行多个人的直播会议,当人比较多时,建议使用一个流媒体服务器,笔者使用的是SRS。 这个开源项目资料比较全,笔者仅在此记录下搭建过程 1.操作系统ubuntu22.04 64位 x86架构(建议更新到最新) 2.安装编译器相

    2024年02月09日
    浏览(45)
  • 华为云云耀云服务器L实例评测|将rtmp延迟降低到500ms以内-srs流媒体服务器测试(rtmp、http-flv、webrtc)

    最近华为云提供华为云-云耀云服务器出了一项 征文活动,可以免费试用。于是本人也迫不及待的白嫖体验一下华为云云耀云服务器L实例,该实例配置如下图,系统版本为 本次测试方向是使用SRS开源服务。SRS是一个简单高效的实时视频服务器,支持RTMP/WebRTC/HLS/HTTP-FLV/SRT/GB2

    2024年04月14日
    浏览(33)
  • 流媒体服务器(17)—— 流媒体开源服务 MediaSoup 初识

    目录 前言 正文 一、简单介绍 二、关键特色 1. 超强 SFU 功能 2. Node.js 模块 3. 客户端 SDK 三、架构组成 1. 关键实例 2. 重要模块 四、发展现状 https://liuzhen.blog.csdn.net/article/details/115603863 https://liuzhen.blog.csdn.net/article/details/115603863 最近收看了一期微软(中国)关于云原生、大数据

    2023年04月09日
    浏览(39)
  • 学着搭建流媒体服务器

    操作系统:NAME=\\\"openEuler\\\",架构:aarch64,CPU 运行模式:64-bit 目前有多个开发源代码可以搭建流媒体服务,但要先依赖gcc和cmake,所以首先安装gcc和cmake,查了一通资料,cmake安装记录如下: 1、依赖环境安装 yum -y install libyaml libyaml-devel python-setuptools libcurl-devel python-devel gmp gmp

    2024年02月11日
    浏览(37)
  • 流媒体服务器与视频服务器有什么区别?

    流媒体服务器与视频服务器有什么区别? 流媒体服务器用在远程教育,视频点播、网络电台、网络视频等方面。 直播过程中就需要使用流媒体服务器,一个完整的直播过程,包括采集、处理、编码、封包、推流、传输、转码、分发、解码、播放等过程,流媒体服务器主要负

    2024年02月11日
    浏览(30)
  • 搭建家庭影音媒体中心 --公网远程连接Jellyfin流媒体服务器

    转载自远程穿透的文章:【智能家居】Home Assistant入门安装并内网穿透实现远程安全控制 Home Assistant(以下简称HA)是个开源的智能家居平台,也叫家庭助手,就像一个软件,比如我们的QQ软件,微信软件。 Home Assistant把家中的智能家居设备整合到HA中,它能够接入的设备非常的

    2024年02月01日
    浏览(46)
  • FFmpeg 的使用与Docker安装流媒体服务器

    本文阐述的均为命令行的使用方式,并不牵扯FFmpeg 的 C++音视频开发内容,补充一句,C++的资料真的少,能把C++学好的人,我真的是觉得巨佬。 我主要是使用FFmpeg 推流方面的知识,案例大都是靠近这方面。 一、FFmpeg 介绍 本文读者会比较小众~ 看到此文的朋友,大概率是需要

    2024年01月17日
    浏览(42)
  • ZLMediaKit流媒体服务器 RTSP推流时候的堆栈

    先直接看图 这是ffmpeg向流媒体服务器推流时候的堆栈 引入C++ 11之后  堆栈会显得特别繁复冗余 看起来 也没有 以前没有C++11之前那样 简单明了   太复杂了 标记下  很多函数名字被我改了 因为原来的看起来 同名函数太多了 C++11 和lambada 匿名函数 让看堆栈 成了地狱模式 

    2023年04月20日
    浏览(36)
  • 网络摄像头-流媒体服务器-视频流客户端

    当涉及交通事件检测算法和摄像头视频数据处理时,涉及的代码案例可能会非常复杂,因为这涉及到多个组件和技术。以下是一个简单的Python代码示例,演示如何使用OpenCV库捕获摄像头视频流并进行实时车辆检测,这是一个常见的交通事件检测任务。请注意,这只是一个入门

    2024年02月09日
    浏览(44)
  • 使用nginx部署rtmp流媒体服务器完成直播推流

    笔者为了开发方便使用windows系统的Nginx进行配置。 下载Nginx http://nginx-win.ecsds.eu/download/ 在windows版本下只有个别的几个版本才支持rtmp服务,本文选择版本 nginx 1.7.11.3 Gryphon.zip 解压下载zip文件 在conf文件夹中找到 nginx-win.conf 配置我们所需要的内容 rtmp是adobe基于flash开发的音视频

    2024年02月15日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包