Files
lingniu-vehicle-ingest/docs/ops/100k-capacity-baseline.md

9.9 KiB
Raw Blame History

100K 车辆接入容量基线

更新时间2026-07-03

目标

支撑 100,000 台车辆接入,入口服务在高连接数和高帧率下保持可观测、可背压、可恢复。

初始容量假设

目标
连接车辆数 100,000
平均帧间隔 10-30 秒
平均入口 FPS 3,000-10,000
短时 burst FPS 20,000
Gateway p99 parse + enqueue < 50ms
Redis 当前态延迟 < 3s
TDengine 历史写入 lag 可观测且 burst 后下降
MySQL 当前态 异步,不能阻塞 Redis

当前生产观测

当前 ECS 115.29.187.205 在低负载下健康:

  • JT808 连接约 242。
  • GB32960 连接约 2。
  • Kafka lag 为 0。
  • NATS ack pending 为 0。
  • Redis 写入约 0ms。
  • MySQL 投影约 1-2ms。
  • ECS load 约 0.09 / 0.15 / 0.21
  • 可用内存约 6.6GB。
  • 根分区使用约 37%。

当前已知缺口

  • net.core.somaxconn=128,无法作为 100K 连接生产基线。
  • Gateway 默认 TCP_MAX_CONNECTIONS 已调整为 120000,生产仍可通过环境变量覆盖。
  • 已新增可重复的 TCP 连接压测工具,后续需要用它跑 10K/50K/100K 阶段测试并记录结果。
  • 仍缺读超时按协议维度计数Gateway frame duration 已提供 histogram可用于 parse + enqueue + response 的 p95/p99 估算。
  • TDengine history writer 和 NATS fast writer 已使用 batch 写入;后续需要用带帧率压测验证 batch size、flush latency 和存储端承载能力。
  • Kafka topic 当前 12 分区100K 目标下需要结合实际 FPS 再评估分区数。

ECS OS 参数建议

100K 连接目标需要至少以下系统参数作为起点:

sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.tcp_max_syn_backlog=65535
sysctl -w net.ipv4.ip_local_port_range="10000 65000"
sysctl -w net.ipv4.tcp_tw_reuse=1

systemd gateway 已配置 LimitNOFILE=1048576,需要持续保持。

验收指标

指标 目标
Gateway vehicle_gateway_active_connections 能稳定到阶段目标连接数
Gateway vehicle_gateway_connection_closes_total{reason} read_error/extract_error/max_connections 不异常增长
Gateway vehicle_gateway_connection_rejections_total 容量目标内不增长
Gateway async sink vehicle_async_sink_queue_depth{sink} 队列深度不持续增长
Gateway async sink vehicle_async_sink_enqueue_total{sink,kind,status} timeout/closed 不增长
Gateway async sink vehicle_async_sink_publish_total{sink,kind,status} error 不增长
Gateway async sink vehicle_async_sink_publish_duration_ms_histogram_bucket p99 不持续上升
Gateway vehicle_gateway_publish_total{status="ok"} 持续增长
Gateway vehicle_gateway_frame_duration_ms_histogram_bucket p99 小于容量目标
History writer vehicle_history_batch_flush_total{status} error 不增长
History writer vehicle_history_batch_rows_total{status} batch 行数持续增长
History writer vehicle_history_batch_pending_messages 稳态接近 0burst 后下降
History writer vehicle_history_batch_pending_rows 稳态接近 0burst 后下降
History writer vehicle_history_batch_flush_duration_ms{status} flush 延迟不持续上升
NATS bridge vehicle_bridge_nats_consumer_ack_pending 稳态为 0
NATS bridge vehicle_bridge_nats_consumer_pending burst 后下降
NATS bridge vehicle_bridge_batch_pending_messages 稳态接近 0burst 后下降
NATS bridge vehicle_bridge_batch_duration_ms_histogram_bucket p99 不持续上升
NATS fast writer vehicle_fast_writer_nats_consumer_ack_pending 稳态为 0
NATS fast writer vehicle_fast_writer_nats_consumer_pending burst 后下降
NATS fast writer vehicle_fast_writer_batch_pending_messages 稳态接近 0burst 后下降
NATS fast writer vehicle_fast_writer_batch_pending_envelopes 稳态接近 0burst 后下降
NATS fast writer vehicle_fast_writer_stage_duration_ms_histogram_bucket TDengine/Redis/ack 各阶段 p99 不持续上升
Kafka consumers vehicle_*_kafka_lag 稳态为 0burst 后下降
Realtime Redis vehicle_realtime_store_update_duration_ms_histogram_bucket{store="redis"} p99 毫秒级且不持续上升
Realtime MySQL vehicle_realtime_store_update_duration_ms_histogram_bucket{store="mysql"} p99 不持续上升
Realtime MySQL async queue depth 不持续增长
Stat writer vehicle_stat_write_duration_ms_histogram_bucket p99 不持续上升

Retention Guardrails

10W 车辆接入时,中间件只承担解耦和短期缓冲职责,不能成为长期历史库。

Component Guardrail
NATS JetStream VEHICLE_INGEST NATS_STREAM_MAX_BYTES=21474836480NATS_STREAM_MAX_AGE_HOURS=24NATS_STREAM_ENSURE_TIMEOUT_SECONDS=60
Kafka vehicle.raw.go.* / vehicle.fields.go.* retention.ms=21600000segment.ms=600000segment.bytes=268435456
Fast writer FAST_WRITER_OPERATION_TIMEOUT_MS=1000,避免 TDengine 批量写尾延迟导致整批重投
Root disk 使用率低于 80%,超过 85% 进入容量告警

如果 NATS consumer_pending 下降但仍高,说明系统在追历史积压;如果 ack_pending=0 且 Kafka lag 为 0,不要重启服务,重点观察 NATS data size 和 pending 下降斜率。

分阶段压测

压测入口:

# 100 连接 smoke test
/opt/lingniu-go-native/current/load-sim \
  -protocol jt808 \
  -addr 127.0.0.1:808 \
  -connections 100 \
  -connect-rate 100 \
  -send-interval 10s \
  -duration 2m \
  -template 0200 \
  -send=false

load-sim-send=true 时会按连接和帧序号生成可被现有解析器解析的唯一协议帧:

  • JT808 会变更包头手机号、流水号和 0x0200 位置时间,并重新计算转义和校验码。
  • GB32960 会变更 VIN 和实时数据时间,并重新计算 BCC。
  • 低 FPS 全链路压测必须使用该模式,避免重复静态帧导致 event id 冲突。
  • 对生产端口执行 -send=true 会写入合成 raw 数据,只能在明确隔离标识和压测窗口后执行。
  1. 100 连接 smoke test。
  2. 10,000 连接保持测试。
  3. 10,000 连接 + 1 FPS/连接短测。
  4. 50,000 连接保持测试。
  5. 100,000 连接保持测试。
  6. 按真实协议分布进行混合帧率测试。

每一阶段必须记录:

  • active connections
  • gateway frame/publish counters
  • NATS pending 和 ack pending
  • Kafka lag
  • Redis/MySQL/TDengine 写入耗时和 pending depth
  • CPU/load/memory/file descriptors
  • 错误日志

2026-07-03 阶段压测记录

压测方式:在 ECS 本机使用 /opt/lingniu-go-native/current/load-sim127.0.0.1:808 发起 JT808 hold-only 连接,-send=false,不发送业务帧,不污染 raw 数据。

压测前基线,时间 2026-07-03 18:03:10 CST

服务状态 6 个 Go systemd 服务均 active
JT808 连接 约 240
GB32960 连接 约 2
load average 0.43 / 0.22 / 0.23
available memory 6661 MB
NATS ack pending 0
NATS pending 39
history/stat/realtime Kafka lag 0

阶段结果:

阶段 时间 参数 峰值连接/FD 结果 资源和队列
100 连接 18:03:21-18:04:21 CST connections=100 connect-rate=100 duration=60s send=false JT808 active 340ss341 opened 100failed 0frames 0write_errors 0 load 约 0.33/0.21/0.22available memory 约 6659 MB
1,000 连接 18:04:38-18:05:38 CST connections=1000 connect-rate=500 duration=60s send=false JT808 active 1240ss1241gateway FD 约 1256 opened 1000failed 0frames 0write_errors 0 load 约 0.80/0.33/0.26available memory 约 6645 MB
10,000 连接 18:05:59-18:07:59 CST connections=10000 connect-rate=1000 duration=120s send=false JT808 active 10240ss10241gateway FD 约 10256 opened 10000failed 0frames 0write_errors 0 20 秒时 load 约 0.45/0.33/0.27available memory 约 6409 MBNATS ack pending 0
50,000 连接 18:11:22-18:14:22 CST connections=50000 connect-rate=2000 duration=180s send=false JT808 active 50238ss50239gateway FD 约 50254 opened 50000failed 0frames 0write_errors 0 45 秒时 load 约 0.07/0.23/0.24available memory 约 5590 MBNATS ack pending 短时 29,后续归零
100,000 总连接 18:18:13-18:21:13 CST JT808 50000 + GB32960 50000,各 connect-rate=2000 duration=180s send=false JT808 active 50236GB32960 active 50002,总 active 约 100238gateway FD 约 100252 JT808 opened 50000 / failed 0GB32960 opened 50000 / failed 0frames 0write_errors 0 75 秒时 load 约 0.16/0.30/0.29available memory 约 4511 MBNATS ack pending 短时 10,后续归零

压测后:

  • 2026-07-03 18:08:47 CST JT808 active 回落到 240ss241
  • 2026-07-03 18:15:36 CST 5W 压测后 JT808 active 回落到约 238ss239
  • 2026-07-03 18:16:49 CST NATS ack pending 回到 0history/stat/realtime Kafka lag 总和均为 0
  • 2026-07-03 18:23:02 CST 10W 总连接压测后 JT808 active 回落到 236GB32960 active 回落到 2NATS ack pending 为 0history/stat/realtime Kafka lag 总和均为 0
  • 20211/20212/20213/20214/20200 readyz 均 OK。
  • 压测窗口未出现 gateway error|failed|panic|fatal|rejected 日志。
  • vehicle_gateway_connection_rejections_total 未输出,表示本轮没有连接拒绝计数。

结论:单 ECS 已通过本机 10W 总连接 hold-only 基线测试。该结果证明当前内核参数、gateway 连接上限和 systemd 文件句柄设置可以承载 10W 空闲长连接;下一阶段必须进入带真实帧率的低 FPS 压测验证解析、NATS、Kafka、Redis、TDengine、MySQL 全链路吞吐。