跳到主要内容
版本:4.0

Streaming服务的布署和维护

安装包和许可文件

流媒体服务交付时,将提供一个安装包文件和一个许可文件。

安装包文件为streaming-release-x.x.x.zip(其中x.x.x为版本号)压缩包文件。压缩包内包含以下文件:

文件名说明
config/application.yml配置文件1
config/config.json配置文件2
config/trusted-clients.json信任客户端表数据文件
config/log4j.xml程序日志配置文件
start.sh程序启动脚本文件
streaming.serviceStreaming服务的systemd服务单元文件
streaming-x.x.x.jar流媒体服务Jar包(其中x.x.x为版本号)

许可文件为streaming-cert.json,此文件另行交付。

程序的安装

本文假设:

  • 操作系统为Ubuntu Server 20.04,并已经完成一般性操作系统环境的准备
  • 域名为:wx.gratour.info,按下文配置时,应改为实际的域名
  • 操作系统用户名为:streaming,按下文配置时,应改为实际的用户名
  • Java使用JDK版本,安装在/opt/jdk-21

程序端口规划

Streaming服务需要在以下端口监听(均为TCP协议),部分只在本机内内部使用,部分需要开放内网访问,部分需要开放外网访问。 对于需要外网访问的端口,本文假设外网端口和内网端口一致。

端口号内网入站访问需求外网入站访问需求用途
1975Y终端JT/T 808协议接入端口
2000YY流媒体服务API接口端口(https)
2001YY媒体发布端口(FLV-HTTPS)
2002YY媒体发布端口(FLV-HTTP, 实时)
2003YY媒体发布端口(FLV-HTTP, 回放)
2004YY媒体发布端口(WSS)
2005YY新版WebsocketAPI端口
2006Y终端JT/T 1078 接收端口
2007Y终端JT/T 1078 接收端口
2008Y终端JT/T 1078 接收端口
2009Y终端ADAS附件接收端口
2010YFTP信令端口
2011-2030YFTP数据端口(passive模式),应设置20个端口号或以上,内外网端口号必须一致

目录规划

  • /opt/strm-fs目录:用于Streaming服务和Micro-GNSS服务存储服务端音视频转储文件、附件等文件
  • /opt/strm目录:用于安装Streaming服务
  • /opt/certs目录:用于存放域名的SSL证书文件,此目录应可为服务执行用户(本文假设为streaming)读取

创建这两个目录并将目录属主改为规划的运行用户(本文假设为streaming):

sudo mkdir /opt/strm
sudo chown streaming:streaming /opt/strm
sudo mkdir /opt/strm-fs
sudo chown streaming:streaming /opt/strm-fs

安装 ZooKeeper 服务程序

https://zookeeper.apache.org/ 网站下载安装文件并安装,设置好服务端口号(此端口仅内部使用).

安装 Streaming 服务程序

  1. 解压压缩包文件到/opt/streaming目录:
unzip streaming-release-x.x.x.zip -d /opt/strm
  1. 修改/opt/strm/start.sh文件中的JAVA_HOME变量的赋值(下图第一个黄色荧光部分) ,使之符合实际Java的安装路径(此处安装的是JDK版),并将最后一行的命令行的jar文件路径改为实际的文件路径( 下图第二个黄色荧光部分):
#!/bin/bash
export JAVA_HOME=/opt/jdk-21
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
java -Djava.net.preferIPv4Stack=true -Duser.timezone=Asia/Shanghai -jar /opt/strm/streaming-4.0.10.jar
  1. /opt/strm/start.sh添加可执行属性:
chmod +x start.sh
  1. 修改/opt/strm/streaming.service文件中的WorkingDirectory属性,使之符合Streaming服务实际的安装目录; 修改User属性为执行服务的用户的用户名;修改ExecStart属性中的黄色荧光部分,改为start.sh文件的实际路径:
[Unit]
Description=GT Streaming Service
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
WorkingDirectory=/opt/strm
Restart=always
RestartSec=5
User=streaming
ExecStart=/bin/bash /opt/strm/start.sh

[Install]
WantedBy=multi-user.target
  1. /opt/strm/streaming.service复制到/etc/systemd/system目录下,并激活(enable)服务(但先不要启动,因为后面还有一些配置要完成):
sudo cp /opt/strm/streaming.service /etc/systemd/system/
sudo systemctl enable streaming
  1. 将域名的SSL证书文件复制到某个streaming用户可读取的目录,这里假设为/opt/certs目录
  2. 修改/opt/strm/config/application.yml文件:
    • 修改server.port属性的值为流媒体服务API接口端口的端口号;HTTPS 协议。
    • 修改server.private-port属性的值为内部接口端口的端口号; 默认 HTTPS 协议,设置 server.ssl.private-port-plain-httptrue 可以调整为 HTTP 协议。
    • 修改server.ssl.certificate属性的值设为域名SSL证书文件(PEM格式)的文件路径;
    • 修改server.ssl.certificate-private-key属性的值设为域名SSL 私钥文件(PEM格式)的文件路径;
server:
port: 2000
private-port: 2001
ssl:
certificate: "/opt/certs/wx.gratour.info-certificate.pem"
certificate-private-key: "/opt/certs/wx.gratour.info-private-key.pem"
private-port-plain-http: true
enabled: true
  1. 将许可文件streaming-cert.json文件复制到/opt/strm/config目录下(不要修改此文件的内容)
  2. 根据下表说明,按实际情况和/或需要修改/opt/strm/config/config.json文件:

文件的初始内容大致如下:

{
"instIdPrefix": "strm",
"db": {
"jdbcUrl": "jdbc:postgresql://localhost:5432/strm",
"user": "strm",
"pwd": "strm",
"strmLogCleanupCron": "0 0 1 * * *",
"strmStatCron": "0 40 1 * * *"
},
"externalAddr": "wx.gratour.info",
"mq": {
"kafka": {
"servers": "192.168.80.106:9092,192.168.80.107:9092,192.168.80.108:9092",
"groupId": "strm"
},
"redis": {
"host": "192.168.80.106",
"port": 6379,
"database": 1
},
"adaptor": {
"script": "e-eye",
"logEnabled": true
},
"termCmd": {
"channel": "redis",
"destination": "gnss_cmd:gateway:send",
"useAdaptor": true
},
"cmdStateChanged": {
"channel": "kafka",
"destination": "inet-cmd-ack",
"useAdaptor": true
}
},
"zk": {
"connectString": "192.168.1.129:2181"
},
"endPoint": {
"ports": {
"livePort": 2006,
"replayPort": 2007,
"talkPort": 2008
}
},
"gnss": {
"jt808Host": "wx.gratour.info",
"jt808Ports": [
7510
],
"spiVersion": "1.0.0",
"features": {
"batchOnlineTermsQryDisabled": true,
"attrsQry": false,
"avAttrsQry": false,
"noQryLocationCmd": true,
"exposeJt808Addr": true
}
},
"publisher": {
"livePort": 2001,
"liveHttpPort": 2002,
"replayHttpPort": 2003,
"websocketPort": 2004,
"ws2Port": 2005,
"hls": {
"tmpDir": "/opt/strm-fs/hls"
}
},
"ftp": {
"port": 2010,
"passivePorts": "2011-2030",
"storePath": "/opt/strm-fs/ftp"
},

"avDump": {
"storePath": "/opt/strm-fs/strm",
"cleanup": {
"enabled": true,
"cron": "0 0 2 * * *",
"keepDays": 7
}
},
"adas": {
"cleanup": {
"enabled": true,
"cron": "0 0 0/2 * * ?",
"keepDays": 190
},
"port": 2009
},
"options": {}
}

文件中的各属性说明如下:

属性名数据类型修改说明
instIdPrefix字符串实例ID前缀;可分配任意要可见ASCII字符;如果整个系统中(即使不在同一台机器上)有多个Streaming服务实例,则应分配不同的ID前缀给每个实例
db.jdbcUrl字符串数据库的JDBC URL
db.user字符串数据库用户名
db.pwd字符串数据库密码
db.strmLogCleanupCron字符串执行流媒体日志记录自动清理的 Spring CRON 调度时间表达式,服务将依照此表达式定义的时间执行周期性的日志记录清理工作
db.codeStrmLogCleanupCron字符串执行流媒体码流日志记录自动清理的 Spring CRON 调度时间表达式,服务将依照此表达式定义的时间执行周期性的日志记录清理工作
db.strmStatCron字符串执行流媒体活动统计的 Spring CRON 调度时间表达式,服务将依照此表达式定义的时间执行周期性的隔日统计工作
externalAddr字符串外部地址,应填写服务器的域名
mq.kafka.servers字符串Kafka集群地址
mq.kafka.groupId字符串Kafka的Group ID
mq.redis.host字符串Redis主机地址
mq.redis.port整数Redis服务端口号
mq.redis.database整数Redis的数据库号
mq.adaptor.script字符串消息转换脚本的名称,消息转换脚本存放在 config/script 目录下,此属性设置文件名(不带扩展名,扩展名必须为.mjs),如设置为 e-eye,则脚本文件为 config/script/e-eye.mjs
mq.adaptor.logEnabled布尔值是否输出脚本中的日志输出信息到日志
mq.termCmd.channel字符串媒体服务下发指令使用的通道(消息队列),为 rabbit, kafka, redis 之一
mq.termCmd.destination字符串消息队列的topic或destination
mq.termCmd.useAdaptor布尔值是否调用消息转换脚本(见mq.adaptor.script)的特定方法将指令(TermCmd对象)转换成集成系统所需要的格式再发到消息队列
mq.cmdStateChange.channel字符串媒体服务接收指令状态变更使用的通道(消息队列),为 rabbit, kafka, redis 之一
mq.cmdStateChange.destination字符串消息队列的topic或destination
mq.cmdStateChange.useAdaptor布尔值是否调用消息转换脚本(见mq.adaptor.script)的特定方法将从消息队列接收到消息转换成 TermCmdStateChanged 信息对象
zk.connectString字符串ZooKeeper服务的地址
endPoint.ports.livePort整数JT/T 1078协议终端实时码流接收端口;此端口要求外网访问
endPoint.ports.replayPort整数JT/T 1078协议终端回放码流接收端口此端口要求外网访问
endPoint.ports.talkPort整数JT/T 1078协议终端对讲码流接收端口;此端口要求外网访问
publisher.livePort整数FLV-HTTPS实时播放端口;此端口要求外网访问,否则只能内网播放
publisher.liveHttpPort整数FLV-HTTP实时播放端口;此端口要求外网访问,否则只能内网播放
publisher.replayHttpPort整数FLV-HTTP回放播放端口;此端口要求外网访问,否则只能内网播放
publisher.websocketPort整数FLV-Websocket端口;此端口要求外网访问,否则只能内网播放
publisher.ws2Port整数新版WebSocket API服务端口
publisher.hls.tmpDir字符串音视频HLS转码的临时文件存储目录;可设置到/opt/strm-fshls子目录,或/tmp/hls,必须为服务执行用户可读写的目录;目录不存在时,服务将在启动时创建此目录
avDump.storePath字符串服务端音视频转储文件存储目录;一般为/opt/strm-fsstrm子目录,必须为服务执行用户可读写的目录;目录不存在时,服务将在启动时创建此目录
avDump.cleanup.enabled布尔值是否执行服务端音视频转储文件自动清理;一般应设为true
avDump.cleanup.cron字符串服务端音视频转储文件自动清理 Spring CRON 调度时间表达式请务必将自动清理工作安排在每天凌晨2点之后,在0点至2点之间执行统计可能导致统计不准确;服务将依照此表达式定义的时间执行周期性的音视频转储文件清理工作
avDump.cleanup.keepDays整数执行服务端音视频转储文件自动清理时,保留的最近转储文件的天数;转储时间在此天数内的文件不会被清理掉;应大于0。默认为32天
ftp.port整数FTP(用于接收终端远程录像上传)的信令端口
ftp.passivePorts字符串FTP数据端口(passive模式),应设置20个端口号或以上,内外网端口号必须一致。支持设置多个端口,可用逗号分隔单个端口或端口范围,端口范围用 - 号连起来
ftp.storePath字符串用于存储FTP接收到的文件的目录
adas.port整数主动安全附件服务接收文件的端口
adas.cleanup.enabled布尔值是否执行主动安全附件文件的自动清理;一般应设为true
adas.cleanup.cron字符串主动安全附件文件自动清理 Spring CRON 调度时间表达式;服务将依照此表达式定义的时间执行周期性的主动安全附件文件清理工作
adas.cleanup.keepDays整数执行主动安全附件文件自动清理时,保留的最近上传的主动安全附件文件的天数;上传时间在此天数内的文件不会被清理掉;应大于0。默认为190天
  1. /opt/strm/config/trusted-client.json文件中的clients[0].password 属性的值修改为一个随机密码(不要使用文件中已有密码),建议生成长度为12个或以上的字母数字字符组成的密码。Micro-Gateway 服务将使用此密码访问安全敏感的接口。
{
"clients": [
{
"username": "gnss-1",
"password": "Jc4xrpsIX2c2PGSm",
"privs": [
"config", "strm"
]
}
]
}
  1. 根据前述端口需求,设置好防火墙和端口映射

  2. 启动服务

sudo systemctl start streaming

日常维护

服务的启动、停止、重启

  1. 启动Streaming服务可执行:
sudo systemctl start streaming
  1. 停止Streaming服务可执行:
sudo systemctl stop streaming
  1. 重启Streaming服务可执行:
sudo systemctl restart streaming

SSL证书更换

将PEM的格式证书(nginx格式)上传到配置的证书目录即可

日志文件

日志文件为服务安装目录(本文为opt/strm)下的log子目录下的strm.log文件。

Spring CRON 调度时间表达式

Spring CRON表达式类似于crontab表达式,但分为6个(crontab为5个,少了秒字段)以空格分隔的时间日期字段:

cron-expr.png

主要规则如下

  • 字段可以设为星号(*),表示从第一个到最后一个。对于周几字段,可以用问号(?),表示的意义和星号(*)一样。
  • 范围可以用连接号(-)连接两个数字表示;它表示的范围是包含的,即包含开始的数字,也包含结尾的数字;如:3-7,表示[3,4,5,6,7],范围包含开始数字3,也包含结尾数字7
  • 在一个字段中,单个数字或一个范围或星号(*)后跟/n(其中n为具体数字),可表示在触发后,在范围内再多次触发,间隔由n值指出。
  • 字段中可以使用一个L字符,表示月的最后一天。如果L后面跟随一个负的偏量,即L-n(其中n为具体数字),表示月的倒数n天。如果L后面跟随W字母,即LW,则表示月的最后一个工作日。
  • 周几字段中可以使用一个L字符,表示周的最后一天。如果在L前面加一个数字,表示月的最后一个周几。
  • 字段可以是nW(其中n为具体数字),表示与n号最接近的工作日;如果当月n号刚好为工作日,则计算为n号;如果n不为1,n号那天为周六,则计算为n号的前一天(周五);如果n为1,1号那天为周六,则计算为1号的下周一;如果n号那天为周日,则为n号的后一天(周一)。
  • 周几字段可以指定为d#n(其中d, n为具体数字),表示月的第n个周d。

同时也支持以下宏:

  • @yearly (或 @annually),表示每年1月1日零时
  • @monthly,表示每月1日零时
  • @weekly,表示每个周日的零时
  • @daily (或 @midnight),表示每天的零时
  • @hourly,表示每个小时的0分0秒

表达式示例

表达式说明
0 0 * * * *每小时的0分0秒
*/10 * * * * *每隔10秒
0 0 8-10 * * *每天8点,9点,10点三个时刻
0 0 6,19 * * *每天的6点和19点二个时刻
0 0/30 8-10 * * *每天的8:00, 8:30, 9:00, 9:30, 10:00和10:30
0 0 9-17 * * 1-5工作日的9点至17点的九个整点时刻
0 0 0 25 12 ?每年12月25日零时
0 0 0 L * *每个月的月末那天零时
0 0 0 L-3 * *每个月的倒数第三天的零时
0 0 0 1W * *每个月的第一个工作日的零时
0 0 0 LW * *每个月的最后一个工作日的零时
0 0 0 * * 5L每月最后一个周五的零时
0 0 0 ? * 5#2每月第二个周五的零时