ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Jitsi Meet核心组件Prosody:信令中枢的配置与排障实战

Jitsi Meet核心组件Prosody:信令中枢的配置与排障实战 做视频会议运维这些年我最大的感触是Jitsi Meet 这摊子事表面上是个网页应用真到排查故障的时候十有八九是在跟一个叫 Prosody谐音“破扫敌”的家伙打交道。很多人一看到这三个组件 Jicofo、JVB、Prosody 就头大觉得里面最不起眼的就是这个 Prosody体积小、名字怪、平时吭哧吭哧也不吭声。但恰恰是它撑起了整个 Jitsi Meet 的信令神经系统。你开会时能不能进房间、能不能看到谁在线、权限对不对、房间能不能创建成功全由它说了算。这篇文章我就围绕 Jitsi 里的 Prosody 展开从它在整体架构中的定位到配置文件的核心逻辑再到我实际部署和排障中踩过的坑尽量讲透。无论你是刚准备自建 Jitsi Meet 的小白还是已经在线上跑着服务、时不时被会议异常搞得焦头烂额的老手这篇文章都应该能给你一些参考。1. 为什么折腾 Jitsi 的人绕不开 Prosody 这个小家伙先说个我自己的经历。去年有段时间公司内部 Jitsi 服务频繁出现“无法加入会议”“提示连接中”的情况前端页面打开正常但一点“加入会议”就转圈。当时我们几个工程师围着 Nginx 日志、JVB 日志翻了一下午愣是没找到问题。最后是团队里一个老哥不耐烦地说了一句你们去看看 Prosody 的日志。结果打开 journalctl 一看里面全是一行一行的证书验证失败和域名不匹配报错问题根源一下子就暴露了。从那以后我就意识到在 Jitsi 这套系统里Prosody 就像人体里的神经系统——平时感觉不到它的存在一旦它出问题整个身体立刻瘫掉。理解它是玩转 Jitsi Meet 的基本功。1.1 Prosody 是什么一个用 Lua 写的轻量级 XMPP 服务器Prosody 本身并不是 Jitsi 的专有组件它是一个通用的、开源的 XMPPExtensible Messaging and Presence Protocol可扩展消息与在线状态协议服务器用 Lua 语言写成。XMPP 这个协议你可能听说过它是早期即时通讯软件比如谷歌 Talk 的老底子广泛使用的通信协议擅长处理在线状态、消息路由和多用户聊天室。之所以 Jitsi 团队会在众多 XMPP 服务器里挑中 Prosody而不是用更老牌的 Openfire 或者 ejabberd我看主要是三个原因轻量Lua 写的服务端内存占用小单机部署 Jitsi Meet 时不至于一台 2G 内存的机器就被压垮。易于嵌入Prosody 的模块化设计极好可以非常方便地通过 Lua 插件扩展认证方式、会议房间逻辑等。和 Jitsi 生态深度绑定Jitsi 官方文档和安装脚本直接适配 Prosody开箱即用的集成度远高于自己手动折腾其他 XMPP 服务器。1.2 轻松一下为什么大家都叫它“破扫敌”标题里这个谐音“破扫敌”可能有人觉得奇怪其实是因为 Prosody 这个单词正常读法接近“普罗索迪”国内社区一些朋友图顺口就给它起了个“破扫敌”的土名。名字土归土功能可一点不含糊。你在搜资料的时候偶尔能看到有人用这个调侃称呼知道指的是它就够了。2. Prosody 在 Jitsi 架构中的位置信令神经中枢不是交通警察新手最容易犯的一个认知错误是把 Prosody 当成“负责转发视频流量的工具”。实际上在 Jitsi Meet 的架构里流媒体也就是你的视频和声音数据根本不经过 Prosody它走的是 WebRTC 的 UDP 通道直连 Jitsi VideobridgeJVB。Prosody 的主要职责是信令面管理客户的在线状态、房间创建/销毁、用户权限验证、消息路由。打个比方Prosody 是电话交换机负责接通和调度而真正通话的声音是通过独立的电话线媒体通道传送的。2.1 一个会议从发起到结束Prosody 都干了什么我给你完整梳理一下当你打开 Jitsi Meet 页面、输入会议室名字、点“加入”的那一刻后台到底发生了什么浏览器向 Nginx 请求页面资源加载完前端 JS。前端 JS 通过WebSocket默认端口 443 或独立 5280 端口与 Prosody 建立 XMPP 连接。Prosody 完成匿名或 token 认证并分配一个会话 ID。前端向 Prosody 发送创建/加入 MUC多用户聊天室在这里就对应“会议室”请求。Prosody 里的mod_muc模块创建房间并返回会议室内的在线用户列表。前端拿着这个会议信号向JicofoJitsi Conference Focus请求分配媒体传输节点。Jicofo 与 JVB 沟通分配媒体端口再把连接信息通过 Prosody 传回浏览器。浏览器正式与 JVB 建立 WebRTC 媒体流会议画面开始出现。看到没有这一步一步的过程里除了第 8 步建立媒体流之外其余几乎每一环都要经过 Prosody 中转。一旦 Prosody 挂掉或者配置有问题用户要么进不了房间要么进去了也看不到别人上线但页面却是“正常”的极具迷惑性。2.2 与 Jicofo、JVB 的三方配合关系我把这三个组件的关系理解成“餐厅运作”Prosody 是前台接待负责引导你进包间会议室、核对身份、查看包间里有哪些人。Jicofo 是调度经理看到你进包间了就立刻安排厨师和服务员也就是协调 JVB 准备媒体通道。JVB 是后厨真正负责把食材音视频流加工、分发给其他客人。Jicofo 自身也会作为一个特殊的 XMPP Client 登录到 Prosody 上通常是 focus 用户它通过 Prosody 来获取会议室状态。所以一旦 Prosody 挂了Jicofo 也会变成一个无头苍蝇日志里充斥着连接失败。你如果在 Jicofo 日志里看到一堆connection failed之类的内容不要先怀疑 Jicofo 本身先去看看 Prosody 还活着没有。3. Prosody 配置核心拆解VirtualHost、Component 和模块三板斧Prosody 的默认配置文件在 Debian/Ubuntu 上位于/etc/prosody/prosody.cfg.lua是 Lua 语法。很多没接触过 Lua 的人一看这格式就发怵其实它的配置逻辑并不复杂核心就三个概念VirtualHost、Component 和模块modules_enabled。3.1 VirtualHost虚拟主机一个 Prosody 管多个域名VirtualHost 可以理解为“虚拟域”。在 Jitsi 的标准部署中你通常会看到两个 VirtualHostVirtualHost meet.example.com authentication token app_id jitsi app_secret 你的共享密钥 -- 其他参数 VirtualHost guest.meet.example.com authentication anonymous c2s_require_encryption false第一个meet.example.com是给内部认证用户用的通过 token 认证第二个guest.meet.example.com是给匿名访客用的。为什么要拆两个因为 Jitsi 支持两种加入模式如果你自己搭了自带鉴权的上层服务比如集成到自己的企业 OA 系统就走 token 认证如果只是拿 Jitsi 当一个任何人都能开的临时会议室就允许匿名。拆开的好处是职责清晰也方便单独调整安全策略。3.2 Component外部组件接入的入口Component 是 Prosody 里最容易忽略又最关键的存在。Jitsi 的会议功能本质上是依赖 MUC 组件来完成的默认配置中你会看到Component conference.meet.example.com muc restrict_room_creation admin max_rooms 50这行的意思是在conference.meet.example.com这个子域上启用 MUC 组件并且限制只有管理员才能创建房间。这里的restrict_room_creation admin很关键如果不设置或者设置不当可能出现任何用户都能建一堆房间最后把服务器资源耗光的情况。3.3 模块Prosody 的功能开关一个都不能少modules_enabled 是一个列表里面列出的每个模块都对应一个功能。Jitsi 部署时有一些模块是必须启用的我列一份最核心的模块名作用如果不启用会怎样mod_muc多用户聊天室即会议室功能完全无法创建会议mod_auth_token基于 token 的认证方式带鉴权的用户全部无法登录mod_smacks流管理保证网络抖动时消息不丢弱网环境下会议状态容易不同步mod_websocket让浏览器通过 WebSocket 与 Prosody 通信前端无法建立 XMPP 连接mod_csi客户端状态指示优化移动端耗电移动端 Web 体验差mod_pubsub发布订阅服务很多扩展功能的基础组件部分 Jitsi 特性如举手、投票失效我在实际部署中踩过一次很搞笑的坑某个模块因为版本升级被禁用启动 Jitsi 后会议看起来正常但是别人“举手”时主持人端没有任何反应。排查了半天最后发现是mod_pubsub没加载。这类问题最难缠的地方在于症状与根因之间隔得很远你不熟悉模块架构根本想不到是那里出了问题。4. 配置中容易让 Prosody“闹脾气”的5个关键点Jitsi 官方的一键安装脚本通常已经帮你配好了大部分内容但凡是手动安装、或者对默认配置动过手脚的朋友大概率会撞上这几个坑。我逐个说一下现象和背后的原因。4.1 域名对不上证书验证失败与“房间不存在”现象浏览器控制台报 WebSocket 连接失败Prosody 日志里大量出现certificate verify failed或host unknown错误。原因Prosody 会对入站连接的目标域名进行校验。如果你的 VirtualHost 写的是meet.example.com但前端实际请求的是jitsi.example.org两者不一致就会直接拒绝。这个问题经常出现在你配置了 Nginx 反向代理、但忘记在 Prosody 里同步新域名的情况下。解决办法很简单修改prosody.cfg.lua里 VirtualHost、Component 的域名然后重启 prosody 服务。但这里有个隐藏点如果你用TurnServercoturn也要同步修改域名的 related 配置否则媒体协商时也会出错。4.2 内部密码不一致服务间无法相互照应Jitsi 的多个组件之间需要互相通信这种通信是通过 Prosody 上的不同账户完成的。例如 Jicofo 登录 Prosody 时使用的密码配置在/etc/jitsi/jicofo/sip-communicator.properties里而 Prosody 这边的prosody.cfg.lua里也要有同名用户和相同密码。我见过有人升级服务后只改了 Prosody 这边的密码忘了同步 Jicofo 的结果整个会议服务彻底罢工。排查这类问题看 Jicofo 日志里是否反复出现authentication failed就知道了。所以每次你改任何一处密码务必把以下这组对应关系全部过一遍Prosody 里的focus用户密码 Jicofo 配置文件里的JICOFO_AUTH_PASSWORD或 properties 里的值Prosody 里的jvb用户密码 JVB 配置文件/etc/jitsi/videobridge/sip-communicator.properties里的值Prosody 里的app_secret 前端如果走 token 认证时生成 token 用的同一个密钥4.3 WebSocket 被反向代理屏蔽前端能开页面但进不了会现象页面加载正常点完加入按钮后一直转圈同时 Prosody 日志里没有任何连接请求。原因浏览器与 Prosody 之间的 WebSocket 默认通过 Nginx 的/xmpp-websocket路径转发。如果你在 Nginx 配置里启用了 HTTPS 但没有正确配置map和location /xmpp-websocket的代理或者手动改 Nginx 时删掉了这段配置WebSocket 就会被掐掉。这个问题其实不算 Prosody 的锅但它的症状通常被误判为 Prosody 故障。我的排查习惯是先看浏览器 Network 面板里ws://开头的请求返回码如果是 404 或 502那大概率是 Nginx 层的问题不是 Prosody 的问题。4.4 内存不足Prosody 被 OOM Killer 干掉Prosody 本身很轻量一般开会到几十人也不会占太多内存。但 Prosody 会缓存每个连接的会话信息和已加入用户的 presence在线状态数据。如果一场大型会议有几百人在线且长时间不退出内存会缓步增长。当 VPS 内存不够时Linux 的 OOM Killer 会优先挑内存占用大的进程杀掉有时就是 Prosody。排查方法很简单systemctl status prosody如果显示Active: inactive (dead)或failed再看journalctl -k | grep -i oom有没有被 kill 的记录。预防手段一是升级内存二是在prosody.cfg.lua里适当调低连接数限制和会话超时时间三是设置 systemd 服务的Restartalways确保 Prosody 被误杀后能自动拉起。4.5 端口被占用5280 和 5222 的冲突Prosody 默认监听的端口包括5222XMPP C2S 客户端直连端口Jitsi 一般用 WebSocket不太用到它5269XMPP 服务器间通信端口S2S5280HTTP/WebSocket 对外服务端口5347Jicofo、JVB 等外部组件连接 Prosody 的端口Component 端口如果你在同一台机器上还跑了其他 XMPP 服务或者监控程序就可能把 5280 或 5347 占掉。Jitsi 的会议异常时先执行下面的命令看看端口占用情况ss -ltnp | grep -E 5222|5269|5280|5347我遇到过一台机器上同时装了旧的 ejabberd把 5222 和 5280 全部占满导致 Prosody 只能监听部分端口会议功能时好时坏。后来直接把旧服务卸载世界安静了。5. 排查 Prosody 问题的实战路径日志、命令和错误速查如果你现在已经遇到了 Jitsi 会议异常别急我按“先看哪里、再查什么、最后怎么改”的顺序给你一套可复制的排查流程。这一节是纯经验输出都是平时官方文档里不写细的东西。5.1 第一步去看 Prosody 的日志比猜重要一万倍Prosody 在 systemd 环境下的日志通常用 journalctl 查看journalctl -u prosody -f如果你想要更持久的日志记录可以在/etc/prosody/prosody.cfg.lua里找到log { info /var/log/prosody/prosody.log; error /var/log/prosody/prosody.err; }建议把 info 和 error 都开启线上排障时有用。日志一开你就能刷出类似下面这些信息Client disconnected: no session一般是 token 过期或 session 异常销毁。Failed to get password from auth认证密码不对。Invalid host请求的 VirtualHost 不存在。Component disconnectedJicofo 或 JVB 与 Prosody 的组件连接断开了。5.2 第二步快速检验 Prosody 本身状态用prosodyctl这个命令行工具可以快速检查配置和状态# 检查配置文件语法并加载模块 sudo prosodyctl check config # 检查具体域名状态 sudo prosodyctl check config meet.example.com # 列出所有注册用户 sudo prosodyctl list users # 重新加载配置 sudo prosodyctl reload其中check config是我每改一次配置文件都会执行一次的命令它能直接指出 Lua 语法错误、模块缺失、参数值不合法等明显问题比直接重启再等失败要高效得多。5.3 第三步常见错误与解决对照表我在维护过程中总结了一些高频错误信息做成表格方便你对照日志/现象可能的根因推荐解法certificate verify failed证书和域名不匹配或证书过期重新签发证书并prosodyctl cert importUnknown host: conference.xxxComponent 域名忘记写或拼错检查 Component 块配置重启 prosodyauthentication failed for focusJicofo 密码不一致同步 prosody 和 jicofo 的 focus 密码only local clients allowed外部组件从非白名单 IP 连接检查组件配置里的 IP 限制或防火墙websocket handshake failedNginx 反向代理配置问题检查 Nginx 的/xmpp-websocket代理配置这张表只是抛砖引玉实际环境千奇百怪但大多数问题都能追到域名、密码、模块、证书这四个筐里。6. 从能用走向好用Prosody 的性能调优和个人运维心得Jitsi 跑起来简单跑得稳就需要抠细节了。随着公司会议频率提高我从线上事故中总结了一些 Prosody 相关的调优和运维经验在这里一并分享。6.1 调整连接与会话参数应对百人会议默认配置对小型会议足够但如果你动不动就开几十上百人的全员会建议在prosody.cfg.lua里加上limits { c2s { rate 10kb/s; burst 20kb/s; }; };这个配置是对单连接速率做一个限制防止某些异常客户端比如发了一大堆 presence 的脚本把服务器连接占满。注意 rate 参数要结合你们真实网络的带宽情况来调设太小会导致弱网用户频繁掉线。另一个参数是max_rooms。默认配置可能允许任意数量的会议室创建如果某段时间内部有人写了个脚本批量开会占用资源服务器会很难看。我建议在 MUC Component 里加上Component conference.meet.example.com muc max_rooms 100 restrict_room_creation admin6.2 开启多实例与负载均衡先看看你的场景再说网上很多教程会让你搞一套 Prosody Jicofo JVB 的多实例集群方案。我个人观点是这种方式对于大部分中小团队来说有点过度设计。Prosody 本身的性能瓶颈通常在几百个用户量级上才会出现而且它承载的是文本信令对带宽的要求远低于视频流。如果只是为了增加可靠性可以做双 Prosody 共享数据库的方案。但 Prosody 默认把数据存在本地文件里/var/lib/prosody双实例需要配置共享存储或切到数据库存储。这块配置复杂度比单实例高不少我自己的经验是先通过监控发现问题再动手不要为了高可用而高可用。6.3 善用 systemd 守护和自动重启Jitsi 稳定运行最难防的就是“半夜 3 点进程死了没人知道”。我强烈建议你检查一下 prosody 的 systemd 服务状态和它的重启策略sudo systemctl edit prosody然后写入[Service] Restartalways RestartSec10这样 Prosody 因为偶发 bug 或 OOM 被干掉之后10 秒内会自己爬回来。配合 UptimeRobot、云监控等工具做 HTTP 探测基本能保证 99% 以上的可用性。6.4 附赠一条升级 Prosody 前一定要做配置备份Jitsi 的 apt 源更新频率不低Prosody 偶尔会发布新版。我吃过一次大亏执行完apt upgrade后老配置里的一些模块名直接变了比如某个模块被改名或合并结果 Prosody 起不来。好在当时对prosody.cfg.lua做了备份花了几分钟改一下模块名就恢复了。所以这里不得不提醒一句任何生产环境的升级先备份/etc/prosody/整个目录再升级真出问题能哭着笑出来。6.5 监控日志与会议质量的联动方法如果你有 Grafana PrometheusJitsi 官方提供了一个jitsi-prometheus-exporter可以抓取 Jicofo 和其他组件的指标。但对 Prosody 本身的监控比较简单实用的方案是写一个 cron 脚本每 5 分钟检查一下进程是否活着、端口是否在监听、日志文件是否有新的 error#!/bin/bash if ! systemctl is-active --quiet prosody; then echo $(date) prosody down /var/log/prosody-monitor.log systemctl restart prosody fi报警可以做得很轻但有了它我至少不会再因为 Prosody 半夜挂掉而第二天一早被会议发起人连环夺命 call 了。写在最后Jitsi Meet 能火起来很大程度是因为它把复杂到了极点的 WebRTC 视频会议系统做成了普通运维也能部署的形态。但这并不意味着你可以完全忽略背后的每个组件。Prosody 作为信令层的中枢是连接浏览器、Jicofo、JVB 和用户的粘合剂也是最容易被忽视的故障源头之一。希望能通过我这篇文章帮你在遇到会议连接异常时少走一点弯路先想到“破扫敌”这哥们儿。根据我自己的经验搞定 ProsodyJitsi Meet 的运维底气起码能多一半。
返回列表