转载请注明出处:https://blog.csdn.net/impingo
项目地址:https://github.com/im-pingo/pingos

多进程问题背景

由于nginx的架构设计是多进程模式,即一个master进程创建一个或者多个worker进程,网络请求会被随机均分给每个worker进程,网络事件在worker进程中处理,同时每个worker进程的内存空间是相对独立的。

假设当前有三个worker进程(1号、2号、3号),rtmp流A发布在1号进程。此时如果有三个播放端请求流A,但是该请求被分配到了1号、2号和3号worker进程,只有被分配到1号进程的请求能获取到播放内容,2号和3号进程上无法获取到流A的内容。
也就是说多个worker进程共享一个网络端口,从这个网络接口过来的请求被随机分配给不同的worker进程,无法将请求指定传递给某一个worker进程。如下图:

创建
创建
创建
master监听端口1935
worker1
worker2
worker3
创建
创建
创建
推送流
播放
播放
播放
master
worker 1
worker 2
worker 3
主播
播放成功
播放失败
播放失败

进程间回源实现原理

为了能够将请求准确传递给指定进程,nginx-rtmp-module为每个worker进程监听不同的端口,同时记录下每条流和进程号之间的映射表(使用共享内存保存),当某个进程收到播放请求时如果该流不在当前进程中发布就查询这张映射表并且向目标进程的独立端口(此端口可以是TCP、UDP或者unix套接字端口)发起回源请求。nginx监听端口情况如下图:

创建
创建
创建
Master监听端口1935
worker1监听unix_1套接口
worker2监听unix_2套接口
worker3监听unix_3套接口

同样的问题,如果推流到1号进程,而播放请求被分配到2号和3号进程,2号和3号进程在发现本身进程没有该流之后向1号进程拉流,则2号和3号进程上就同样有了此路流,借助此特性播放端请求无论被分配给几号进程都可以拉取到直播流。

推送流
从unix_1套接口回源拉流
从unix_1套接口回源拉流
播放
播放
播放
主播
worker 1
worker 2
worker 3
播放成功
播放成功
播放成功

使用nginx-rtmp-module实现进程间回源

配置项参数类型默认值描述
multi_listen多项多进程监听独立端口的配置选项,必须配置在events中。配置规则:multi_port [映射后的起始端口或unix端口前缀] [被映射的端口]。例如要将1935端口映射给每个worker进程,让每个进程监听一个独立的unix套接字,就可以配置成 multi_port unix:/tmp/rtmp 1935;
rtmp_auto_pull布尔类型on是否打开进程间回源功能
rtmp_auto_pull_port字符串unix:/tmp/rtmp每个进程监听的unix端口前缀或者tcp/udp起始端口,注意要与 multi_port的第一个参数保持一致

配置示例:

user  root;
daemon on;
master_process on;
worker_processes  10;
#worker_rlimit 4g;
#working_directory /usr/local/openresty/nginx/logs;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
error_log  logs/error.log  info;

worker_rlimit_nofile 102400;
worker_rlimit_core   2G;
working_directory    /tmp;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
    multi_listen unix:/tmp/rtmp 1935;
}
stream_zone buckets=1024 streams=4096;

rtmp {
    server {
        listen 1935;
        application live {
            rtmp_auto_pull on;
            rtmp_auto_pull_port unix:/tmp/rtmp;
            send_all off;
            zero_start off;
            live on;
            hls on;
            hls_path /tmp/hls;
            wait_key on;
            wait_video on;
            cache_time 2s;
            low_latency on;
            fix_timestamp 2000ms;
            # h265 codecid, default 12
            hevc_codecid  12;
        }
    }
}

http {
    server {
        listen     80;
	    location / {
           chunked_transfer_encoding on;
            root html/;
        }
        location /flv {
            flv_live 1935 app=live;
        }
        location /ts {
            ts_live 1935 app=live;
        }
        location /rtmp_stat {
            rtmp_stat all;
            rtmp_stat_stylesheet /stat.xsl;
        }
        location /xstat {
            rtmp_stat all;
        }
        location /sys_stat {
            sys_stat;
        }
        location /hls {
              # Serve HLS fragments
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            root /tmp;
            add_header Cache-Control no-cache;
        }
        location /dash {
            # Serve DASH fragments
            root /tmp;
            add_header Cache-Control no-cache;
        }
    }
}

QQ交流群:697773082

Logo

鸿蒙生态一站式服务平台。

更多推荐