macOS launchctl 本机部署模板
本目录用于把本机 32960/JT808/history 三个服务的启动方式仓库化。模板面向当前生产验证链路:
gb32960-ingest-app: TCP32960,HTTP20100jt808-ingest-app: TCP808,HTTP20482vehicle-history-app: HTTP20200
三个服务必须使用同一个 SINK_ARCHIVE_PATH。协议接入服务负责落原始 .bin 文件,Kafka raw envelope 只携带 archive://... 引用;history 服务按同一个 archive root 读取原始帧并提供查询。
vehicle-history-app 的生产高吞吐默认配置是 TDengine-only:
EVENT_FILE_STORE_ENABLED=false:避免 DuckDB/EventFileStore 进入实时消费热路径。TDENGINE_TELEMETRY_FIELDS_ENABLED=false:默认只写raw_frames和协议位置表,避免逐字段写放大。- GB32960 snapshot/fields 接口默认通过 TDengine
raw_frames索引找到rawUri,再回读共享 archive 中的原始.bin即时解析;后续解析器新增字段后可直接查询历史 raw。 - 如果需要兼容旧
/api/event-history/records低层记录接口或逐字段趋势宽表,可以显式打开对应开关;开启后要重新压测 Kafka lag 和 TDengine 写入吞吐。
生成 plist
在仓库根目录执行:
export PROJECT_ROOT="$(pwd)"
export JAVA_BIN="$(/usr/libexec/java_home 2>/dev/null)/bin/java"
export SHARED_ARCHIVE_PATH="$PROJECT_ROOT/data/archive-live"
export EVENT_STORE_PATH="$PROJECT_ROOT/data/event-store-live"
export TDENGINE_JDBC_URL='jdbc:TAOS-WS://<tdengine-host>:6041/vehicle_ts'
export TDENGINE_USERNAME='root'
export TDENGINE_PASSWORD='<tdengine-password>'
export VEHICLE_IDENTITY_MYSQL_JDBC_URL='jdbc:mysql://<mysql-host>:3306/vehicle_ingest'
export VEHICLE_IDENTITY_MYSQL_USERNAME='<mysql-user>'
export VEHICLE_IDENTITY_MYSQL_PASSWORD='<mysql-password>'
export VEHICLE_IDENTITY_MYSQL_REFRESH_INTERVAL='60s'
mkdir -p "$HOME/Library/LaunchAgents" "$PROJECT_ROOT/data"
mkdir -p /tmp/lingniu-gb32960-live /tmp/lingniu-jt808-live /tmp/lingniu-history-live
for service in gb32960 jt808 vehicle-history; do
sed \
-e "s#__PROJECT_ROOT__#$PROJECT_ROOT#g" \
-e "s#__JAVA_BIN__#$JAVA_BIN#g" \
-e "s#__SHARED_ARCHIVE_PATH__#$SHARED_ARCHIVE_PATH#g" \
-e "s#__EVENT_STORE_PATH__#$EVENT_STORE_PATH#g" \
-e "s#__TDENGINE_JDBC_URL__#$TDENGINE_JDBC_URL#g" \
-e "s#__TDENGINE_USERNAME__#$TDENGINE_USERNAME#g" \
-e "s#__TDENGINE_PASSWORD__#$TDENGINE_PASSWORD#g" \
-e "s#__VEHICLE_IDENTITY_MYSQL_JDBC_URL__#$VEHICLE_IDENTITY_MYSQL_JDBC_URL#g" \
-e "s#__VEHICLE_IDENTITY_MYSQL_USERNAME__#$VEHICLE_IDENTITY_MYSQL_USERNAME#g" \
-e "s#__VEHICLE_IDENTITY_MYSQL_PASSWORD__#$VEHICLE_IDENTITY_MYSQL_PASSWORD#g" \
-e "s#__VEHICLE_IDENTITY_MYSQL_REFRESH_INTERVAL__#$VEHICLE_IDENTITY_MYSQL_REFRESH_INTERVAL#g" \
"deploy/local/launchctl/com.lingniu.${service}.plist.template" \
> "$HOME/Library/LaunchAgents/com.lingniu.${service}.plist"
done
如果生产配置由 Nacos 下发,可以把模板里的 NACOS_CONFIG_ENABLED 改成 true,并补充 NACOS_SERVER_ADDR、NACOS_NAMESPACE、NACOS_GROUP、NACOS_USERNAME、NACOS_PASSWORD。端口、Kafka topic、archive root、TDengine 连接建议仍保留为启动环境变量,便于 Portainer、launchctl 和临时压测保持一致。
history 消费者会按协议和 raw/event 自动拆分 consumer group。设置 KAFKA_GROUP_HISTORY=vehicle-history-live 后,实际 group 为:
vehicle-history-live-gb32960-eventvehicle-history-live-gb32960-rawvehicle-history-live-jt808-eventvehicle-history-live-jt808-raw
JT808 身份绑定本地模板默认使用 file,可以在没有 MySQL 时持久化人工绑定,避免重启后退回 unknown。需要把 0x0100 注册信息维护到 MySQL 并支持真实 VIN 反写时,将 com.lingniu.jt808.plist.template 里的 VEHICLE_IDENTITY_STORE 改为 mysql,并提供 VEHICLE_IDENTITY_MYSQL_* 连接参数。服务会自动创建 vehicle_identity_binding 和 vehicle_identity_binding_registration 两张表:前者保存已确认 VIN 的外部标识绑定,后者保存 0x0100 注册字段;外部系统可把真实 VIN 反写到 registration 表,服务按刷新周期加载后,后续 raw/event 会带真实 VIN。memory 仅适合一次性联调,不建议用于生产验证。
启停
launchctl bootstrap "gui/$(id -u)" "$HOME/Library/LaunchAgents/com.lingniu.gb32960.plist"
launchctl bootstrap "gui/$(id -u)" "$HOME/Library/LaunchAgents/com.lingniu.jt808.plist"
launchctl bootstrap "gui/$(id -u)" "$HOME/Library/LaunchAgents/com.lingniu.vehicle-history.plist"
launchctl list | rg 'com.lingniu.(gb32960|jt808|vehicle-history)'
替换 jar 前先停止服务,避免 KeepAlive 在 jar 拷贝中途拉起半包:
launchctl bootout "gui/$(id -u)" "$HOME/Library/LaunchAgents/com.lingniu.gb32960.plist" || true
launchctl bootout "gui/$(id -u)" "$HOME/Library/LaunchAgents/com.lingniu.jt808.plist" || true
launchctl bootout "gui/$(id -u)" "$HOME/Library/LaunchAgents/com.lingniu.vehicle-history.plist" || true
验证地址
curl -sS http://127.0.0.1:20100/actuator/health
curl -sS http://127.0.0.1:20482/actuator/health
curl -sS http://127.0.0.1:20200/actuator/health
Swagger:
- GB32960 ingest:
http://127.0.0.1:20100/swagger-ui/index.html - JT808 ingest:
http://127.0.0.1:20482/swagger-ui/index.html - History query:
http://127.0.0.1:20200/swagger-ui/index.html