chore: add go gateway deployment stack
This commit is contained in:
101
deploy/portainer/docker-compose-go.yml
Normal file
101
deploy/portainer/docker-compose-go.yml
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
# Go sidecar stack for the vehicle ingest redesign.
|
||||||
|
# It is intentionally separate from deploy/portainer/docker-compose.yml so the
|
||||||
|
# current Java production stack can keep running until Go evidence is captured.
|
||||||
|
|
||||||
|
x-common-env: &common-env
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
KAFKA_BROKERS: ${KAFKA_BROKERS:-172.17.111.56:9092}
|
||||||
|
KAFKA_TOPIC_GB32960_RAW: ${KAFKA_TOPIC_GB32960_RAW:-vehicle.raw.gb32960.v1}
|
||||||
|
KAFKA_TOPIC_JT808_RAW: ${KAFKA_TOPIC_JT808_RAW:-vehicle.raw.jt808.v1}
|
||||||
|
KAFKA_TOPIC_YUTONG_MQTT_RAW: ${KAFKA_TOPIC_YUTONG_MQTT_RAW:-vehicle.raw.yutong-mqtt.v1}
|
||||||
|
KAFKA_TOPIC_UNIFIED: ${KAFKA_TOPIC_UNIFIED:-vehicle.event.unified.v1}
|
||||||
|
|
||||||
|
x-restart: &restart-policy
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- vehicle-ingest
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: "100m"
|
||||||
|
max-file: "5"
|
||||||
|
|
||||||
|
services:
|
||||||
|
go-vehicle-gateway:
|
||||||
|
<<: *restart-policy
|
||||||
|
image: ${LINGNIU_GO_IMAGE_REGISTRY:-crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com}/${LINGNIU_GO_IMAGE_NAMESPACE:-oneos}/vehicle-gateway-go:${LINGNIU_GO_IMAGE_VERSION:?set LINGNIU_GO_IMAGE_VERSION}
|
||||||
|
container_name: go-vehicle-gateway
|
||||||
|
command: ["/app/gateway"]
|
||||||
|
mem_limit: ${GO_GATEWAY_MEM_LIMIT:-512m}
|
||||||
|
environment:
|
||||||
|
<<: *common-env
|
||||||
|
GB32960_TCP_ADDR: ":32960"
|
||||||
|
JT808_TCP_ADDR: ":808"
|
||||||
|
TCP_READ_BUFFER_BYTES: ${TCP_READ_BUFFER_BYTES:-65536}
|
||||||
|
TCP_IDLE_TIMEOUT_SECONDS: ${TCP_IDLE_TIMEOUT_SECONDS:-180}
|
||||||
|
TCP_MAX_CONNECTIONS: ${TCP_MAX_CONNECTIONS:-20000}
|
||||||
|
YUTONG_MQTT_ENABLED: ${YUTONG_MQTT_ENABLED:-false}
|
||||||
|
YUTONG_MQTT_ENDPOINT: ${YUTONG_MQTT_ENDPOINT:-yutong}
|
||||||
|
YUTONG_MQTT_URI: ${YUTONG_MQTT_URI:-}
|
||||||
|
YUTONG_MQTT_TOPICS: ${YUTONG_MQTT_TOPICS:-/ytforward/shln/+}
|
||||||
|
YUTONG_MQTT_QOS: ${YUTONG_MQTT_QOS:-2}
|
||||||
|
YUTONG_MQTT_CLIENT_ID: ${YUTONG_MQTT_CLIENT_ID:-lingniu-go-yutong-mqtt}
|
||||||
|
YUTONG_MQTT_USERNAME: ${YUTONG_MQTT_USERNAME:-}
|
||||||
|
YUTONG_MQTT_PASSWORD: ${YUTONG_MQTT_PASSWORD:-}
|
||||||
|
ports:
|
||||||
|
- "${GO_GB32960_TCP_PORT:-32960}:32960"
|
||||||
|
- "${GO_JT808_TCP_PORT:-808}:808"
|
||||||
|
|
||||||
|
go-history-writer:
|
||||||
|
<<: *restart-policy
|
||||||
|
image: ${LINGNIU_GO_IMAGE_REGISTRY:-crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com}/${LINGNIU_GO_IMAGE_NAMESPACE:-oneos}/vehicle-gateway-go:${LINGNIU_GO_IMAGE_VERSION:?set LINGNIU_GO_IMAGE_VERSION}
|
||||||
|
container_name: go-history-writer
|
||||||
|
command: ["/app/history-writer"]
|
||||||
|
mem_limit: ${GO_HISTORY_WRITER_MEM_LIMIT:-768m}
|
||||||
|
environment:
|
||||||
|
<<: *common-env
|
||||||
|
KAFKA_GROUP: ${KAFKA_GROUP_GO_HISTORY:-go-history-writer}
|
||||||
|
KAFKA_TOPICS: ${KAFKA_TOPICS_GO_HISTORY:-vehicle.raw.gb32960.v1,vehicle.raw.jt808.v1,vehicle.raw.yutong-mqtt.v1}
|
||||||
|
TDENGINE_DRIVER: ${TDENGINE_DRIVER:-taosWS}
|
||||||
|
TDENGINE_DSN: ${TDENGINE_DSN:?set TDENGINE_DSN, example root:password@ws(172.17.111.57:6041)/lingniu_vehicle_ts}
|
||||||
|
TDENGINE_DATABASE: ${TDENGINE_DATABASE:-lingniu_vehicle_ts}
|
||||||
|
TDENGINE_ENSURE_SCHEMA: ${TDENGINE_ENSURE_SCHEMA:-true}
|
||||||
|
|
||||||
|
go-stat-writer:
|
||||||
|
<<: *restart-policy
|
||||||
|
image: ${LINGNIU_GO_IMAGE_REGISTRY:-crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com}/${LINGNIU_GO_IMAGE_NAMESPACE:-oneos}/vehicle-gateway-go:${LINGNIU_GO_IMAGE_VERSION:?set LINGNIU_GO_IMAGE_VERSION}
|
||||||
|
container_name: go-stat-writer
|
||||||
|
command: ["/app/stat-writer"]
|
||||||
|
mem_limit: ${GO_STAT_WRITER_MEM_LIMIT:-512m}
|
||||||
|
environment:
|
||||||
|
<<: *common-env
|
||||||
|
KAFKA_GROUP: ${KAFKA_GROUP_GO_STAT:-go-stat-writer}
|
||||||
|
KAFKA_TOPICS: ${KAFKA_TOPICS_GO_STAT:-vehicle.raw.gb32960.v1,vehicle.raw.jt808.v1}
|
||||||
|
MYSQL_DSN: ${MYSQL_DSN:?set MYSQL_DSN}
|
||||||
|
MYSQL_ENSURE_SCHEMA: ${MYSQL_ENSURE_SCHEMA:-true}
|
||||||
|
LOCAL_TZ: ${LOCAL_TZ:-Asia/Shanghai}
|
||||||
|
|
||||||
|
go-realtime-api:
|
||||||
|
<<: *restart-policy
|
||||||
|
image: ${LINGNIU_GO_IMAGE_REGISTRY:-crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com}/${LINGNIU_GO_IMAGE_NAMESPACE:-oneos}/vehicle-gateway-go:${LINGNIU_GO_IMAGE_VERSION:?set LINGNIU_GO_IMAGE_VERSION}
|
||||||
|
container_name: go-realtime-api
|
||||||
|
command: ["/app/realtime-api"]
|
||||||
|
mem_limit: ${GO_REALTIME_API_MEM_LIMIT:-512m}
|
||||||
|
environment:
|
||||||
|
<<: *common-env
|
||||||
|
HTTP_ADDR: ":20210"
|
||||||
|
KAFKA_GROUP: ${KAFKA_GROUP_GO_REALTIME:-go-realtime-api}
|
||||||
|
KAFKA_TOPICS: ${KAFKA_TOPICS_GO_REALTIME:-vehicle.event.unified.v1}
|
||||||
|
REDIS_ADDR: ${REDIS_ADDR:-r-bp1u741kij7e51i481.redis.rds.aliyuncs.com:6379}
|
||||||
|
REDIS_USERNAME: ${REDIS_USERNAME:-}
|
||||||
|
REDIS_PASSWORD: ${REDIS_PASSWORD:?set REDIS_PASSWORD}
|
||||||
|
REDIS_DB: ${REDIS_DB:-50}
|
||||||
|
ONLINE_TTL_SECONDS: ${ONLINE_TTL_SECONDS:-600}
|
||||||
|
ports:
|
||||||
|
- "${GO_REALTIME_HTTP_PORT:-20210}:20210"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
vehicle-ingest:
|
||||||
|
name: vehicle-ingest
|
||||||
127
docs/operations/go-vehicle-gateway-verification.md
Normal file
127
docs/operations/go-vehicle-gateway-verification.md
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
# Go Vehicle Gateway 验证手册
|
||||||
|
|
||||||
|
本文档用于验证 Go 重构运行面:
|
||||||
|
|
||||||
|
- `go-vehicle-gateway`:GB32960 TCP、JT808 TCP、宇通 MQTT 接入。
|
||||||
|
- `go-history-writer`:Kafka RAW 写 TDengine。
|
||||||
|
- `go-stat-writer`:Kafka RAW 写 MySQL 每日指标。
|
||||||
|
- `go-realtime-api`:Kafka unified event 写 Redis,并提供实时查询 API。
|
||||||
|
|
||||||
|
## 本地构建验证
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd go/vehicle-gateway
|
||||||
|
go test ./...
|
||||||
|
go build ./cmd/gateway
|
||||||
|
go build ./cmd/history-writer
|
||||||
|
go build ./cmd/stat-writer
|
||||||
|
go build ./cmd/realtime-api
|
||||||
|
```
|
||||||
|
|
||||||
|
## 镜像构建
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd go/vehicle-gateway
|
||||||
|
docker build -t vehicle-gateway-go:local .
|
||||||
|
```
|
||||||
|
|
||||||
|
同一个镜像包含四个二进制:
|
||||||
|
|
||||||
|
- `/app/gateway`
|
||||||
|
- `/app/history-writer`
|
||||||
|
- `/app/stat-writer`
|
||||||
|
- `/app/realtime-api`
|
||||||
|
|
||||||
|
## Portainer 部署
|
||||||
|
|
||||||
|
Go 旁路 stack 文件:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
deploy/portainer/docker-compose-go.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
必填变量:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
LINGNIU_GO_IMAGE_VERSION=<image-version>
|
||||||
|
KAFKA_BROKERS=172.17.111.56:9092
|
||||||
|
TDENGINE_DSN=root:<password>@ws(172.17.111.57:6041)/lingniu_vehicle_ts
|
||||||
|
MYSQL_DSN=lingniu_vehicle:<password>@tcp(rm-bp179zbv481rnw3e2.mysql.rds.aliyuncs.com:3306)/lingniu_vehicle_data?parseTime=true&charset=utf8mb4,utf8&loc=Asia%2FShanghai
|
||||||
|
REDIS_ADDR=r-bp1u741kij7e51i481.redis.rds.aliyuncs.com:6379
|
||||||
|
REDIS_PASSWORD=<password>
|
||||||
|
REDIS_DB=50
|
||||||
|
```
|
||||||
|
|
||||||
|
宇通 MQTT 开启时再配置:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
YUTONG_MQTT_ENABLED=true
|
||||||
|
YUTONG_MQTT_URI=<mqtt-uri>
|
||||||
|
YUTONG_MQTT_TOPICS=/ytforward/shln/+
|
||||||
|
YUTONG_MQTT_CLIENT_ID=lingniu-go-yutong-mqtt
|
||||||
|
YUTONG_MQTT_USERNAME=<username>
|
||||||
|
YUTONG_MQTT_PASSWORD=<password>
|
||||||
|
```
|
||||||
|
|
||||||
|
## ECS 进程检查
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' \
|
||||||
|
| egrep 'go-vehicle-gateway|go-history-writer|go-stat-writer|go-realtime-api|NAMES'
|
||||||
|
|
||||||
|
ss -lntp | egrep ':(808|32960|20210)\b'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Kafka 验证
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kafka-console-consumer --bootstrap-server 172.17.111.56:9092 \
|
||||||
|
--topic vehicle.raw.jt808.v1 --max-messages 1 --timeout-ms 10000
|
||||||
|
|
||||||
|
kafka-console-consumer --bootstrap-server 172.17.111.56:9092 \
|
||||||
|
--topic vehicle.raw.gb32960.v1 --max-messages 1 --timeout-ms 10000
|
||||||
|
|
||||||
|
kafka-console-consumer --bootstrap-server 172.17.111.56:9092 \
|
||||||
|
--topic vehicle.event.unified.v1 --max-messages 1 --timeout-ms 10000
|
||||||
|
```
|
||||||
|
|
||||||
|
## TDengine 验证
|
||||||
|
|
||||||
|
```sql
|
||||||
|
USE lingniu_vehicle_ts;
|
||||||
|
SHOW STABLES;
|
||||||
|
SELECT COUNT(*) FROM raw_frames;
|
||||||
|
SELECT COUNT(*) FROM vehicle_locations;
|
||||||
|
SELECT COUNT(*) FROM vehicle_mileage_points;
|
||||||
|
```
|
||||||
|
|
||||||
|
## MySQL 验证
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT protocol, metric_key, COUNT(*)
|
||||||
|
FROM vehicle_daily_metric
|
||||||
|
GROUP BY protocol, metric_key;
|
||||||
|
|
||||||
|
SELECT *
|
||||||
|
FROM vehicle_daily_metric
|
||||||
|
WHERE metric_key IN ('daily_mileage_km', 'daily_total_mileage_km')
|
||||||
|
ORDER BY updated_at DESC
|
||||||
|
LIMIT 20;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Redis 实时查询
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -sS 'http://115.29.187.205:20210/api/realtime/vehicles/<vin>'
|
||||||
|
curl -sS 'http://115.29.187.205:20210/api/realtime/vehicles/<vin>/online'
|
||||||
|
curl -sS 'http://115.29.187.205:20210/api/realtime/vehicles/<vin>/protocols/JT808'
|
||||||
|
```
|
||||||
|
|
||||||
|
## 验收证据
|
||||||
|
|
||||||
|
正式切换前至少记录:
|
||||||
|
|
||||||
|
- 一个真实 GB32960 VIN 的 RAW、location、mileage point、Redis snapshot。
|
||||||
|
- 一个真实 JT808 VIN/phone 的 RAW、location、mileage point、daily metric、Redis snapshot。
|
||||||
|
- 一个真实宇通 MQTT VIN 或 device_id 的 RAW、Redis snapshot。
|
||||||
|
- `go-history-writer` 和 `go-stat-writer` 重启后 Kafka offset 能继续推进。
|
||||||
29
go/vehicle-gateway/Dockerfile
Normal file
29
go/vehicle-gateway/Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
FROM golang:1.26-bookworm AS build
|
||||||
|
|
||||||
|
WORKDIR /src
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o /out/gateway ./cmd/gateway \
|
||||||
|
&& CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o /out/history-writer ./cmd/history-writer \
|
||||||
|
&& CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o /out/stat-writer ./cmd/stat-writer \
|
||||||
|
&& CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o /out/realtime-api ./cmd/realtime-api
|
||||||
|
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends ca-certificates tzdata \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=build /out/gateway /app/gateway
|
||||||
|
COPY --from=build /out/history-writer /app/history-writer
|
||||||
|
COPY --from=build /out/stat-writer /app/stat-writer
|
||||||
|
COPY --from=build /out/realtime-api /app/realtime-api
|
||||||
|
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
|
||||||
|
EXPOSE 808 32960 20210
|
||||||
|
|
||||||
|
CMD ["/app/gateway"]
|
||||||
Reference in New Issue
Block a user