做车联网的人应该都清楚,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/443 | Nginx对外服务 |
| 后端API | 8080 | 建议通过Nginx反向代理暴露 |
| JT808信令接入 | 808 | TCP长连接,终端注册和心跳 |
| JT1078视频媒体 | 1078 | TCP/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、FFmpeg
RTVS后端通常是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 'Rtv@123456'; GRANT ALL PRIVILEGES ON rtvs.* TO 'rtv'@'%'; FLUSH PRIVILEGES;然后导入初始化脚本:
mysql -urtv -pRtv@123456 rtvs < /data/rtv/doc/rtvs.sql mysql -urtv -pRtv@123456 -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?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true username: rtv password: Rtv@123456 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.active=prod > /data/rtv/logs/run.log 2>&1 & 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"; } }报警推送和实时状态走WebSocket,Nginx代理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连接串里没有allowPublicKeyRetrieval=true,MySQL 8下会报公钥检索错误。
- 时区相关报错:连接串里补serverTimezone=Asia/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用时不到一天,但这份操作记录到现在还在用,后面每次搭新环境都直接抄自己上次的步骤,效率高了很多。