perf+flamegraph 分析 nginx-rtmp 性能

perf+flamegraph 分析 nginx-rtmp 性能


问题

最近在对 Nginx-rtmp 进行性能测试时发现,当一路推流的观看者数量达到一定上限后,会出现推流断流现象。推流配置了:

drop_idle_publisher 3s;

最后分析得到的结果,在 ngx_rtmp_recv 中,一路流并发路数过多时,会导致 ngx_rtmp_receive_message 执行时间过长(当并发数超过 1000 时,该函数执行时间会经常超过 20 ms)。当推流端接收数据速度大于该函数处理时长时,进程处理流程无法退出 ngx_rtmp_recv,下次退出 ngx_rtmp_recv 超过 3s 时,推流被断掉。

下图是不同码率不同并发下,20000 个采样点的数据

perf+flamegraph 分析 nginx-rtmp 性能_第1张图片

该问题不仅会导致正在处理的流被断掉,还会导致该进程上其它流无法处理被饿死,因此有必要分析 ngx_rtmp_receive_message 消耗点在哪儿。

环境安装

  • 安装 perf

    yum install -y perf
    
  • 安装 flamegraph

    git clone https://github.com/brendangregg/FlameGraph.git
    mv FlameGraph/ /usr/local/flamegraph
    

    在 /usr/local/bin 下放置 flamegraph 脚本,脚本内容:

    #!/bin/bash
    
    perf script > perf.tmp1
    /usr/local/flamegraph/stackcollapse-perf.pl perf.tmp1 > perf.tmp2
    /usr/local/flamegraph/flamegraph.pl perf.tmp2 > perf.svg
    rm -f perf.tmp1 perf.tmp2
    

    修改脚本权限

    chmod a+x /usr/local/bin/flamegraph
    
  • 安装 nginx-rtmp

    这个直接参考 https://github.com/arut/nginx-rtmp-module,唯一需要注意的是,在完成 configure 步骤后,需要修改 objs/Makefile 文件,将:

    CFLAGS =  -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g
    

    行中的 -O 改为 -O0,否则后面采集到的数据看不到 Nginx 程序的堆栈,修改完成后再

    make && make install
    

开始测试

  • 使用 ffmpeg 推流

    ffmpeg -re -i  after.flv  -map 0 -flags +global_header -sn -acodec copy -vcodec libx264 -preset superfast  -b:v 100k -bufsize 1800k -maxrate 100k -g 90  -f flv  rtmp://172.16.26.22/cdntest/live1
    
  • 使用 srs-bench 并发拉流

    sb_rtmp_load  -c 500 -r rtmp://172.16.26.22/cdntest/live1
    
  • 启动 perf 采集 nginx worker 进程数据

    perf record -p  -g
    

    pid 是指定的 nginx worker 进程的进程 ID,一般采集 1-2 分钟即可,时间太长,数据文件会比较大

  • 绘制火焰图

    完成上面采集后,使用安装时建立好的 flamegraph 脚本,直接执行即可

    flamegraph
    

    该过程执行时间会比较长,耐心等待即可,完成后得到一个 perf.svg 文件。直接使用浏览器打开

火焰图

perf+flamegraph 分析 nginx-rtmp 性能_第2张图片

从图中可以看到,系统的 99.53% 均消耗在 ngx_rtmp_receive_message,而该函数主要消耗在 ngx_rtmp_live_av 中,向用户发送音视频数据上。消耗点在内核态上,怎么去解决,就留给各位看官了。

唯一的建议是控制一个流上的并发观看用户数,打散热点

你可能感兴趣的:(Nginx)