首页 / 资讯中心 / 文章详情

OWT框架全解析:架构、部署与实战经验

OWT框架全解析:架构、部署与实战经验 ★ FEATURED ARTICLE
搞实时音视频的人应该都听过OWT这个名字。我第一次接触OWT的时候手里正好缺一个能扛住多人视频会议的服务端当时市面上要么是封装太重的商业方案要么是自己用WebRTC原生协议拼出来的玩具既能跑起来又敢拿来生产的还真不多。OWT的出现把媒体服务器、信令控制、RESTful API和客户端SDK一次性打包好了省掉了大量从零造轮子的时间。这篇文章是OWT概览的第一篇主要讲清楚OWT是什么、它的整体结构、部署起来要经历哪些步骤、以及我在实际使用中踩过的坑。对准备用WebRTC做互动直播、视频会议、在线教育的团队来说这篇算是入门前的第一块垫脚石。1. 项目整体设计与核心思路1.1 OWT到底解决什么痛点做WebRTC开发的人都知道浏览器之间的P2P连接只适合小规模场景一旦人数超过四五个全网状的连接数会爆炸带宽和CPU都扛不住。而且P2P连接里每个终端的网络环境都不一样有人上行带宽小有人NAT特别严苛信号一差整个会议就卡成幻灯片。OWT做的事情就是把这些麻烦集中到一个服务端里解决。简单说OWT是一套完整的实时音视频服务端框架。它不像某些方案只给你一个媒体转发层而是把媒体处理、房间管理、信令交换、REST API、录制、流媒体分发、客户端SDK都串在一起。你在自己的服务器上部署好OWT之后客户端只需要通过SDK接入就能实现多人开会、直播流转发、屏幕共享、录制回放这些功能而不需要自己实现复杂的WebRTC信令交互和媒体协商逻辑。我最早被OWT吸引是因为它解决了两个很现实的痛点一是SFU选择转发单元的转发模型服务端只转发流而不做转码CPU压力小延迟也低二是它自带了一套统一的RESTful接口创建房间、申请加入、订阅媒体流都可以通过HTTP协议完成对接现有业务后台特别方便。以前用原生WebRTC写服务端光信令这一块就要定义一堆消息格式还得自己处理SDP的解析和ICE候选的交换OWT把这些全部标准化了。1.2 整体架构一句话说清用最精简的话描述OWT的架构一个中央信令和房间管理服务搭配一个媒体服务集群对外暴露REST API和WebSocket信令接口客户端通过SDK和这两个接口通信。其中信令和房间管理负责维护会议状态比如谁在房间里、谁发布了流、谁订阅了哪条流。媒体服务负责接收终端的音视频流并根据订阅关系进行转发或者按需转码、混流。客户端SDK则封装了WebRTC的细节让上层业务不用关心SDP和ICE只要调用join、publish、subscribe这些方法就行。这个架构的好处在于控制面和媒体面分离。控制面可以横向扩展媒体面也可以单独扩容。运营方可以只接入几台控制服务器后面挂一组媒体服务器哪个忙就多塞几台。对比Monolithic的单体应用OWT的这种分离开放思路更适合做生产环境。此外OWT不仅支持WebRTC协议还支持RTMP等流媒体协议接入。这意味着你可以把摄像头的RTMP流拉进来再通过WebRTC分发给浏览器端用户。这个能力在互动直播场景里非常实用相当于把传统直播和实时互动融合在了一起。2. 核心模块拆解2.1 媒体服务模块媒体服务是OWT最核心的部分。它使用SFU架构也就是说当三个参会者A、B、C在房间里A把自己的音视频流推到服务端服务端不会把A的流解码再重新编码而是直接把A的流复制后转发给B和C。这种转发的模式最大优点就是开销小服务端不参与复杂的编解码延迟也低。SFU模式下每个终端的上行带宽和下行带宽是不对称的。A上行只需要推一路流B和C下行各需要拉A的流如果同时有多人在讲B和C的下行带宽就会叠加。所以多人会议里面服务端通常会做码率控制和带宽估计把每路下行流的清晰度控制在合理范围。OWT在这方面内置了自适应能力可以根据网络状况动态调整编码码率后期部署时我们只需要在配置里开开关就行。除了纯转发OWT的媒体服务也支持转码和混流。转码主要用于兼容不同终端比如有的浏览器不支持VP9而发送端偏偏用了VP9服务端可以把它转成H.264再转发给不支持的一方。混流则是把多路视频拼成一个画面常用于录制存档或向RTMP客户端分发成单路直播流。这两个功能默认情况下不开因为转码和混流都消耗CPU生产环境通常只在需要时才点亮。2.2 信令与控制面OWT的信令服务解决的是WebRTC最繁琐的协商过程。客户端加入房间时需要先通过信令通道向服务端发起请求服务端校验房间、鉴权、分配发布/订阅权限然后把媒体服务端的地址和端口返回给客户端。之后客户端再按照正常的WebRTC流程完成SDP交换和ICE连接。这块做得好的是它把信令逻辑抽象成了一套简单的请求-响应模型join、publish、subscribe、leave。实际项目中我们只需要在业务后台调用REST API创建房间然后把房间号和token发给客户端客户端SDK拿着这些信息就能完成整个入会流程。信令服务器和媒体服务器之间的连接、媒体端口的分配全被内部管理起来外部业务系统不需要关心。这种设计对业务集成极其友好。比如在在线教育系统里老师端和学生端不直接访问OWT而是访问我们自己的业务后台。后台调用OWT的REST API创建房间、获取token再把token下发到客户端。客户端拿着token接入OWT。这层解耦让我们无论是做小程序端、Web端还是桌面端都只需要维护同一套后台逻辑。2.3 客户端SDK与接入方式OWT的客户端SDK覆盖了主流平台包括Web、Android、iOS以及桌面端。SDK的职责是隐藏WebRTC的细节对外暴露可读性很强的API。在Web端典型接入代码是这样的const conferenceClient new Owt.Conference.ConferenceClient(); conferenceClient.join(roomId, token) .then(room { const stream new Owt.Base.MediaStream({ video: true, audio: true }); return room.publish(stream); }) .then(publication { console.log(published, publication.id); });这套API设计得很直观几个方法就能完成入会、推流。Android和iOS的SDK也类似只是语言不同。SDK内部处理了断线重连、ICE重启、分辨率切换等底层逻辑省了很多事。有一点需要注意OWT的Web SDK依赖最基础的WebRTC能力浏览器必须支持getUserMedia和RTCPeerConnection。如果你们的业务里还有比较老的浏览器建议提前确认版本兼容性因为SDK不会自动降级到Flash之类的技术。3. 部署与快速体验3.1 环境准备与依赖检查OWT服务端对操作系统的选择比较保守官方测试主要基于Ubuntu系列如果你在用CentOS或者Debian也能跑但可能需要自己编译更多的依赖库。我个人建议用一台干净的Ubuntu 18.04或20.04服务器内存至少4GB磁盘40GB以上编译时CPU核数越多越好因为要编译大量C和JavaScript代码。依赖方面编译器、Python、Node.js、CMake、libnice、libsrtp、OpenSSL、GStreamer等都要准备。Ubuntu下可以用一条命令把基础依赖装上apt update apt install -y python3 python3-pip cmake build-essential \ ninja-build nodejs npm libsrtp2-dev libnice-dev \ libssl-dev libopus-dev libvpx-dev libgstreamer1.0-dev \ libgstreamer-plugins-base1.0-dev装完依赖后建议先检查一下Node和Python版本OWT不同版本对Node版本的要求不一样过新或过旧都可能编译不过。通常Node 12到14之间比较稳我踩过Node 16的坑编译时提示某些模块不兼容。如果你们用的是稳定版分支按照官方README里写的版本要求来准备就好。3.2 编译安装详细步骤OWT的编译过程不算复杂但从源码仓库拉取代码后需要执行它的构建脚本。构建脚本会自动下载额外的依赖包并编译所有组件。典型过程如下git clone owt-server源码地址 cd owt-server ./scripts/build.py --installbuild.py会检查依赖、生成配置文件、编译C模块、编译Node.js扩展整个过程需要十几分钟到半小时不等取决于服务器性能和网络。编译完成后检查一下目录结构。你会看到bin目录下有启动和停止脚本conf目录下放着所有重要配置dist目录是编译产物。如果编译过程中没有报错到这一步OWT的主要程序已经就绪了。如果你们需要单独编译客户端SDK比如Web SDK还需要单独拉取对应仓库执行类似的构建脚本。服务端和客户端SDK是分开发布的版本号需要匹配不然可能因为协议不兼容导致连不上这个我在后面“常见问题”里会再讲。3.3 启动与功能验证启动OWT服务端很简单./bin/start-all.sh执行完没有输出致命错误就可以通过健康检查接口来看服务状态。OWT提供了一些RESTful API比如获取服务器版本信息可以直接用curl验证curl http://localhost:3000/v1/rooms如果能返回一个空列表或者看起来正常的JSON至少说明管理服务起来了。之后还要检查日志目录确认媒体服务进程是否有报错。要完整验证系统是否可用最好的方式是跑一个官方或者社区提供的Web测试页面输入OWT服务器地址创建一个房间然后用两个浏览器标签页同时加入看看音视频能不能互通。这一步通过之后再接入你们自己的业务SDK。启动时有个小细节start-all.sh会同时拉起多个服务进程包括管理API、信令服务、媒体服务。如果某一个服务启动失败脚本不一定立即报错所以启动之后一定要看日志和进程数。我习惯用ps -ef | grep owt确认一下至少能看到四五个相关进程。4. 关键配置与参数说明4.1 配置文件清单OWT的配置主要集中在conf目录下最核心的是owt.js所有服务端的参数都在里面。打开这个文件你会看到模块化的配置结构分为webrtc、signaling、capacity、proxy、mongo等大类。举个例子媒体端口范围通常在webrtc配置段里指定。因为WebRTC的媒体流一般走UDP需要预留一段连续的UDP端口。OWT默认会使用一个范围比如50000到50050这个范围可以自己定。无论怎么定防火墙一定要放行这些UDP端口否则客户端和服务端的媒体连接永远建不起来。MongoDB也是OWT的重要依赖。房间信息、token状态、录制任务等都需要存库。配置里需要指定MongoDB的连接地址和数据库名。如果你没装MongoDBOWT装完以后也是起不来的。还有客户端访问的HTTPS证书配置。WebRTC在除了localhost之外的所有场景下都强制要求安全上下文所以OWT的对外接口必须启用HTTPS证书文件路径和私钥路径都要在配置文件里设置好。4.2 常用参数调优我最常调整的参数有这几个首先是capacity里面的并发数限制。OWT允许你设置资源和软件层面的并发上限防止服务被突发流量打爆。比如设置单台媒体服务器最多支持100个并发发布超过之后新的发布请求会返回资源不足。生产环境建议按照实际带宽和CPU能力来填不要贪多。其次是带宽估计和码率相关参数。OWT在信令协商时会给发送端下发一个允许码率范围。如果会议室主要用于语音沟通可以把视频码率上限调低一些节省带宽。如果是高清直播场景可以把上限拉高。这个配置在webrtc段里字段名通常是video相关的maxBitrate。还有日志级别和日志输出。开发阶段建议把日志级别调到debug方便定位问题上线之后调到info甚至warn减少磁盘I/O。4.3 安全与鉴权OWT本身提供了一套token机制客户端加入房间需要携带有效token。token通常由业务后台调用REST API获取后台需要配置一个predefined keyOWT会用它生成和校验token。这个机制解决了“任何客户端都能随便进房间”的问题。但token也有过期时间时长要自己设定。会议时长比较长的场景建议用较长的过期时间避免会议中途token失效被踢出来。OWT对外提供的REST API默认没有很细的权限控制凡是能访问到管理接口的人理论上都可以创建房间和获取token。因此生产环境一定要通过防火墙或反向代理把管理接口限制在内网访问不要让REST API直接暴露到公网。我自己一般用Nginx在前面做一层反向代理只代理客户端的信令和媒体端口把REST API单独限制在内网网段。5. 常见问题与排查实录5.1 编译期错误与解决办法OWT编译时最常见的错误是“缺少某某依赖头文件”比如libsrtp没装好或者libnice版本不对。这类问题通常可以通过重新安装依赖来解决但要注意版本版本太高或太低都可能导致编译失败。还有一种我遇过很多次的情况编译到某个JavaScript依赖时卡死半天没有反应。这往往是因为服务器所在的网络访问不了npm的远程仓库或者被墙了。这种时候可以配置npm镜像源比如改成国内可用的镜像再重新执行构建脚本。编译成功但启动失败的情况常见原因是Node版本和OWT要求的版本不匹配。遇到这种情况不要纠结直接用项目要求的版本重装Node。经验之谈用源码编译Node比用包占地安装更可控。5.2 浏览器连不上媒体服务客户端已经连上信令服务也加入了房间但是摄像头画面显示不出来这类问题十有八九是媒体端口没打通。首先检查浏览器控制台看有没有收到ICE候选失败的日志。如果有多个服务器地址的候选都失败基本就是UDP端口被防火墙拦截。Linux环境下还需要检查是否开了防火墙比如ufw或iptables。如果用云服务器安全组规则也要放行。我之前就遇到过一次在本地测试没问题换到云服务器上媒体始终不通排查了半天才发现是安全组里只放行了TCP端口UDP端口没放。还有一种情况是HTTPS证书配置不正确。浏览器在非localhost环境下没有合法的HTTPS证书是不会给页面调用摄麦克风权限的更不会建立WebRTC连接。所以测试阶段建议先用自签名证书部署但正式环境一定换正式证书。5.3 延迟抖动与带宽问题排查多人会议里用户反馈画面卡顿、声音断续是最常见的运行期问题。先从服务端日志里看丢包率和往返时延。如果服务端收到的RTCP反馈显示丢包高那么问题大概率在用户到服务器的最后一公里和OWT本身关系不大。这时候建议先降低发送端的最大码率和分辨率看看能不能缓解。OWT支持动态调整不需要重启服务。如果降低之后依然卡就需要检查服务器出口带宽是否被打满。注意服务器带宽是按上行和下行走的别只看总带宽并发高的时候单台上行可能先被耗尽。如果是跨地区访问比如用户在全国各地访问一台部署在单一机房的服务器长距离传输的延迟和丢包是躲不开的。靠谱的做法是部署多个区域的节点让用户就近接入而不是死磕一台机器。5.4 常见问题速查表格这里可以写得特别干练方便以后翻查现象可能原因排查方向编译死锁 / 报错缺少依赖或版本不匹配检查依赖库版本设置npm镜像服务启动失败Mongo未启动或网络不通确认MongoDB地址和运行状态加入房间返回403token过期或secret不对检查predefined key和token有效期媒体连接不通UDP端口被防火墙拦截放行媒体端口段和安全组只有声音没有画面视频编解码器不受支持检查浏览器是否支持议定编码高并发卡顿带宽或CPU瓶颈降低码率、增加节点扩容客户端SDK连不上服务端版本和SDK版本不匹配统一版本到同一发布版本6. 性能调优与实战心得6.1 服务器硬件选型经验很多人问OWT到底需要什么样的服务器。我的经验是纯SFU转发场景下CPU压力主要来自信令处理和网络包收发性能瓶颈往往在网络带宽和内存而不是CPU核数。当然如果开启了转码那CPU消耗会直线上升此时主频和核数优先。建议单台媒体服务器至少配备4核CPU、8GB内存、千兆网卡。如果并发在100人以上建议10GB内网或者至少万兆对外的服务器。硬盘方面如果不做录制普通SSD就够如果要做会议录制建议单独挂载数据盘把录制目录指向数据盘避免拖累系统盘。6.2 编码与网络参数怎么配视频编码的选择直接影响带宽占用和兼容性。VP8兼容性最好H.264的硬件覆盖最好VP9压缩率高但老设备不支持。OWT支持多编码协商实际部署中我会这样设置优先让客户端使用H.264如果客户端不支持再回退到VP8。VP9一般只在点对点或网络极好的场景里开。网络参数的另一个重点是上行和下行的码率分配。假设一名用户观看三路高清流每路2 Mbps那这名用户的下行就是6 Mbps。会议室带宽是共享的如果出口带宽不够画面就会模糊和卡顿。因此我会根据出口带宽和最大在线人数反推码率上限比如总带宽1 Gbps最多同时在线200人人均可用就是5 Mbps广告KPI平均码率就控制在4 Mbps以内比较稳。6.3 多实例扩展思路当单机扛不住的时候OWT的架构天然支持横向扩展。控制面和媒体面可以分布在多台服务器上通过配置把媒体服务器节点组成一个集群由控制面根据负载情况把新会议分配到空闲节点上。实际扩展的时候我建议先把MongoDB和REST API单独部署不要让它们和数据面混在同一台机器。客户端通过一个统一的入口域名接入由负载均衡器转发到不同接入节点。媒体层面的UDP转发要特别小心如果负载均衡器只支持TCPUDP媒体流就不一定转得过去。理想方案是让四层负载均衡同时支持UDP和TCP或者在DNS层面做就近解析。我自己的经验是在部署多节点之前先做压测。我用过模拟客户端脚本模拟上百个连接给服务器跑30分钟观察CPU、内存、带宽和丢包指标再根据数据来定单机容量。不要凭感觉扩容实测数据才能帮你在后续出问题时有一个可靠的参照基线。最后再说一个实际操作中的小技巧每次修改完owt.js配置后不要直接重启整个集群。先单独重启对应的服务进程比如ps -ef | grep owt找到进程名字再逐个处理。这样你可以快速定位配置项到底影响的是哪一块也不会让所有在线会议瞬间断线。我是踩过好几次“改完配置全量重启结果整个会议全断”的坑才总结出来的。OWT这套系统只要摸透了它的配置思路和排查路径其实比很多人想象中要好上手。希望这篇概览能帮你少走一些弯路。
阅读完成 · 觉得有帮助?
咨询建站