在软交换中,经常有公网转发音频、视频媒体的需求,开源软件有rtpproxy、rtpengine之类,但性能并不是太好,经常有人说跑音、视频几百路就把机器CPU跑满了。
以前写过一篇“跨平台、高性能的媒体转发服务器实现”,本质上是sip软交换B2B服务器,那篇文章对于媒体rtp的转发使用的还是epoll,性能还算马马虎虎,大体上和rtpproxy、rtpengine是一类水平。
Linux有个较新的技术,叫XDP,也叫eBpf,允许我们写一个内核级别的模块,将其绑定到网卡上,数据包还没上达协议栈之前就可以被我们的内模块进行处理:或者丢弃,或者转发,或者放行——正常上达协议栈。XDP是比较新的、热门的技术,很多大厂用它来实现防火墙、负载均衡等,我用它来实现 RTP数据的转发,可谓xdp最佳应用。
xdp内核模块如此早就对数据包进行处理,相当于驱动层或者至少是内核层级别的速度,性能相当优异,经测试比起普通的应用层转发,有10到30倍以上的性能提升,而且转发速度飞快,几乎没有延时。
下面简单说一下要点:
1、对 Linux内核有要求,太老的内核是不能支持 XDP的。我的环境是 CentOS 7,但内核升级到5.4.232。
2、需要安装 libBpf,开发环境需要安装最新的 clang、llvm,运行环境则不需要。
3、写好内核模块后,我在虚拟机上测试,按默认安装为xdpdrv,不能通过,一开始以为是校验和计算不对,深入调试后,发现改为xdpgeneric模式附加到网卡就可以。在客户的云服务器上,安装为 xdpdrv模式一切正常。
4、如前所述,将 rtp数据包用 XDP模块转发后,数据包无法上传到操作系统的协议栈——这正是它高效的原因,带来的问题是无法用tcpdump抓包,如果要使用普通的抓包录音软件,是没办法录到的。解决方法是在xdp和用户层程序进行通信,xdp内核模块在转发之前将数据提交给我们的程序,程序将rtp包写入wav文件,这里很多细节,有一定的复杂度。
经测试3000路rtp媒体转发(使用g711u音频),如果不录音,系统cpu没有上升,仅仅信令处理占用cpu在9%以下。如果录音,应用层增加的cpu也很小,几个百分点而已。
对XDP、eBpf、音频视频媒体转发技术感兴趣的,欢迎讨论。程序可以试用,欢迎压力测试。