RTVS车载视频平台阿里云ECS部署:分步骤联调与问题排查实践
做车联网的人应该都清楚JT/T 1078这个标准在行业里的分量。它规定了车载终端如何上报主动安全报警、如何把实时视频流推到平台端而基于这套协议落地实现的RTVS就是很多项目团队在用的开源视频监控平台方案。但协议跑通和真正部署到公网服务器是两码事公网IP、安全组规则、带宽、存储、终端NAT穿透任何一个环节没考虑到画面就是黑屏、卡顿、掉线轮着来。这次我把RTVS部署到了阿里云的一台ECS上全程用的分步骤模式——不是一条命令把所有东西装完再祈祷它能跑而是把环境准备、数据库初始化、信令接入、媒体转发、前端展示拆成独立阶段每完成一步就先验证一步。这套流程跑下来问题定位速度明显提升。这篇文章会从服务器选购开始一直写到模拟终端和真机联调再附上我踩过的坑。如果你正准备把手里的JT1078平台搬到公网试跑可以参考这条路径走一遍。1. 项目背景与部署策略1.1 RTVS和JT1078到底在解决什么事先梳理一下这个平台在整体链路里的位置。JT/T 1078标准定义了车载视频终端与服务平台之间的音视频数据交互方式包括实时视频请求、录像回放、报警信息上传等。一般车载终端还会同时运行JT808协议用来上报定位、心跳、主动安全报警ADAS前向碰撞、车距过近DSM疲劳驾驶、打电话、分神等。两者配合在一起才能构成一套完整的“两客一危”或营运车辆视频监管系统。RTVS就是这个标准下的一个落地实现。它通常包含几个核心模块信令接入网关负责处理终端的注册、鉴权和心跳流媒体网关负责接收终端推上来的视频流并转发给Web端播放器还有管理后台提供车辆管理、设备管理、报警记录、录像回放这些业务功能。很多团队拿它做二次开发对接自己的业务系统。所以RTVS解决的不是“能看视频”这一个表面需求而是“如何把分散在全国各地、跑在4G/5G网络下的几千台车载终端安全稳定地接入一个统一平台并实时展示视频和报警”这个整体问题。视频只是结果链路稳定才是核心。1.2 为什么要把平台部署到阿里云本地开发环境跑通一套RTVS其实不难难的是让终端真的能连上来。车载终端装的是普通物联网卡或者电话卡它只能访问公网地址。如果平台部署在公司内网就需要做端口映射、动态域名这些操作终端侧一换网络环境就容易出问题。阿里云这类公网云服务器解决的是基础网络可达性问题ECS有固定的公网IP安全组规则可以精细化控制放行端口带宽支持随时调整后续要挂对象存储或者扩容也比较方便。对我个人来说最直观的好处是安全组可视化哪些端口开了、对哪些IP开放一眼就能看明白排查问题比登录防火墙敲命令快得多。另外云服务器还能快速重装系统。部署测试阶段很容易把环境弄乱CentOS/Ubuntu镜像重装只要几分钟重新走一遍流程就好这种“试错成本低”的优势对技术验证项目来说很重要。1.3 “分步骤模式”的部署思路拆解所谓分步骤模式本质是把一个大型部署任务切成多个可独立验证的小阶段。我划成六步阶段主要工作验证方式环境准备安装JDK、MySQL、Redis、Nginx、FFmpeg命令检查版本号和运行状态数据层初始化创建数据库、导入初始化SQL、创建账号命令行查询表结构和数据信令接入层启动后端服务验证JT808/1078端口监听curl本地健康检查接口、看日志流媒体转发层配置媒体监听端口、验证推流收流本地工具拉流测试Web展示层编译前端、配置Nginx反向代理浏览器访问登录页终端联调模拟终端或真实设备接入验证全链路实时视频、录像回放、报警弹窗这么拆最直接的好处是问题域隔离。比如终端连不上如果信令层已经验证过端口正常那问题就缩小到终端配置或者安全组不需要从头到尾查一遍。我用这个方法部署基本上每个阶段的验证时间都在五分钟以内出问题时也能快速定位到具体环节。2. 部署前的环境规划与准备2.1 服务器配置与带宽、存储估算在买ECS之前先按自己的并发规模算一笔账。我这次测试场景是模拟20辆车并发每辆车两路视频。按照常见参数来估算主码流1080P按2Mbps算子码流按512Kbps算一路车就是约2.5Mbps。如果20辆车同时都在看主码流并发上行带宽就是20乘以2.5约50Mbps。实际测试中不可能20辆同时看但带宽规划必须按最坏情况算。所以我配了固定带宽50Mbps的ECS测试阶段够用。如果之后要上真实业务建议直接改按使用流量计费配合监控报警避免超出预算。存储方面录像文件是最占空间的。按平均码率1Mbps、每辆车每天跑8小时来算一路车一天产生的录像大约是3.6G折算下来约450MB每小时。20辆车两路视频一天就是18GB左右保留7天的话大约126GB。我直接在数据盘上挂了200GB系统盘和数据盘分开后面单独挂载到/data目录。CPU和内存方面4核8G的配置能覆盖20到50辆级别的接入测试。流媒体转封装、WebSocket推送这些操作会消耗CPU如果以后要跑100辆车以上建议8核16G起步数据库和流媒体服务可以拆到不同机器上。2.2 端口规划和阿里云安全组放行端口规划是部署测试里最容易被忽略、报错率最高的一环。我这里用了一组示例端口不同版本的RTVS可能默认端口不一样但规划逻辑是通用的用途示例端口说明HTTP/HTTPS前端80/443Nginx对外服务后端API8080建议通过Nginx反向代理暴露JT808信令接入808TCP长连接终端注册和心跳JT1078视频媒体1078TCP/UDP推流按实际配置WebSocket推送8888报警和状态实时推送阿里云安全组配置时有个基本思路出方向默认全部放行入方向按最小权限原则只放必要端口。80和443必须对公网开放8080这个后端API端口我建议只对管理端开放或者临时调试用日常通过Nginx反向代理访问即可不要让应用端口直接裸奔在公网上。8008和1078这两个口要做好对应终端IP的管控如果条件允许优先配置固定IP白名单。重点提醒一下媒体服务如果是用UDP推流端口必须放行连续区间。TCP端口只放行某个单独端口没问题UDP如果只开单端口终端推流时随机端口被安全组拦截就会出现“设备在线但画面出不来”的诡异情况。注意如果ECS要绑定域名并通过80/443访问记得提前确认ICP备案要求。未备案域名直接解析到国内服务器访问会被阻断。2.3 基础环境安装JDK、MySQL、Redis、Nginx、FFmpegRTVS后端通常是Java技术栈前端是Vue或者React所以基础环境至少要包含这几样JDK 8或11、MySQL 5.7以上、Redis、Nginx、FFmpeg。操作系统我用的CentOS 7.9用系统包管理器安装即可yum -y install java-1.8.0-openjdk-devel yum -y install mysql-server yum -y install redis yum -y install nginx yum -y install epel-release yum -y install ffmpeg安装完之后逐个确认版本避免后面排查问题时分不清是环境问题还是代码问题java -version mysql --version redis-server --version nginx -v ffmpeg -version这里有几个容易踩的坑。MySQL 8.0默认的认证插件是caching_sha2_password老版本的JDBC驱动连不上报错会让人误以为是数据库配置写错了其实只要把驱动升级到8.x或者创建用户时指定mysql_native_password就能解决。Redis安装好之后默认是没密码的生产环境一定要设置密码并且修改配置只监听内网地址或者绑定127.0.0.1别让Redis端口暴露在公网。FFmpeg主要用于视频转码、截图、录像拼接这些场景。有些精简版的RTVS可能不带转码功能直接用H.264编码推流就没问题如果后续要支持H.265转H.264播放FFmpeg版本不能太老建议用官方静态编译的二进制替换系统版本。3. 分步骤部署实操从数据库到前端再到终端联调3.1 第一步数据层初始化与本地验证部署开始前先把源码放到服务器上我习惯放在/data/rtv目录下数据盘挂载点也是这个方便后面录像文件统一管理。RTVS项目一般会带SQL初始化脚本通常在docs或sql目录下。先建数据库和专用账号不建议用root账号跑业务权限太大会给后面埋安全隐患CREATE DATABASE rtvs DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER rtv% IDENTIFIED BY Rtv123456; GRANT ALL PRIVILEGES ON rtvs.* TO rtv%; FLUSH PRIVILEGES;然后导入初始化脚本mysql -urtv -pRtv123456 rtvs /data/rtv/doc/rtvs.sql mysql -urtv -pRtv123456 -e show tables; rtvs看到表结构成功列出就说明数据层通了。这一步非常关键很多人喜欢直接改完配置再启动一旦启动失败分不清是SQL脚本没导入、账号密码错误还是配置格式有问题。先验证数据层后面的问题面就窄了很多。导入如果报错优先检查字符集。UTF8MB4的库导入UTF8的脚本一般没问题反过来就很容易出中文乱码或者表名报错。脚本里的建表语句如果带了DEFINER当前账号可能没有对应权限需要手动处理或者使用root导入后再回收权限。3.2 第二步后端信令服务启动与健康检查数据库OK之后修改后端配置文件。一般项目里会区分dev和prod环境配置我直接编辑生产环境的配置文件server: port: 8080 address: 0.0.0.0 spring: datasource: url: jdbc:mysql://localhost:3306/rtvs?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue username: rtv password: Rtv123456 redis: host: 127.0.0.1 port: 6379 rtv: media-port: 1078 video-dir: /data/rtv/video配置文件里的几个关键点单独说一下。第一个是server.address必须设置成0.0.0.0如果默认绑定127.0.0.1服务在本机怎么访问都正常公网就永远连不上第二个是JDBC连接串里的serverTimezone和useSSL不配会出现时区偏移和SSL握手报错第三个是Redis如果设置了密码这里也要同步修改。直接打包启动cd /data/rtv mvn clean package -DskipTests nohup java -jar rtv-server.jar --spring.profiles.activeprod /data/rtv/logs/run.log 21 tail -f /data/rtv/logs/run.log看到“TCP Server started on port 808”这类日志输出说明信令接入层起来了。再用curl验证一下健康检查接口curl http://127.0.0.1:8080/api/health返回正常JSON就算通过。如果curl都不通优先检查端口是不是被占用netstat -tlnp | grep -E 8080|808|1078注意如果Java进程启动后过几秒就退出八成是数据库或者Redis连接失败。日志里会直接打出异常堆栈先看日志再改配置不要反复重启试效率太低。3.3 第三步Web前端编译与Nginx反向代理配置前端部分一般是Node.js项目先安装依赖再编译cd /data/rtv/frontend npm install npm run build cp -r dist /var/www/rtv然后配置Nginx。我采用反向代理的方式而不是直接把8080端口暴露到公网。这样有几个好处避免跨域问题、能统一处理HTTPS证书、以后调整后端端口时前端配置不用动。server { listen 80; server_name _; root /var/www/rtv/dist; index index.html; location /api/ { proxy_pass http://127.0.0.1:8080/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /ws/ { proxy_pass http://127.0.0.1:8080/ws/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; } }报警推送和实时状态走WebSocketNginx代理WebSocket时一定要带上Upgrade和Connection这两个header否则前端页面能打开但报警和在线状态的实时推送上不来。浏览器访问http://公网IP/能看到登录页就说明这一层通了。3.4 第四步终端接入与流媒体链路联调平台层全部就绪之后进入终端侧联调。先在管理后台添加车辆和设备信息包括终端编号、车牌号、SIM卡号、设备型号等。车载终端那边需要配置服务器地址和端口这里的端口是JT808信令端口。终端上线后平台在线列表会显示状态变化。注册成功之后播放端发起视频请求平台通过JT808链路下发音视频实时传输指令终端收到指令后向指定的媒体端口推流Web播放器收到流转起来画面就出来了。这一步我遇到最多的问题是“终端显示在线但请求视频没反应”。排查的时候先确认媒体服务端口是不是监听在0.0.0.0上再从服务器端抓包看终端有没有往媒体端口推数据流tcpdump -i eth0 port 1078 -c 100如果抓包能看到大量数据包说明终端在推流问题出在播放链路如果一条包都抓不到要么是平台没有下发推流指令要么是安全组拦截了媒体端口。分步骤模式下这种问题的排查路径非常清晰不会陷入一团乱麻。4. 终端接入与全链路测试把场景都过一遍4.1 没有真机模拟终端先把链路跑通项目测试阶段最大的困难往往是手上没有真机。部标机的采购周期长有些团队的测试环境连一台符合JT1078协议的设备都没有。这种情况我建议先用模拟方式把链路粗验一遍。思路很简单用脚本模拟终端向JT808端口发起注册注册成功后向媒体端口推送一路视频流。视频源可以直接用FFmpeg推一个H.264编码的标准视频文件ffmpeg -re -i sample.mp4 -vcodec copy -an -f rtp rtp://公网IP:1078当然这种裸流推送并不能完全模拟JT1078标准封装但它的价值在于快速验证服务器的端口连通性、防火墙策略和后端收流能力。如果平台能收到流并转发出来说明媒体链路通了剩下真正符合协议标准的验证再交给真机或者专业模拟器去做。等真机到位后再按平台侧支持的协议细节跑一遍完整注册和推流就能确认开工前链路基础是可靠的。这种方式对我帮助很大至少不用干等设备。4.2 实时视频、录像回放、主动安全报警的验证方法链路通了之后功能验证要覆盖几个核心点实时视频每个通道能正常出画面主码流和子码流能切换画面没有明显撕裂或花屏。播放过程中切换页面再回来流能正常断开重建。录像回放按车辆和时间段检索录像能定位到对应片段并正常播放。重点检查跨时段的录像是否有切片丢失录像时间轴和实际录像时间是否一致。服务器上对应的录像文件也应该存在ls /data/rtv/video/车辆编号/日期/主动安全报警这是整个平台最核心的业务价值不能只看视频画面。测试时触发ADAS前向碰撞预警、DSM疲劳驾驶报警平台端要能实时收到报警并弹出提示报警详情里能看到对应的图片或短视频。我们测试时用模拟报警指令触发平台延迟在两秒内就算正常。这一步如果跳过去后面上线做安全管理的时候必然出问题。4.3 长时间稳定性与断线重连测试功能都过了最后压一道稳定性测试。我建议至少连续跑24小时观察三件事内存有没有持续增长、CPU有没有异常尖峰、网络连接数有没有一直涨不回收。free -m top -d 3 netstat -an | grep -E 808|1078 | wc -l连接数一直涨不降多半是死连接没有正常清理这种问题短时间测试看不出来跑一天就现原形。断线重连也是必测项。直接杀掉终端进程等几分钟再启动观察平台能否主动清理离线状态终端重新上线后能否快速恢复。真实场景里车辆过隧道、进地下车库都会造成断网如果重连逻辑有缺陷车辆出隧道后长时间显示离线那就成事故隐患了。5. 常见问题与排查技巧实录5.1 设备一直不上线先查链路再看日志这是遇到最多的问题。我的排查顺序是固定的先ping服务器公网IP确认网络通再telnet确认TCP端口通telnet 公网IP 808端口不通99%是安全组没放行或者终端配错了IP端口。端口能通就要抓包或者看平台日志。抓包可以定位终端发的数据包到底有没有到服务器tcpdump -i eth0 tcp port 808 -nn有抓到包但平台无响应就是协议层或者鉴权问题重点看终端编号、密码、车牌号是否和平台录入一致。注意有些RTVS版本会对终端IP做白名单校验如果平台里没把当前终端IP加进去即使注册包完全合法服务端也会直接丢弃。5.2 终端在线但视频画面一直缓冲这种情况一般不是信令问题而是媒体链路某个环节带宽不够或者端口不通。先确认安全组里媒体端口的UDP/TCP都已经放行再用播放端看实际拉流码率。在服务器上拉流验证是最直接的ffprobe rtmp://127.0.0.1:1935/live/终端编号如果本地拉流正常而公网播放卡顿基本就是公网带宽不够。带宽跑满的表现是画面从清晰慢慢变糊之后干脆卡住。遇到这个先看带宽监控再考虑限制并发观看路数或者升级带宽。还有种情况是播放器兼容性问题。终端推的如果是H.265编码而前端播放器只支持H.264就会出现画面一直黑或者只有声音。这种情况要么让终端兼容推H.264要么在服务端做转码。5.3 数据库连接报错的一类经典问题启动后端时看到通信链路异常先别急着改代码。列几个我实测过的场景通信链路失败用户名密码错、数据库账号不允许远程登录、网络不通。JDBC连接串里没有allowPublicKeyRetrievaltrueMySQL 8下会报公钥检索错误。时区相关报错连接串里补serverTimezoneAsia/Shanghai即可。数据库服务没起来MySQL启动后注意确认端口在监听状态systemctl status mysqld看一下。Redis连接失败也类似重点检查三点Redis进程是否启动、是否设置了密码但配置里没填、protected-mode有没有限制外部连接。测试阶段最简单的方法是让后端和应用部署在同一台机器上Redis监听127.0.0.1把外部因素降到最低。5.4 内网访问一切正常公网就是不通这个坑我踩过一次印象非常深。服务在本机curl没问题浏览器访问公网IP就是打不开。最后查到底是后端服务启动时绑定了内网IP或者127.0.0.1公网流量通过NAT映射进来之后找不到对应监听地址。阿里云ECS的公网IP其实是通过NAT映射到私网的服务只能监听0.0.0.0才能同时响应内网和公网请求。检查方法也很简单netstat -tlnp | grep java看到监听地址是0.0.0.0:8080就正常如果是127.0.0.1:8080或者具体内网IP改配置重新启动。5.5 速查表部署测试常见问题一览问题现象可能原因优先排查项设备不上线安全组未放行、IP端口配错、鉴权失败telnet端口、抓包、平台日志在线但无视频媒体端口未放行、平台未下发推流指令tcpdump媒体端口、播放日志视频卡顿花屏带宽不足、H.265编码不兼容ffprobe拉流、带宽监控后端启动闪退数据库/Redis连接失败、端口占用启动日志、netstat公网访问不通服务绑定内网IP、安全组未放行netstat监听地址、安全组规则报警不推送WebSocket代理配置缺失Nginx Upgrade配置6. 上线之后的运维细节与个人建议部署测试跑完平台能正常出画面了并不意味着工作结束了。真实业务上线后还有几个运维细节需要盯住。第一是磁盘空间。录像文件增长很快测试阶段你感觉不到一旦接入几十台车数据盘可能一周就满。建议写一个定时脚本清理超过N天的录像同时监控磁盘使用率到80%就报警。我一般把录像目录单独挂载数据盘并配置logrotate处理日志文件。第二是多做配置备份。数据库里面车辆信息、设备信息、报警记录都是核心资产每天定时用mysqldump备份到其他目录或者OSS防止误操作把表结构改崩了。我就是有一次测试报警规则的时候把配置表改乱了好在有备份几分钟就恢复了。第三是安全组规则要定期复核。调试阶段为了快速解决问题可能会临时放行一些端口功能验证完之后要记得关掉。RTVS后端API端口尽量别直接暴露在公网用Nginx反代加上访问控制能挡掉很多扫描攻击。第四是关注带宽成本。固定带宽的ECS如果峰值跑满平台会直接限速所有车辆的视频都会卡。建议开阿里云的带宽监控和费用预警心里时刻有个数。最后分享个小经验做这种部署测试时把每一步操作都记下来包括改了哪些配置、重启了哪个服务、命令输出是什么。因为人真的会忘而且过了几天你再回来看这份记录比任何文档都管用。我这次部署RTVS用时不到一天但这份操作记录到现在还在用后面每次搭新环境都直接抄自己上次的步骤效率高了很多。