在实战中使用nginx-rtmp遇到的TCP连接问题分析
在实战中使用nginx-rtmp遇到的TCP连接问题分析
背景
前段时间公司做了一次体育赛事的现场直播,网络由某通信公司负责搭建,主要测试5G CPE上行网络的带宽和稳定性,为了做到万无一失,他们同时搭建了一条用作备份的400M光纤线路。通过配置交换机来做到主备切换,要达到以下的效果:
- 无线链路down掉,交换机自动检测到丢包,丢包到指定数量(可以在交换机中配置),自动切换到备用链路。
- 无线链接恢复,备用链路切换回无线链路。
参考 静态路由与SLA技术
我们采用nginx-rtmp搭建了2层CDN。

测试
推流端推送RTMP流会向nginx-rtmp发送请求建立TCP链接,推流过程中,把交换机上的无线链路网线拔掉。自动切换到光纤线路,推流端重连后依然不能够成功建立链接,推流软件卡死。
server端的TCP链接一直存在:
root@iz2zehy7gff0ksipgb4ch3z /u/l/nginx# netstat -natp | grep "1936"
tcp 0 0 0.0.0.0:1936 0.0.0.0:* LISTEN 9467/nginx: master
tcp 0 0 192.168.199.6:1936 223.71.3.82:46012 ESTABLISHED 11177/nginx: worker
nginx 报错了:
2019/05/20 15:44:58 [error] 6947#0: *286 live: already publishing, client: 223.71.3.82, server: 0.0.0.0:1936
此时
就是因为无线链接断开时,TCP链接不能够被正常关闭,publisher会一直存在导致的。
复习一下四次挥手:

我们知道TCP连接有一个特性:
TCP 连接一旦建立,只要通信双方之间的中间结点(包括网关和交换机、路由器等网络设备)工作正常,那么在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。TCP 连接的这种特性,使得一个长期不交换任何信息的空闲连接可以长期保持数小时、数天甚至数月。中间路由器可以崩溃、重启,网线可以被挂断再连通,只要两端的主机没有被重启,TCP 连接就可以被一直保持下来。
可以看到,网线虽然断掉了,但是server端没有收到client的任何消息,server端不会主动发起挥手,因此连接会一直维持很长一段时间(我的测试机器上大概数小时)。链接断开后server端一直在发送PSH+ACK:

如何才能实现快速重连
为源站加load balance
加一个备源和一个调度服务,调度策略采取轮询,两次连续的TCP连接请求会被定向到不同的源站上面。这个方法治标不治本,切一次可以,如果无线链路恢复,再切回来的时候,可能TCP链接还没有关闭。

添加drop_idle_publisher
Syntax: drop_idle_publisher timeout
Context: rtmp, server, applicationDrop publisher connection which has been idle (no audio/video data) within specified time. Default is off. Note this only works when connection is in publish mode (after sending publish command).
drop_idle_publisher 10s;
nginx-rtmp会在指定的时间内丢弃空闲的publisher:
root@iz2zehy7gff0ksipgb4ch3z /u/l/n/logs# netstat -natp | grep "1936"
tcp 0 0 0.0.0.0:1936 0.0.0.0:* LISTEN 11421/nginx: master
tcp 0 0 192.168.199.6:1936 61.148.243.150:9338 ESTABLISHED 12923/nginx: worker
tcp 0 1 192.168.199.6:1936 223.71.3.82:47240 FIN_WAIT1 -
我们将drop_idle_publisher设置为2s,抓包可见这次是server端在2s后探测到这个TCP连接处于空闲状态,主动发起了挥手消息,此时publisher就被释放掉了,再次推流会重新建立新的TCP,重新生成此publisher。

上图是链路断掉后,TCP链接完全断开前server端向client发送的数据包,可以看到一直在发送FIN+最后一个数据包的ACK,时间间隔大概为 0.2秒->0.4秒->0.8秒->1.6秒->3.2秒->6.4秒->12.8秒->25.6秒
这种方法是可行的。
so_keepalive
listen
syntax: listen (addr[:port]|port|unix:path) [bind] [ipv6only=on|off] [so_keepalive=on|off|keepidle:keepintvl:keepcnt|proxy_protocol]
context: server
Adds listening socket to NGINX for accepting RTMP connections
关于TCP探活机制的几个参数的说明:
- keepcnt 关闭一个非活跃连接之前进行探测的最大次数t
- keepidle 对一个连接进行有效性探测之前运行的最大非活跃时间间隔
- keepintvl 两个探测的时间间隔
设置如下参数:
listen 1936 so_keepalive=5s:2:2;

可以看到,最后一个ACK没有回复后隔了5秒开始TCP keep-alive 探活,总共两次,间隔2秒,最后发送RST+ACK断开了TCP连接 。
参考
在实战中使用nginx-rtmp遇到的TCP连接问题分析的更多相关文章
- Ubuntu中使用Nginx+rtmp搭建流媒体直播服务
一.背景 本篇文章是继上一篇文章<Ubuntu中使用Nginx+rtmp模块搭建流媒体视频点播服务>文章而写,在上一篇文章中我们搭建了一个点播服务器,在此基础上我们再搭建一个直播服务器, ...
- Ubuntu中使用Nginx+rtmp模块搭建流媒体视频点播服务
1. 背景 不知不觉笔者来到流媒体部门已经一年半多了,积攒了不少的流媒体知识,但平时工作也比较忙,很少进行总结性的梳理,最近准备花几个周末时间写一个流媒体系列的实践文章,也算是给自己做总结的同时帮助有 ...
- linux中top命令使用及查看tcp连接
Linux top命令 介绍:top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,Linux top命令用于实时显示 process 的动态,即可以通过用户按键来不断 ...
- Centos7 搭建Nginx+rtmp+hls直播推流服务器
1 准备工具 使用yum安装git [root~]# yum -y install git 下载nginx-rtmp-module,官方github地址 // 通过git clone 的方式下载到服务 ...
- TCP连接中的状态
1. 正常状态转换 我们用图 3-13 来显示在正常的 TCP 连接的建立与终止过程中,客户与服务器所经历的不同状态.读者可以对照图 3-12 来阅读,使用图 3-12 的状态图来跟踪图 3-13 的 ...
- Android中直播视频技术探究之---视频直播服务端环境搭建(Nginx+RTMP)
一.前言 前面介绍了Android中视频直播中的一个重要类ByteBuffer,不了解的同学可以 点击查看 到这里开始,我们开始动手开发了,因为我们后续肯定是需要直播视频功能,然后把视频推流到服务端, ...
- [微信小程序直播平台开发]___(二)Nginx+rtmp在Windows中的搭建
1.一个可以忽略的前言 Nginx (engine x) 是一个高性能的HTTP和反向代理服务,也是一个IMAP/POP3/SMTP服务.Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Ramble ...
- 转:Nginx RTMP 功能研究
看点: 1. Nginx 配置信息与使用. (支持 rtmp与HLS配置) 2. 有ffmpeg 编译与使用, 命令行方式来测试验证客户端使用. 转自:http://blog.cs ...
- centos7+nginx+rtmp+ffmpeg搭建流媒体服务器(保存流目录与http目录不要随意配置,否则有权限问题)
搭建nginx-http-flv-module升级代替rtmp模块,详情:https://github.com/winshining/nginx-http-flv-module/blob/master ...
随机推荐
- java通过http方式下载文件
package com.qiyi; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStr ...
- Bootstrap Table 查询(服务器端)、刷新数据
Refresh from url after use data option <!DOCTYPE html> <html> <head> <title> ...
- linux下修改主机名hostname方法(转载)
查看主机名: 在终端输入hostname 永久修改 第一步:#hostname oratest 第二步:修改/etc/sysconfig/network中的hostname 第三步:修改/etc/ho ...
- spring applicationContext.xml详解及模板
applicationContext.xml 文件 1.<context:component-scan base-package="com.eduoinfo.finances.ba ...
- hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- ReentrantLock(重入锁)简单源码分析
1.ReentrantLock是基于AQS实现的一种重入锁. 2.先介绍下公平锁/非公平锁 公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁. 非公平锁 非公平锁是指多个线程获取锁的顺序并不是按照申 ...
- guava cache与spring集成
缓存的背景 缓存,在我们日常开发中是必不可少的一种解决性能问题的方法.简单的说,cache 就是为了提升系统性能而开辟的一块内存空间.在cpu进行计算的时候, 首先是读取寄存器,然后内存,再是硬盘.由 ...
- Linux-VMware三种网络模式
虚拟机网络模式 对于VMware虚拟软件来说,有三种网络模式 1.桥接 2.NAT 3.Host-only 桥接 桥接网络是指本地物理网卡和虚拟网卡通过VMnet0虚拟交换机进行桥接,因此物理网卡和虚 ...
- [noip2014day1-T2]联合权值
无向连通图 G 有 n 个点,n-1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 Wi,每条边的长度均为 1.图上两点(u, v)的距离定义为 u 点到 v 点的最短距离.对于图 G ...
- codeforces B. Polo the Penguin and Matrix 解题报告
题目链接:http://codeforces.com/problemset/problem/289/B 题目意思:给出一个 n 行 m 列的矩阵和数值 d .通过对矩阵里面的数进行 + d 或者 - ...