整理中文文档结构与索引
This commit is contained in:
878
doc/gateway/实时设备网关架构.md
Normal file
878
doc/gateway/实时设备网关架构.md
Normal file
@@ -0,0 +1,878 @@
|
||||
# 实时设备数据网关最终方案
|
||||
|
||||
本文档用于收敛当前关于 GPS 模拟、中转、监控、规则判定、回放、通知分发等讨论,给出一版可直接进入实现设计的最终方案。
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标与定位
|
||||
|
||||
本系统不再定义为“GPS 模拟器”,而定义为:
|
||||
|
||||
- 一个独立部署的实时设备数据网关
|
||||
- 负责实时接入、标准化、路由、订阅、最新状态同步
|
||||
- 默认不依赖数据库,不承担历史存储职责
|
||||
- 通过插件扩展规则判定、通知分发、回放、归档等能力
|
||||
|
||||
一句话定义:
|
||||
|
||||
> 一个以实时中转为核心、以插件扩展业务能力的轻量遥测网关。
|
||||
|
||||
---
|
||||
|
||||
## 2. 设计原则
|
||||
|
||||
### 2.1 核心优先级
|
||||
|
||||
核心目标按优先级排序如下:
|
||||
|
||||
1. 实时性能
|
||||
2. 稳定性
|
||||
3. 低耦合
|
||||
4. 易扩展
|
||||
5. 易观测
|
||||
|
||||
### 2.2 核心边界
|
||||
|
||||
核心服务只负责:
|
||||
|
||||
- 长连接接入
|
||||
- 消息标准化
|
||||
- 路由转发
|
||||
- 订阅管理
|
||||
- latest state 缓存
|
||||
- 连接管理
|
||||
- 心跳和断线清理
|
||||
- 基础鉴权
|
||||
- 限流与基本防护
|
||||
|
||||
核心服务不负责:
|
||||
|
||||
- 历史存储
|
||||
- 业务报表
|
||||
- 复杂规则引擎
|
||||
- 第三方通知发送
|
||||
- 业务数据库查询
|
||||
- 面向家长端或场控端的专属业务逻辑
|
||||
|
||||
---
|
||||
|
||||
## 3. 总体架构
|
||||
|
||||
### 3.1 拓扑关系
|
||||
|
||||
```text
|
||||
Producer
|
||||
├─ 手机客户端
|
||||
├─ 外部模拟器
|
||||
├─ 回放器
|
||||
└─ 设备接入器
|
||||
|
|
||||
v
|
||||
Realtime Device Gateway
|
||||
├─ Connection Manager
|
||||
├─ Protocol Layer
|
||||
├─ Session Manager
|
||||
├─ Router / Fanout
|
||||
├─ Latest State Cache
|
||||
└─ Plugin Bus
|
||||
|
|
||||
+--> Consumer
|
||||
| ├─ 小程序 / App
|
||||
| ├─ 家长端
|
||||
| ├─ 场控端
|
||||
| └─ 调试端 / 大屏
|
||||
|
|
||||
+--> Plugins
|
||||
├─ Rule Engine
|
||||
├─ Dispatcher
|
||||
├─ Recorder
|
||||
├─ Replayer Adapter
|
||||
└─ Webhook / Bridge
|
||||
|
||||
Business Server
|
||||
├─ 用户与设备关系
|
||||
├─ 配置管理
|
||||
├─ 历史归档
|
||||
└─ 业务接口
|
||||
```
|
||||
|
||||
### 3.2 在整个系统中的定位
|
||||
|
||||
实时网关在整个系统中,不是主业务服务器的替代品,而是一层独立的实时中枢。
|
||||
|
||||
职责分工建议固定为:
|
||||
|
||||
- 设备、模拟器、回放器
|
||||
- 负责产出实时数据
|
||||
- 实时网关
|
||||
- 负责接入、路由、订阅、latest state、实时分发、运行态观察
|
||||
- 业务服务器
|
||||
- 负责用户、设备归属、配置、历史存档、业务查询
|
||||
- 插件
|
||||
- 负责规则、通知、归档、回放等异步能力
|
||||
|
||||
一句话理解:
|
||||
|
||||
> 主业务服务器负责“谁是谁”,实时网关负责“现在发生了什么,发给谁看”。
|
||||
|
||||
### 3.3 服务角色
|
||||
|
||||
- `Producer`
|
||||
- 实时数据生产者
|
||||
- 包括真实设备、模拟器、回放器
|
||||
|
||||
- `Consumer`
|
||||
- 实时数据消费者
|
||||
- 包括家长端、场控端、调试端、大屏
|
||||
|
||||
- `Controller`
|
||||
- 可向 Producer 或 Gateway 下发控制命令
|
||||
- 包括调试控制台、场控后台、回放控制器
|
||||
|
||||
### 3.4 角色使用流程
|
||||
|
||||
#### 开发模拟
|
||||
|
||||
1. Controller 在管理台创建 `channel`
|
||||
2. 网关返回 `channelId / producerToken / consumerToken`
|
||||
3. 老模拟器作为 Producer 加入 channel 并开始发 `telemetry.location / telemetry.heart_rate`
|
||||
4. 管理台和调试 Consumer 实时观察数据
|
||||
5. 业务服务器此时可以不参与,或仅做低频归档
|
||||
|
||||
#### 家长端监控
|
||||
|
||||
1. 真机设备作为 Producer 向网关持续上报位置和状态
|
||||
2. 家长端作为 Consumer 订阅某个 `deviceId` 或 `groupId`
|
||||
3. 网关负责实时分发
|
||||
4. 业务服务器负责账号关系、历史数据和业务页面
|
||||
|
||||
#### 场控
|
||||
|
||||
1. 场控端作为 Consumer 订阅多个设备或一个分组
|
||||
2. 网关持续推送实时位置、状态和事件
|
||||
3. 如果有控制需求,场控端再以 Controller 身份下发命令
|
||||
4. 规则插件可基于同一条实时流做违规判定
|
||||
|
||||
#### 归档
|
||||
|
||||
1. Producer 只向网关上报实时数据
|
||||
2. Recorder 插件异步消费网关流
|
||||
3. Recorder 再按 `10-30s` 批量写入业务服务器
|
||||
|
||||
这样可以保证:
|
||||
|
||||
- 实时链路和归档链路解耦
|
||||
- 客户端可以逐步从双写演进到单写网关
|
||||
- 实时数据和历史数据口径更一致
|
||||
|
||||
---
|
||||
|
||||
## 4. 部署原则
|
||||
|
||||
### 4.1 独立部署
|
||||
|
||||
实时网关必须独立于主业务服务器部署。
|
||||
|
||||
这样做的原因:
|
||||
|
||||
- 不占用主业务服务器的实时长连接资源
|
||||
- 不让实时 fanout 干扰主业务接口
|
||||
- 实时服务可独立扩容
|
||||
- 便于分离故障和性能问题
|
||||
|
||||
### 4.2 与主业务服务的关系
|
||||
|
||||
主业务服务只提供控制面能力:
|
||||
|
||||
- 用户与设备归属关系
|
||||
- 权限配置
|
||||
- 策略配置
|
||||
- 历史存档入口
|
||||
|
||||
实时网关处理数据面:
|
||||
|
||||
- 高频 telemetry
|
||||
- 最新状态同步
|
||||
- 实时下行通知和控制
|
||||
|
||||
原则上,不允许每条实时上报都回主业务服务查库。
|
||||
|
||||
---
|
||||
|
||||
## 5. 0 数据库方案
|
||||
|
||||
### 5.1 可行性
|
||||
|
||||
第一版核心网关可以做到 0 数据库依赖。
|
||||
|
||||
这里的含义是:
|
||||
|
||||
- 不接 MySQL
|
||||
- 不接 PostgreSQL
|
||||
- 不接业务持久化存储
|
||||
- 不存历史轨迹
|
||||
- 不做持久化 session
|
||||
|
||||
### 5.2 保留的内存态
|
||||
|
||||
即使 0 数据库,网关仍然必须保留以下运行时内存数据:
|
||||
|
||||
- 连接表
|
||||
- 订阅关系
|
||||
- 设备 latest state
|
||||
- 会话元数据
|
||||
- 限流计数
|
||||
- 心跳状态
|
||||
|
||||
### 5.3 重启语义
|
||||
|
||||
网关重启后允许丢失:
|
||||
|
||||
- 当前连接
|
||||
- 当前订阅
|
||||
- latest state
|
||||
- 临时限流计数
|
||||
|
||||
系统恢复方式:
|
||||
|
||||
- 客户端自动重连
|
||||
- 重新鉴权
|
||||
- 重新订阅
|
||||
- Producer 继续上报最新点
|
||||
|
||||
这对实时网关是可接受的。
|
||||
|
||||
---
|
||||
|
||||
## 6. 性能目标
|
||||
|
||||
### 6.1 第一版容量目标
|
||||
|
||||
第一版至少满足:
|
||||
|
||||
- `1000-2000` 设备同时在线上报
|
||||
- 默认 `1 Hz` 实时上报能力
|
||||
- 支持部分调试设备升频到 `2-5 Hz`
|
||||
- 端到端实时链路延迟目标 `< 500 ms`
|
||||
- 插件故障不阻塞核心中转
|
||||
|
||||
### 6.2 带宽认知
|
||||
|
||||
实时中转一定消耗网关所在服务器的带宽,但不会占用主业务服务器带宽。
|
||||
|
||||
不做历史存储,只能减少:
|
||||
|
||||
- 磁盘 IO
|
||||
- 存储成本
|
||||
- 数据库压力
|
||||
|
||||
不能减少:
|
||||
|
||||
- 长连接压力
|
||||
- 实时 fanout 压力
|
||||
- 网关入口和出口带宽
|
||||
|
||||
### 6.3 核心优化原则
|
||||
|
||||
- 不允许全量广播
|
||||
- 必须按设备或组定向订阅
|
||||
- payload 尽量小
|
||||
- latest state 只保留当前值
|
||||
- 插件必须异步消费
|
||||
- 高频调试源必须可限流
|
||||
|
||||
---
|
||||
|
||||
## 7. 消息模型
|
||||
|
||||
### 7.1 统一信封
|
||||
|
||||
所有进入网关的数据统一使用一个标准信封:
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"messageId": "uuid",
|
||||
"timestamp": 1711267200000,
|
||||
"topic": "telemetry.location",
|
||||
"source": {
|
||||
"kind": "producer",
|
||||
"id": "watch-001",
|
||||
"mode": "real"
|
||||
},
|
||||
"target": {
|
||||
"deviceId": "child-001",
|
||||
"groupId": "class-a"
|
||||
},
|
||||
"payload": {}
|
||||
}
|
||||
```
|
||||
|
||||
### 7.2 topic 分类
|
||||
|
||||
建议只保留四类顶级 topic:
|
||||
|
||||
- `telemetry.*`
|
||||
- `state.*`
|
||||
- `event.*`
|
||||
- `command.*`
|
||||
|
||||
示例:
|
||||
|
||||
- `telemetry.location`
|
||||
- `telemetry.heart_rate`
|
||||
- `telemetry.motion`
|
||||
- `state.device`
|
||||
- `event.rule_violation`
|
||||
- `event.sos`
|
||||
- `command.replay.start`
|
||||
- `command.simulation.stop`
|
||||
|
||||
### 7.3 source mode
|
||||
|
||||
建议显式区分数据来源模式:
|
||||
|
||||
- `real`
|
||||
- `mock`
|
||||
- `replay`
|
||||
- `control`
|
||||
|
||||
这样业务侧可以明确识别是真实数据还是模拟/回放数据。
|
||||
|
||||
---
|
||||
|
||||
## 8. 主要数据载荷
|
||||
|
||||
### 8.1 位置 telemetry
|
||||
|
||||
```json
|
||||
{
|
||||
"lat": 31.2304,
|
||||
"lng": 121.4737,
|
||||
"altitude": 12.3,
|
||||
"speed": 1.5,
|
||||
"bearing": 90,
|
||||
"accuracy": 8,
|
||||
"coordSystem": "GCJ02"
|
||||
}
|
||||
```
|
||||
|
||||
最少保留字段:
|
||||
|
||||
- `timestamp`
|
||||
- `lat`
|
||||
- `lng`
|
||||
- `speed`
|
||||
- `bearing`
|
||||
- `accuracy`
|
||||
- `coordSystem`
|
||||
|
||||
### 8.2 心率 telemetry
|
||||
|
||||
```json
|
||||
{
|
||||
"bpm": 142,
|
||||
"confidence": 0.92
|
||||
}
|
||||
```
|
||||
|
||||
### 8.3 运动 telemetry
|
||||
|
||||
```json
|
||||
{
|
||||
"cadence": 168,
|
||||
"stepCount": 3201,
|
||||
"calories": 248.5,
|
||||
"movementState": "run"
|
||||
}
|
||||
```
|
||||
|
||||
### 8.4 设备状态
|
||||
|
||||
```json
|
||||
{
|
||||
"online": true,
|
||||
"battery": 76,
|
||||
"network": "4g",
|
||||
"charging": false
|
||||
}
|
||||
```
|
||||
|
||||
### 8.5 事件
|
||||
|
||||
```json
|
||||
{
|
||||
"eventType": "rule_violation",
|
||||
"ruleId": "geo-fence-01",
|
||||
"severity": "high",
|
||||
"text": "leave allowed area"
|
||||
}
|
||||
```
|
||||
|
||||
### 8.6 控制命令
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "simulation.start",
|
||||
"args": {
|
||||
"sessionId": "sim-001",
|
||||
"speedRate": 2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 订阅与路由模型
|
||||
|
||||
### 9.1 路由单位
|
||||
|
||||
实时网关按以下维度路由:
|
||||
|
||||
- `deviceId`
|
||||
- `groupId`
|
||||
- `topic`
|
||||
|
||||
### 9.2 推荐订阅粒度
|
||||
|
||||
- 订阅某个设备全部实时消息
|
||||
- 订阅某个设备某类消息
|
||||
- 订阅某个组某类消息
|
||||
|
||||
示例:
|
||||
|
||||
- `device:child-001`
|
||||
- `device:child-001/topic:telemetry.location`
|
||||
- `group:class-a/topic:event.*`
|
||||
|
||||
### 9.3 latest state
|
||||
|
||||
每个设备保留一个最新状态快照,不存历史。
|
||||
|
||||
用途:
|
||||
|
||||
- 新订阅者刚连上时立即获得当前状态
|
||||
- 页面重连后快速恢复
|
||||
- 插件可从最新态快速计算
|
||||
|
||||
---
|
||||
|
||||
## 10. 鉴权策略
|
||||
|
||||
### 10.1 不建议完全不鉴权
|
||||
|
||||
如果完全不鉴权,会带来两个高风险问题:
|
||||
|
||||
- 任意客户端都能伪造位置或心率
|
||||
- 任意客户端都可能下发控制命令
|
||||
|
||||
### 10.2 推荐分级鉴权
|
||||
|
||||
- `Producer`
|
||||
- 必须强鉴权
|
||||
- 防止伪造上报
|
||||
|
||||
- `Controller`
|
||||
- 必须强鉴权
|
||||
- 防止误操作和恶意控制
|
||||
|
||||
- `Consumer`
|
||||
- 可轻鉴权
|
||||
- 可按内网、白名单、临时 token、短期票据放宽
|
||||
|
||||
### 10.3 第一版推荐方式
|
||||
|
||||
第一版建议:
|
||||
|
||||
- Producer 使用签名 token 或短期接入 token
|
||||
- Controller 使用管理 token
|
||||
- Consumer 使用轻量订阅 token
|
||||
|
||||
网关本身不查数据库,只做:
|
||||
|
||||
- token 基本校验
|
||||
- 角色识别
|
||||
- 权限范围校验
|
||||
|
||||
复杂鉴权可以由独立鉴权服务承担。
|
||||
|
||||
---
|
||||
|
||||
## 11. 插件体系
|
||||
|
||||
### 11.1 原则
|
||||
|
||||
事件处理不是核心同步主链路的一部分,而是插件。
|
||||
|
||||
同步主链路只做:
|
||||
|
||||
`ingest -> normalize -> route -> fanout -> update latest state`
|
||||
|
||||
然后异步投递到插件总线:
|
||||
|
||||
`publish -> plugin bus -> plugin async consume`
|
||||
|
||||
### 11.2 第一批插件类型
|
||||
|
||||
- `Rule Engine`
|
||||
- 实时规则判定
|
||||
- `Dispatcher`
|
||||
- 通知和下行分发
|
||||
- `Recorder`
|
||||
- 归档与历史写入
|
||||
- `Replayer`
|
||||
- 文件或历史流回放
|
||||
- `Webhook`
|
||||
- 向外部系统桥接
|
||||
|
||||
### 11.3 插件要求
|
||||
|
||||
- 不能阻塞主链路
|
||||
- 失败必须隔离
|
||||
- 可独立启停
|
||||
- 最好支持单独部署
|
||||
|
||||
---
|
||||
|
||||
## 12. 规则判定与通知分发
|
||||
|
||||
### 12.1 规则不进核心
|
||||
|
||||
规则判定必须在插件层执行,不进入中转核心。
|
||||
|
||||
原因:
|
||||
|
||||
- 规则计算不稳定
|
||||
- 容易引入复杂状态
|
||||
- 容易放大 CPU 和 IO 消耗
|
||||
- 不应影响实时转发
|
||||
|
||||
### 12.2 推荐规则类型
|
||||
|
||||
- 阈值规则
|
||||
- 心率过高
|
||||
- 速度异常
|
||||
- 电量过低
|
||||
|
||||
- 时空规则
|
||||
- 离开围栏
|
||||
- 进入禁区
|
||||
- 停留超时
|
||||
- 偏离路线
|
||||
|
||||
- 行为规则
|
||||
- 长时间静止
|
||||
- 轨迹跳变
|
||||
- 设备离线
|
||||
|
||||
### 12.3 动作分发
|
||||
|
||||
规则命中后由 Dispatcher 插件执行动作:
|
||||
|
||||
- 下发终端警告
|
||||
- 推送给家长端
|
||||
- 推送给场控端
|
||||
- 上报业务服务
|
||||
- 触发 Webhook
|
||||
|
||||
### 12.4 规则系统必须处理的问题
|
||||
|
||||
- 去重
|
||||
- 冷却时间
|
||||
- 恢复事件
|
||||
- 幂等
|
||||
|
||||
---
|
||||
|
||||
## 13. 客户端上报策略
|
||||
|
||||
### 13.1 当前推荐的第一阶段方案
|
||||
|
||||
客户端保留两条链路:
|
||||
|
||||
- 实时链路
|
||||
- 有需要时实时上报到网关
|
||||
- 归档链路
|
||||
- 每 `10-30s` 打包一次发给业务服务器存档
|
||||
|
||||
这个方案的优点:
|
||||
|
||||
- 改造快
|
||||
- 实时与归档解耦
|
||||
- 主业务服务器不承受高频位置流
|
||||
|
||||
### 13.2 双写风险
|
||||
|
||||
客户端双写存在天然风险:
|
||||
|
||||
- 两边成功率不同
|
||||
- 数据口径可能不一致
|
||||
- 客户端逻辑更复杂
|
||||
- 重试和去重更难
|
||||
|
||||
### 13.3 推荐演进方向
|
||||
|
||||
推荐第二阶段改成:
|
||||
|
||||
- 客户端只向网关实时上报
|
||||
- `Recorder` 插件按 `10-30s` 批量归档到业务服务器
|
||||
|
||||
这样可以保证:
|
||||
|
||||
- 实时和归档数据同源
|
||||
- 客户端逻辑更轻
|
||||
- 后续回放、规则、告警直接复用同一条实时流
|
||||
|
||||
### 13.4 客户端升频策略
|
||||
|
||||
建议客户端支持策略切换:
|
||||
|
||||
- `normal`
|
||||
- 低频或关闭实时上报
|
||||
- `monitor`
|
||||
- `1-5s` 实时上报
|
||||
- `debug`
|
||||
- `1 Hz`
|
||||
- `alert`
|
||||
- 临时升频
|
||||
|
||||
---
|
||||
|
||||
## 14. 模拟与回放
|
||||
|
||||
### 14.1 模拟器定位
|
||||
|
||||
模拟器不再是一个独立特殊系统,而是一个标准 Producer。
|
||||
|
||||
它可以上报:
|
||||
|
||||
- `telemetry.location`
|
||||
- `telemetry.heart_rate`
|
||||
- `telemetry.motion`
|
||||
- `state.device`
|
||||
|
||||
### 14.2 回放器定位
|
||||
|
||||
回放器也是 Producer。
|
||||
|
||||
区别只是:
|
||||
|
||||
- source mode 为 `replay`
|
||||
- 输入来源是文件或历史流
|
||||
- 支持播放、暂停、倍速、循环
|
||||
|
||||
### 14.3 地图模拟器要求
|
||||
|
||||
地图拖点时不应直接瞬移发点,至少要支持:
|
||||
|
||||
- 时间戳
|
||||
- 插值
|
||||
- 平滑
|
||||
- 速度和朝向生成
|
||||
|
||||
否则业务侧会看到不真实的轨迹。
|
||||
|
||||
---
|
||||
|
||||
## 15. 技术选型建议
|
||||
|
||||
### 15.1 技术选型原则
|
||||
|
||||
本系统技术选型必须遵守以下原则:
|
||||
|
||||
- 轻量
|
||||
- 健壮
|
||||
- 性能优先
|
||||
- 少依赖
|
||||
- 易部署
|
||||
- 易排障
|
||||
|
||||
目标形态应更接近:
|
||||
|
||||
- 软路由插件
|
||||
- 轻量代理
|
||||
- 边缘网关
|
||||
- 单二进制网络服务
|
||||
|
||||
而不是典型的重业务后台服务。
|
||||
|
||||
### 15.2 第一版推荐
|
||||
|
||||
核心网关建议明确采用以下技术栈:
|
||||
|
||||
- 服务端语言:`Go`
|
||||
- 实时协议:`WebSocket`
|
||||
- 管理接口:`HTTP`
|
||||
- 消息格式:`JSON`
|
||||
- 运行态存储:纯内存
|
||||
- 配置方式:本地配置文件加环境变量
|
||||
- 部署形态:单二进制
|
||||
- 日志:结构化日志
|
||||
|
||||
推荐原因:
|
||||
|
||||
- 更适合长连接、低延迟、fanout 场景
|
||||
- 内存和 CPU 占用更可控
|
||||
- 二进制部署简单
|
||||
- 依赖少,更接近基础设施服务风格
|
||||
- 后续扩到更高在线数更稳
|
||||
|
||||
如果目标是先稳定支撑 `1000-2000` 在线连接,推荐优先考虑:
|
||||
|
||||
- 服务端:`Go`
|
||||
- 实时协议:`WebSocket`
|
||||
- 管理接口:`HTTP`
|
||||
- 配置来源:本地配置文件或环境变量
|
||||
- latest state:进程内内存
|
||||
|
||||
原因:
|
||||
|
||||
- 长连接和 fanout 场景更贴近 Go 的强项
|
||||
- 资源占用更稳
|
||||
- 后续扩到更高并发成本更低
|
||||
|
||||
### 15.3 网关内部建议模块
|
||||
|
||||
为了保持“轻量但可扩展”,建议核心网关内部拆为以下模块:
|
||||
|
||||
- `listener`
|
||||
- 管理 WebSocket 和 HTTP 入口
|
||||
- `session manager`
|
||||
- 管理连接、身份、心跳、会话元数据
|
||||
- `router`
|
||||
- 负责 topic、device、group 维度路由
|
||||
- `fanout hub`
|
||||
- 负责多订阅者分发
|
||||
- `state cache`
|
||||
- 保存设备 latest state
|
||||
- `auth verifier`
|
||||
- 校验 Producer、Consumer、Controller 的 token
|
||||
- `rate limiter`
|
||||
- 限制异常高频上报
|
||||
- `plugin bus`
|
||||
- 异步发布给规则、通知、归档等插件
|
||||
|
||||
这些模块都应保持进程内实现,避免第一版引入外部组件。
|
||||
|
||||
### 15.4 第一版不建议引入的依赖
|
||||
|
||||
第一版不建议引入:
|
||||
|
||||
- 数据库
|
||||
- 消息队列
|
||||
- 服务注册中心
|
||||
- 复杂配置中心
|
||||
- 脚本型规则执行器
|
||||
- 重型 RPC 框架
|
||||
|
||||
这些能力都可以在后续容量和业务复杂度真正需要时再补。
|
||||
|
||||
### 15.5 可接受的替代方案
|
||||
|
||||
如果团队更熟悉 TypeScript,也可以先用:
|
||||
|
||||
- `Node.js + TypeScript + WebSocket`
|
||||
|
||||
但要注意:
|
||||
|
||||
- 网关层应保持非常薄
|
||||
- 不要过早塞业务逻辑
|
||||
- 一开始就准备好以后拆分插件
|
||||
|
||||
但如果核心目标明确是“像软路由一样稳定跑实时中转”,仍然优先推荐 Go。
|
||||
|
||||
---
|
||||
|
||||
## 16. MVP 范围
|
||||
|
||||
第一版只做以下内容:
|
||||
|
||||
### 16.1 核心网关
|
||||
|
||||
- WebSocket 接入
|
||||
- Producer / Consumer / Controller 三类角色
|
||||
- 统一消息信封
|
||||
- 按设备订阅
|
||||
- latest state 缓存
|
||||
- 心跳和断线处理
|
||||
- 基础限流
|
||||
- 基础鉴权
|
||||
|
||||
### 16.2 模拟器接入
|
||||
|
||||
- 地图拖点
|
||||
- 轨迹文件导入
|
||||
- 播放 / 暂停 / 倍速 / 循环
|
||||
- 输出位置和心率等标准 telemetry
|
||||
|
||||
### 16.3 观察端
|
||||
|
||||
- 订阅设备位置和状态
|
||||
- 查看最新点
|
||||
- 接收实时事件
|
||||
|
||||
### 16.4 插件最小集
|
||||
|
||||
- Recorder
|
||||
- 可选启用
|
||||
- Rule Engine
|
||||
- 先做最简单几条规则
|
||||
- Dispatcher
|
||||
- 先支持网关内消息通知
|
||||
|
||||
### 16.5 明确不做
|
||||
|
||||
- 业务数据库耦合
|
||||
- 复杂多租户
|
||||
- 大报表系统
|
||||
- 历史查询中心
|
||||
- 集群调度系统
|
||||
|
||||
---
|
||||
|
||||
## 17. 第二阶段演进
|
||||
|
||||
第二阶段建议逐步增加:
|
||||
|
||||
- 归档从客户端双写迁移到 Recorder
|
||||
- 多实例网关
|
||||
- Redis 作为共享状态和实例间消息桥
|
||||
- 更细粒度权限
|
||||
- 完整规则库
|
||||
- 回放服务独立化
|
||||
- 外部通知集成
|
||||
|
||||
第三阶段再考虑:
|
||||
|
||||
- 数据库落盘
|
||||
- 历史检索
|
||||
- 统计分析
|
||||
- 高可用和地域分布
|
||||
|
||||
---
|
||||
|
||||
## 18. 最终结论
|
||||
|
||||
最终方案建议如下:
|
||||
|
||||
- 以“实时设备数据网关”作为系统核心,而不是继续围绕“GPS 模拟器”扩展
|
||||
- 网关独立部署,不占主业务服务器的实时带宽和连接资源
|
||||
- 第一版采用 0 数据库设计,仅保留运行时内存态
|
||||
- 核心只做实时接入、标准化、路由、订阅和 latest state
|
||||
- 规则判定、通知分发、回放、归档全部插件化
|
||||
- 第一版先支撑 `1000-2000` 在线上报
|
||||
- 当前客户端可继续采用“实时发网关 + 10-30 秒批量发业务服”的过渡方案
|
||||
- 中期应演进为“客户端单写网关,归档由 Recorder 插件完成”
|
||||
|
||||
这套方案能同时覆盖:
|
||||
|
||||
- 开发模拟
|
||||
- 家长端监控
|
||||
- 场控
|
||||
- 规则判定
|
||||
- 通知分发
|
||||
- 数据回放
|
||||
- 后续更多传感器接入
|
||||
|
||||
同时又能把实时性能放在系统设计的首位。
|
||||
|
||||
Reference in New Issue
Block a user