CentOS 7.7 下 WebRTC Janus-Gateway 部署指南:从依赖解析到生产环境调优
在 2024 年依旧跑 CentOS 7.7 的老机器上折腾 WebRTC,就像给 90 年代的桑塔纳装涡轮:能跑,但得先解决一堆“不兼容”。本文把我在两台 4C8G 云主机上踩过的坑写成可复制的脚本,帮你把 Janus 从源码编译到上线调优一次搞定。全程命令行,无图胜有图。
- 背景痛点:老系统与新玩具的“代沟”
- CentOS 7.7 自带 GLib 2.56,而 Janus ≥1.1.x 要求 GLib ≥2.62,直接 yum 安装会报
configure: error: GLib version too old。 - 内核 3.10 的 WebSocket 子系统没有
SO_REUSEPORT的多队列优化,Janus 的libwebsockets在高并发下 CPU 飙高。 - 默认仓库连
libsrtp2都没有,只有 1.5,DTLS 1.3 握手直接失败,Chrome 报DTLS alert 80。
一句话:要么升级,要么放弃;既然不放弃,就源码硬刚。
- 技术方案:源码升级关键依赖
下面所有命令均在干净 CentOS 7.7 最小化安装环境验证通过,普通用户加 sudo,root 请自觉去掉 sudo。
2.1 升级 GLib 到 2.62+(源码方式)
# 1. 先装编译工具链 sudo yum groupinstall "Development Tools" -y sudo yum install python3 python3-devel meson ninja-build -y # 2. 源码编译 GLib 2.62 cd /usr/local/src sudo curl -L -o glib-2.62.6.tar.xz https://download.gnome.org/sources/glib/2.62/glib-2.62.6.tar.xz sudo tar -xf glib-2.62.6.tar.xz && cd glib-2.62.6 sudo meson setup _build --prefix=/usr/local/glib-2.62 sudo ninja -C _build install # 3. 写 pkgconfig 路径 echo 'export PKG_CONFIG_PATH=/usr/local/glib-2.62/lib/pkgconfig:$PKG_CONFIG_PATH' | sudo tee /etc/profile.d/glib226.sh source /etc/profile.d/glib226.sh优劣对比
- 源码:版本新,Janus 编译通过;后续升级灵活。
- yum(elrepo-testing):简单一条命令,但可能停留在 2.58,仍不够。
2.2 安装 libsrtp2(EPEL 即可)
sudo yum install epel-release -y sudo yum install libsrtp-devel libsrtp-utils -y注意:如果内网机器无法不到外网,可提前下载 rpm 然后rpm -Uvh *.rpm,比源码编译省 10 分钟。
2.3 其他 Janus 硬依赖
sudo yum install libconfig libmicrohttpd libwebsockets jansson \ openssl-devel opus-devel libogg-devel -y- 核心实现:编译 Janus 与最小可用配置
3.1 获取源码
cd /usr/local/src sudo git clone https://github.com/meetecho/janus-gateway.git cd janus-gateway sudo git checkout v1.2.2 # 写本文时最新 stable3.2 编译 & 安装
sh autogen.sh ./configure --prefix=/opt/janus \ --enable-websockets --enable-post-processing \ --enable-dtls-settimeout make -j$(nproc) sudo make install sudo make configs # 自动生成样例配置3.3 配置文件关键参数(/opt/janus/etc/janus/janus.jcfg)
# 限制 UDP 端口范围,方便防火墙一次性放行 nat: { ice_udp_port_range = "10000-10200" stun_server = "stun.l.google.com" stun_port = 19302 } # DTLS 证书:自签即可,浏览器只校验指纹 certificates: { cert_pem = "/opt/janus/share/certs/mycert.pem" cert_key = "/opt/janus/share/certs/mycert.key" }生成自签证书
sudo mkdir -p /opt/janus/share/certs sudo openssl req -x509 -newkey rsa:2048 -keyout /opt/janus/share/certs/mycert.key \ -out /opt/janus/share/certs/mycert.pem -days 365 -nodes \ -subj "/CN=janus.example.com"3.4 最小可用 systemd 单元
# /etc/systemd/system/janus.service [Unit] Description=Janus WebRTC Gateway After=network.target [Service] Type=notify ExecStart=/opt/janus/bin/janus --configs-folder=/opt/janus/etc/janus Restart=on-failure RestartSec=5s LimitNOFILE=65536 [Install] WantedBy=multi-user.targetsudo systemctl daemon-reload sudo systemctl enable --now janus3.5 验证服务:janus-pp-rec 录制回放
# 先让浏览器发布流,然后调用录制插件 curl -H "Content-Type: application/json" \ -X POST http://localhost:8088/janus/record/start \ -d '{"request":"start","filename":"/tmp/test.mjr"}' # 结束录制 curl -X POST .../stop # 转码成 webm /opt/janus/bin/janus-pp-rec /tmp/test.mjr /tmp/test.webm能正常播放 webm 说明 DTLS + SRTP 链路已通。
- 避坑指南:让 Janus 在 NAT/防火墙里“说人话”
4.1 「Failed to create ICE agent」
现象:日志里反复刷ICE failed, no usable pair。
根因:云主机内网 IP 与公网映射不一致,Janus 默认拿内网 IP 当 host candidate。
解决:
# janus.jcfg nat: { # 告诉 Janus 公网地址 public_ip = "1.2.3.4" # 或者走 1:1 映射 iceserver = "turn:turn.example.com:3478?transport=tcp" turn_user = "janus" turn_pwd = "janus123" }4.2 段错误 & 核心转储
场景:开了libasan调试内存泄漏,结果一跑压力就SIGSEGV。
调试:
# 1. 打开 core echo "kernel.core_pattern=/tmp/core.%e.%p" | sudo tee /etc/sysctl.d/99-core.conf sudo sysctl -p /etc/sysctl.d/99-core.conf ulimit -c unlimited # 2. 运行 janus 直到崩溃 sudo gdb /opt/janus/bin/janus /tmp/core.janus.* (gdb) bt80% 的崩溃来自glib2版本混用:系统 2.56 与/usr/local2.62 混链,确认ldd /opt/janus/bin/janus | grep glib只出现 2.62 路径即可。
- 性能调优:把 UDP 缓冲区“拉满”
5.1 内核参数
# /etc/sysctl.d/99-janus.conf net.core.rmem_max = 26214400 net.core.wmem_max = 26214400 net.ipv4.udp_mem = 65536 131072 262144 net.core.netdev_max_backlog = 3000sudo sysctl -p /etc/sysctl.d/99-janus.conf5.2 单会话限速(避免 1 个用户把 1 Gbps 跑满)
# 假设 Janus 跑在 UDP 10000-10200 tc qdisc add dev eth0 root handle 1: htb tc class add dev eth0 parent 1: classid 1:10 htb rate 10mbit ceil 10mbit tc filter add dev eth0 parent 1: protocol ip prio 1 u32 \ match ip dport 10000 0xff00 flowid 1:10- 小结 & 开放问题
至此,CentOS 7.7 老底子的系统也能跑出低延迟、可录制、可扩展的 SFU 服务。Janus 的插件架构留了一个很灵活的口子:所有信令交互都走janus.c的incoming_request,再通过plugin->handle_message分发给具体插件。
那么,下一个问题来了:
如何基于 Janus 的插件机制实现自定义信令协议?比如把 WebSocket JSON 换成二进制 Protobuf,或者把 MQTT 指令桥接进来?欢迎一起动手试。
如果你更想“先跑起来再折腾”,推荐直接体验火山引擎的从0打造个人豆包实时通话AI动手实验:它把 ASR→LLM→TTS 整条链路封装成可插拔的 Web 模板,10 分钟就能在浏览器里跟 AI 语音对话。我本地 Janus 跑通后,把实验里的 TTS 流推到同一个房间,秒变“实时语音客服”,小白也能顺利复刻。