现有市场上的主流直播在传输方面,大部分使用TCP传输,也有部分使用UDP传输(类似上行使用rtc,然后在源站或者媒体服务器转换为rtmp协议再进行推流)。通常来说,udp效率更高一些,但由于自身无连接缺少确认机制,缺少丢包重传,所以通常开发者会增加冗余来对抗网络的不稳定性,这也造成了流量费用的增加;TCP自身做了重传,确保可靠和顺序性,所以在对实时性要求并不高的直播,使用TCP是个很好的选择。
网易云信直播sdk目前使用了TCP进行传输,而且基于此从编码动态适配,发送队列调整,协议优化,socket等做了全流程的优化,确保我们在限带宽,丢包,时延,抖动,无论单项,还是复杂网络,都有不输于竞品的体验。
优化的细节指标:
在不牺牲卡顿率的情况下,提升带宽利用率8成以上,码流更平稳。
优化的理论基础:
为了防止网络的拥塞现象,TCP提出了一系列的拥塞控制机制。最初由V.Jacobson在1988年的论文中提出的TCP的拥塞控制由“慢启动(Slowstart)”和“拥塞避免(Congestionavoidance)”组成,后来TCPReno版本中又针对性的加入了“快速重传(Fastretransmit)”、“快速恢复(FastRecovery)”算法,再后来在TCPNewReno中又对“快速恢复”算法进行了改进,近些年又出现了选择性应答(selectiveacknowledgement,SACK)算法,还有其他方面的大大小小的改进,包括google优化后的BBR算法(目前移动端无法使用),成为大家研究的一个热点。
快速重传:
快速重传算法要求首先接收方收到一个失序的报文段后就立刻发出重复确认,而不要等待自己发送数据时才进行捎带确认。接收方成功的接受了发送方发送来的M1、M2并且分别给发送了ACK,现在接收方没有收到M3,而接收到了M4,显然接收方不能确认M4,因为M4是失序的报文段。如果根据可靠性传输原理接收方什么都不做,但是按照快速重传算法,在收到M4、M5等报文段的时候,不断重复的向发送方发送M2的ACK,如果接收方一连收到三个重复的ACK,那么发送方不必等待重传计时器到期,由于发送方尽早重传未被确认的报文段。
快速恢复:
当发送发连续接收到三个确认时,就执行乘法减小算法,把慢启动开始门限(ssthresh)减半,但是接下来并不执行慢开始算法。
此时不执行慢启动算法,而是把cwnd设置为ssthresh的一半,然后执行拥塞避免算法,使拥塞窗口缓慢增大。
TCP的拥塞控制主要原理依赖于一个拥塞窗口(cwnd)来控制,TCP还有一个对端用的接收窗口(rwnd)用于流量控制。窗口值的大小就代表能够发送出去的但还没有收到ACK的最大数据报文段,显然窗口越大那么数据发送的速度也就越快,但是也有越可能使得网络出现拥塞,如果窗口值为1,那么就简化为一个停等协议,每发送一个数据,都要等到对方的确认才能发送第二个数据包,显然数据传输效率低下。TCP的拥塞控制算法就是要在这两者之间权衡,选取最好的cwnd值,从而使得网络吞吐量最大化且不产生拥塞。
由于需要考虑拥塞控制和流量控制两个方面的内容,因此TCP的真正的发送窗口=min(rwnd,cwnd)。但是rwnd是由对端确定的,网络环境对其没有影响,所以在考虑拥塞的时候我们一般不考虑rwnd的值,我们暂时只讨论如何确定cwnd值的大小。关于cwnd的单位,在TCP中是以字节来做单位的,我们假设TCP每次传输都是按照MSS大小来发送数据的,因此你可以认为cwnd按照数据包个数来做单位也可以理解,所以有时我们说cwnd增加1也就是相当于字节数增加1个MSS大小。
优化的具体内容:
TCP的慢启动,拥塞避免,快速重传机制告诉我们,在应用层拥堵之前,会快速降低拥塞窗口大小,导致tcp通道可发送带宽会快速降低,这个时候如果不快速降低数据流量,会大量丢包重传,应用层会进入拥堵状态。导致恶化
我们通过观测若干系统反馈的socket健康指标,一旦发现该socket进入快速重传,我们会提前降低视频的编码参数;同时如果周期一直健康状况良好,我们测算的可发送带宽也大于实际发送大小,我们会缓慢提升视频的编码参数;
整个调优会基于快降慢升,音频优先的原则来实施