2.3 IoT DC3微服务架构实践
本节阅读说明:IoT DC3 是贯穿本书的开源工程参照。2.3.1 给出“一个网关 + 四个中心服务”的整体架构和协作逻辑——这是理解“物联网平台如何落地五层模型”的核心内容。2.3.2 至 2.3.6 对网关和各中心做了架构级展开,重点在设计决策和工程权衡而非操作手册——如果你需要快速建立全局认知,读完 2.3.1 和 2.3.7(协同流程时序图)即可满足后续章节的阅读需要。网关和各中心的源码级实现细节、部署配置和调试方法统一放在第 14 章项目实战中。
2.3.1 IoT DC3项目简介与微服务理念
一辆汽车的发动机、变速箱、底盘各自独立设计,却通过标准的接口组合成一整套动力系统。物联网平台如果也把所有功能焊死在一个单体应用里,一个告警规则的升级就可能拖垮整条数据采集链路。把“采集—归一—分析—决策—执行—反馈”拆成多个可独立迭代的微服务,正是 IoT DC3 的核心思路。理解它的设计逻辑,胜过记住几个服务名。
项目定位:通用底座,而非行业成品
IoT DC3 是一个基于微服务架构的开源物联网平台,采用 AGPL-3.0 许可证。它的目标不是给某个行业做一套定制方案,而是构建一条从设备连接到智能决策的通用底座。通用意味着它抽象了设备接入、数据归一、多租户隔离、RBAC(Role-Based Access Control,基于角色的访问控制)权限、时序存储这些底层能力,不绑定任何行业逻辑。底座则意味着提供可依赖的稳固结构——租户隔离、高可用部署、水平扩展——开发者不必从零搭建这些基础设施。DC3 的设计哲学强调通过微服务解耦来应对多样化设备接入和持续演进的业务逻辑。
为什么选微服务:解耦是第一驱动力
单体与微服务怎么选、按什么边界拆、拆分的代价如何偿还——这是通用方法论,第 6 章会系统展开,这里只看 DC3 的具体取舍。DC3 按业务边界拆分服务,协议 Driver 可独立开发和部署,模型实验也不必进入高频遥测进程。独立扩缩容是否成立,还取决于 Broker、数据库、缓存和有状态会话,不能理解成“只加一个 Data 实例”就必然解决瓶颈。规模较小时,跨服务配置、可观测性和一致性成本可能超过收益;规模扩大后也要以压测与团队所有权证明拆分价值,而不是假设微服务天然更高效。
一个网关 + 四个中心:各管一段,协同闭环
DC3 当前平台服务包含一个 Gateway 和 Auth、Manager、Data、Agentic 四个中心,南向接入则由独立协议 Driver 承担。五个服务不是一条必须依次经过的流水线:高频遥测走 Driver → RabbitMQ → Data,外部 HTTP 请求走 Client → Gateway → 对应中心,两条链路在职责上分离。
- Gateway 网关:平台北向 HTTP 入口,负责路由和认证过滤;限流、熔断等能力只有在当前配置和测试能够证明时,才算项目已启用能力。
- Auth 中心:认身份、管权限。实现多租户隔离和 RBAC。设计原则是不和任何设备数据接触——即使 Auth 短暂失效,数据采集链路仍可运行。
- Manager 中心:元数据服务。管理 Driver、设备、模板、位号和属性等定义;运行时位号值由 Data 管理。
- Data 中心:位号数据与命令枢纽。接收 Driver 上报的归一化位号值,写入时序存储,提供查询并提交设备命令;身份与元数据请求分别由 Auth、Manager 承担。
- Agentic Center:模型、会话和工具调用能力。当前实现只应按实际注册的 Tools 描述;自动化执行需要额外的策略、确认与 Workflow,不能由服务名推断。
下面这张图展示五个核心服务的逻辑关系,以及它们与外部基础设施之间的依赖和数据流向。为保持架构通用,图中将消息队列和时序数据库使用通用名称标注,实际部署时可根据性能要求选择具体产品。
技术栈与部署约束
DC3 的技术栈以 Java/Spring 为主:Spring Boot/Cloud 承载平台服务,Spring Cloud Gateway 提供外部 HTTP 入口,gRPC 用于 Driver 业务注册等内部调用,内部异步链路通过消息端口连接 Broker,Data 通过时序存储端口保存位号历史,Agentic 基于 Spring AI 管理模型、会话与 Tools。以 2026-08-29 的 987c96d50 快照为准,默认适配器是 RabbitMQ 与 TimescaleDB;消息端口另有 Kafka、RocketMQ、Pulsar、ActiveMQ、MQTT 5 适配器,时序端口另有 TDengine、InfluxDB、IoTDB 适配器。当前 Compose 通过服务名和环境变量定位服务,没有独立 Nacos,也没有模型推理容器。具体版本边界见第 14 章。
工程判断:什么时候上微服务
下表列出单体架构与微服务架构的典型权衡节点。数字是参考阈值,基于常见工程经验,并非精确分界点;实际决策需结合团队能力和运维成本。
| 判断因素 | 单体架构更适合 | 微服务架构更适合 |
|---|---|---|
| 设备数量 | 较 少 | 较 多 |
| 团队规模 | 较小,按功能划分 | 较大,按业务切分 |
| 部署条件 | 单机或虚拟机 | 容器编排平台 |
| 发布频率 | 低,全量发布 | 高,持续发布 |
| 设备协议数 | 有 限 | 较多,协议多样 |
| AI 需求 | 无或简单规则 | 需要 LLM 推理与工具调用 |
收束
Gateway 收外部 HTTP,Auth 管平台身份,Manager 管定义,Data 管位号值与命令,Agentic 管模型与 Tools,Driver 管现场协议。下面按这组边界展开,避免把所有流量强行串成一条链。
2.3.2 Gateway 网关:统一 HTTP 入口
以下五小节(2.3.2—2.3.6)为架构示范级展开,聚焦设计决策与工程权衡。各中心的源码实现细节见第 14 章。
工业现场可能同时存在 MQTT、CoAP、Modbus 和 OPC UA。DC3 不让平台 Gateway 解析这些协议,而是由 dc3-driver-* 连接设备、完成协议编解码和位号映射。Gateway 面向浏览器、第三方应用和运维 API,统一路由到 Auth、Manager、Data 与 Agentic。这里的“网关”必须与部署在现场的协议网关区分:前者是平台 API Gateway,后者可能是运行 Driver 或协议转换程序的边缘设备。
协议转换不在平台 Gateway
Driver 把寄存器、Topic 或节点值映射成平台位号值,经 RabbitMQ 交给 Data;命令则从 Data 经 RabbitMQ 返回目标 Driver。新增协议时应扩展 Driver 和对应配置,不需要在 Gateway 中注册所谓 UAM 映射器。UAM 不是当前仓库概念,本书不再用它描述 DC3 实现。
认证与路由:门禁与指示牌
对需要认证的外部 HTTP 请求,Gateway 的职责可以概括为:读取认证头 → 执行平台过滤策略 → 转发到目标中心。具体令牌格式与校验实现以当前源码为准。
- 登录与签发:客户端经 Gateway 调用 Auth 的盐值与 Token 接口。
- 携带凭据:后续请求携带项目约定的
X-Auth-Tenant、X-Auth-Login、X-Auth-Token等头,而不是把通用 JWT 示例冒充当前接口。 - 路由分发:Gateway 根据路径和环境变量配置,把请求转到目标中心。
- 纵深校验:下游服务仍要验证资源归属与动作权限,不能把 Gateway 通过等同于业务授权完成。
展开查看:Gateway 路由与认证配置示例(YAML)
spring:
cloud:
gateway:
routes:
- id: data_route
uri: ${GATEWAY_ROUTE_DATA_URI:http://dc3-center-data:8100}
predicates:
- Path=/api/v3/data/**
filters:
- name: AuthenticationFilter
metadata:
excludeAuthentication: false
# 健康检查等路径通过 excludeAuthentication: true 跳过认证
# manager_route 等其余路由按相同结构定义当前部署通过 Compose 服务名和 GATEWAY_ROUTE_*_URI 等环境变量定位中心服务,并不依赖 Nacos 或 lb:// 服务发现。健康检查等公开路径应保持最小集合;路径匹配和过滤顺序需要用集成测试验证,不能只靠配置审阅。
流量控制与安全防护:限流与防火墙
Gateway作为服务入口,需要具备防止资源被意外或恶意耗尽的能力。常见的工程措施包括:
- 请求限流:按登录主体、租户、路由和动作风险设置配额,并用压测确定阈值。设备遥测不走 Gateway,不能用 API 限流解释南向采集削峰。
- 请求体大小限制:对
Content-Length设置合理上限,超出阈值直接返回413 Payload Too Large。具体值取决于业务场景——设备遥测数据通常较小(几KB),但档案同步或固件升级可能达到几十MB,需要在/api/v3/manager/**等路径上单独提升限制。 - 路径暴露与输入校验:Gateway 只路由明确配置的北向接口,运维端点不应默认暴露。下游业务服务仍要按类型、长度、枚举和值域校验输入,并使用参数化查询;依靠网关拦截所谓“非法字符”不能防止注入。
这些防护措施并不构成绝对安全,但它们在极低的性能开销下,可以过滤掉绝大多数基于流量特征的攻击。对于更细致的设备级认证,需依赖Auth中心与Manager中心的二次校验。
工程实践:Gateway配置检查清单
每次发布 Gateway 前应核对路由目标与 Compose 服务名、认证排除路径、请求体上限、跨域策略和敏感管理端点。新增设备协议检查的是 Driver 注册、属性与位号映射,不是 Gateway 路由。完整调试方法见第 14 章。
Gateway 隔离外部 HTTP 入口,Driver 隔离设备协议。下面继续看平台身份和元数据如何落地。
2.3.3 Auth中心:身份认证与权限管理
一个工业物联网平台每天面对的设备种类、用户角色和数据流向错综复杂。运维人员坐在中控台修改变量,一台自动化设备通过网关上报温度数据,一个第三方分析系统请求拉取历史位号——这些动作都来自不同源头,访问不同资源,安全等级也各不相同。如果没有统一的认证与授权层,权限校验逻辑会散落在 Manager、Data、Agentic 各中心里,多租户隔离几乎只能靠开发人员的“自觉”,出问题时极难溯源。Auth 中心(dc3-center-auth)的设计目标,就是把认证与授权这个横切关注点从业务逻辑中剥离出来,实现统一认证、集中授权、租户隔离。在请求进入业务核心之前,Auth 中心会先回答三个问题:你是谁,你能干什么,你属于哪个租户。
认证机制:以当前项目接口为准
当前 Quick Start 中,客户端先申请短时 salt,再按项目规则生成密码摘要并换取 Token,后续通过 X-Auth-Tenant、X-Auth-Login、X-Auth-Token 等头访问 Gateway。Token 的内部格式、验签位置和有效期属于版本化实现细节,应以源码与部署配置为准;本节不再把通用 JWT/OAuth 流程写成 DC3 已实现事实。
自包含令牌可以减少逐请求查会话库的开销,但撤销、权限变更和密钥轮换仍可能引入服务端状态;不透明 Token 则便于集中撤销,却增加在线校验依赖。项目应围绕威胁模型、可用性和撤销时限选择机制,不能从“使用 Token”直接推断为无网络 I/O 的本地 JWT 验签。
如果部署采用纯无状态签名令牌,服务端只有引入撤销表、会话版本、令牌内省或密钥轮换,才能在到期前收回权限。有效期与刷新机制必须从当前配置读取,不宜用“15 分钟”等通用经验代替项目事实。
第三方应用和 MCP 远程传输需要独立设计授权流程。截至 2026-08,OAuth 2.1 仍是 IETF 草案;即使采用 PKCE 等建议,也不能据此宣称 DC3 Auth 已实现完整授权码流程。是否支持某种 grant、动态客户端注册或资源指示符,应逐项以端点和测试验证。
权限模型:RBAC 与租户隔离
认证通过之后是授权。DC3 的 Auth 中心在授权层选择了 RBAC(基于角色的访问控制,Role-Based Access Control)模型。每个用户被分配一个或多个角色,每个角色绑定一组权限集合。权限的表达方式是 resource:action,比如 device:read、command:write。运维人员不必给每个用户单独配置细粒度的权限,而是通过角色做批量管理,在大规模部署场景下明显降低了权限的配置和维护成本。
RBAC 只解决了“能不能做”的问题,没解决“做哪一家的”的问题。物联网平台几乎都是多租户架构——一家平台运营方可能同时服务多家工厂或园区,一家工厂的运维人员绝不该看到另一家工厂的设备位号。因此,DC3 在 RBAC 之上叠加了租户隔离:一个用户所属的租户 ID 直接关联到他能看到的数据范围。Data 中心写入位号值时,会同时带上租户标签;Auth 中心校验权限时,先确认用户角色具备操作权限,再确认他请求的资源属于该用户所属的租户。这两层过滤的组合——角色决定“能不能做”,租户决定“做哪一家的”——是多租户物联网平台安全隔离的常见且有效的工程实践。
在实现上,角色、权限、用户和租户的实际归属应以 Auth 的模型与 API 为准。Web 界面只是这些 API 的客户端,不能因页面入口位置推断数据由 Manager 保存。
平台用户身份与设备身份分开治理
平台用户通过 Gateway/Auth 访问管理 API;现场设备通过具体 Driver 所支持的协议接入,其身份可能由 MQTT 凭据、TLS 证书、OPC UA 证书、现场总线物理边界或上游系统账户表达。Driver 自身再以内部服务身份与平台协作。三类身份的生命周期、密钥和审计主体不同,不应虚构为“Manager 给每台设备生成密钥、Gateway 给设备签 JWT”的统一流程。
Auth 与其他中心的协作
Auth 中心不是孤立存在的,但认证通过不等于业务授权结束。更准确的分工是:Auth 建立平台主体,Gateway 执行入口策略,业务中心验证动作与资源边界,Driver 验证现场连接。
- 与 Gateway:登录请求路由到 Auth,其他外部请求携带认证头并接受入口过滤。
- 与 Manager / Data / Agentic:各中心不能只信任转发头,还要校验租户、资源所有权、工具白名单和动作参数。
- 与 Driver:设备协议认证和 Driver 服务身份是独立安全域,应分别记录连接主体与平台操作主体。
集中身份服务减少了重复认证代码,但授权规则仍分布在最了解资源语义的业务边界。令牌格式或密码算法升级也需要 Gateway、客户端和各中心的兼容测试,不能假定只改 Auth 一处即可自动完成。
安全最佳实践清单
基于 Auth 中心的架构,在部署和运维阶段可以提炼出一份安全检查清单,帮助团队快速识别常见的安全漏洞:
- 令牌加固:access_token 设置较短有效期(常见配置在 15 分钟左右),配合 refresh_token 实现无感续签;refresh_token 应在 Auth 中心保存其哈希值,以便用户主动退出或账户异常时强制失效。
- 传输安全:所有涉及访问凭据的接口都应使用 HTTPS;Gateway 转发至内网中心时,可按威胁模型评估 mTLS,防止凭据在内部链路被窃取。
- 最小权限:为设备和第三方应用分配角色时遵循最小权限原则——一个只上报数据的温湿度传感器,其角色权限应仅包含
data:write,绝对不应包含device:read或command:write。 - 审计日志:Auth 中心必须记录所有认证成功、失败以及权限拒绝事件。日志字段应至少包含来源 IP、操作时间、用户/设备 ID、请求的资源与动作。这些日志是事后安全审计和溯源的关键证据。
Auth 不直接处理业务数据——它不存储设备位号、不执行规则引擎、不运行大模型。但它是架构里一切安全的基础。没有它,Gateway 只是敞开的门,多租户隔离形同虚设,数据泄露和越权操作的风险会急剧上升。在一个成熟的物联网平台中,Auth 中心往往是第一个要搭建、最后一个才能动的服务。
2.3.4 Manager 中心:设备与配置元数据
Manager 中心(dc3-center-manager)承担配置元数据职责,管理 Driver、设备、模板、位号和属性等对象。它不位于实时数据通道中;Driver 负责采集,Data 负责位号值与命令。规则、场景编排和告警是否由某个版本实现,必须另行以代码和 API 验证,不能从“Manager”名称推断。
设备注册、分组与生命周期管理
Manager 中心管理的核心对象是设备在平台中的数字映射。这个映射包含设备身份、型号、位号列表、通信协议、注册位置、所属租户等元数据,存储在关系数据库中。
配置流程需要把可复用定义与运行实例分开:模板或 Profile 描述一类设备的位号结构,设备实例绑定具体 Driver、属性和现场标识。设备协议凭据应由具体 Driver 的属性模型和密钥管理方案承载,不假定 Manager 自动生成统一 Device Secret。
对于大规模部署,分组比单点管理更高效。Manager 中心支持多层级分组:
- 租户级分组:按组织边界隔离,不同租户的设备天然不可见。
- 场地级分组:例如“1号车间”“2号仓库”“办公楼3层”。
- 功能级分组:例如“温度传感器”“空调执行器”“安全门禁”。
若项目扩展了分组和批量策略,需要明确继承规则、租户边界与新增设备是否自动纳入;这是一项上层治理设计,不作为当前 Manager 的默认事实。
完整平台通常需要区分配置状态、连接状态、业务状态与退役状态。图 2-9 是一种通用生命周期设计示例,不代表当前 Manager 已实现同名状态机或自动告警;落地时应以实际字段、心跳来源和状态迁移测试为准。
可选扩展:ECA 规则与 Workflow
物联网项目经常在平台之外或独立服务中增加事件—条件—动作模型(Event-Condition-Action,ECA)。下面是通用设计,不是 DC3 当前 Manager 内嵌规则引擎的接口说明:
- 事件:可以是实时数据到达(例如一个温度位号值上报)、设备状态改变(上线/离线)、定时器到期或外部 API 调用。
- 条件:对事件数据进行求值的布尔表达式。常见条件包括:数值比较(
pointValue > 阈值)、字符串匹配、时间范围判断、复合条件(满足阈值1或阈值2)。条件支持与、或、非逻辑组合。 - 动作:满足条件后执行的操作。典型动作包括:下发命令给设备、推送告警到通知渠道(邮件、短信、微信)、调用外部 Webhook、存储推理结果、或触发另一条规则形成级联。
用一个场景来说明:一座仓库内安装了多个温度传感器。运维人员配置一条规则,规则配置的 JSON 如下(仅作示例,非 DC3 实际格式):
展开查看:温湿度联动 ECA 规则定义示例(JSON,节选)
{
"ruleId": "rule-temp-alert-001",
"name": "仓库温度超标告警",
"enabled": true,
"trigger": {
"type": "point_report",
"deviceGroupIds": ["group-warehouse-sensors"],
"pointCode": "temperature"
},
"conditions": [
{
"id": "cond-red",
"expression": "pointValue >= 30",
"priority": "RED",
"actions": [
{
"type": "alert",
"level": "red",
"message": "设备{deviceId}温度{pointValue}°C,严重超限!",
"channels": ["email", "sms", "wechat"]
},
{
"type": "command",
"deviceIds": ["device-fan-a", "device-fan-b"],
"pointCode": "fan_speed",
"value": 100
}
]
}
// 实际规则中还包含黄牌预警等更低优先级的条件分支
]
}规则或 Workflow 不应直接连接硬件。它产生候选 Action 后,仍需经过权限、值域、互锁、幂等与风险策略,再调用 Data 命令接口进入 RabbitMQ—Driver 链路。图 2-10 表达的是这条参考设计,不是当前 Manager 与 Data 的既有调用图。
场景联动与可视化界面
多设备联动需要显式 Workflow:定义触发事件、前置条件、并行或顺序动作、超时、补偿和人工接管。是否提供拖拽界面并不重要,关键是流程可版本化、可测试、可回放。DC3 当前若没有该引擎,应作为外部扩展接入,不能写成 Manager 开箱即用能力。
架构启示:数据一致性的设计取舍
规则与元数据同库可以获得局部事务,却让 Manager 承担实时执行压力;独立规则服务便于扩缩容,却要处理配置版本和事件一致性。没有普遍最优答案。当前 DC3 的核心边界应保持为 Manager 管定义、Data 管数据与命令;额外规则服务通过版本化配置和失效校验避免向已退役设备执行动作。
实践检查表:Manager 中心配置
配置 Manager 时优先核对 Profile/模板、位号类型与读写属性、Driver 属性和设备实例绑定。涉及规则与 Workflow 时,再增加边界值、退役设备、超时、补偿和人工接管测试;不要把未安装的扩展能力混入 Manager 基线检查表。
2.3.5 Data中心:数据采集、存储与分发
Data 中心(dc3-center-data)负责位号值、命令、回执及相关查询。南向 Driver 与 Data 之间以 RabbitMQ 解耦,外部客户端则经 Gateway 调用 Data API。Agentic 不默认订阅实时位号流,只在任务需要时通过已注册 Tool 查询。
从 RabbitMQ 消费数据:缓冲与解耦
设备上报路径是:dc3-driver-* 读取或接收现场数据,映射成位号值后发布到 RabbitMQ 的相应 Exchange,Data 消费并持久化。MQTT 可能是设备与 MQTT Driver 之间的现场协议,但平台内部总线仍是 RabbitMQ;Gateway 不在这条路径上。
RabbitMQ 位于 Driver 与 Data 之间,吸收短时生产消费速率差并隔离服务生命周期。它不是无限缓冲;队列长度、持久化、确认、死信、磁盘水位和消费者恢复速度必须共同设计。
- 削峰填谷:设备上报的瞬时高峰(如每日整点全楼宇同时上报)被队列吸收,数据库始终以平稳速率写入。
- 解耦生产者与消费者:Driver 不等待数据库逐条写入;Agentic 不在消费主链中,其推理耗时不会直接阻塞 Data 消费。
为直观展现数据流,图2-11描述了从设备到时序存储的完整路径。
图 2-11 展示默认主链:设备 → Driver → RabbitMQ 适配器 → Data → TimescaleDB 适配器。替换消息或时序适配器不会改变 Driver 与 Data 的职责边界。实时推送若由 WebSocket 或其他消费者实现,应从已验证的接口或消息出口接入,不能假定 Data 把每条数据广播给 Agentic。
数据清洗与预处理
无论清洗发生在 Driver、Data 还是独立质量服务,平台都必须显式处理以下问题。下列是应实现并测试的质量契约,不代表当前 Data 已逐项具备:
- 时间戳异常:同时保留采集时间与平台接收时间;超窗值应按业务选择隔离、标记或拒绝,不能统一静默丢弃。
- 数值越界:区分传感器量程、工程合理范围和控制安全范围;保留原值及质量码,避免清洗掩盖故障证据。
- 位号不存在:进入隔离队列并告警,防止配置漂移造成无声数据缺口。
- 重复数据:以来源序列号或事件 ID 做幂等;“设备 + 位号 + 时间戳”可能误删同一时刻的合法多次采样。
- 单位不统一:保留原始单位和值,转换结果记录算法版本和目标单位。
质量差的数据不等于可以丢弃的数据。更稳妥的分层是保存不可变原始事实,再生成带质量码和处理血缘的标准值;控制与分析按各自门槛选择是否消费。
数据存储:时序数据库选型与权衡
物联网平台常面对按设备与时间范围查询、持续追加和分层保留。关系数据库并非天然不能处理时序数据,专用时序引擎也并非天然更快;选择取决于写入规模、查询形态、压缩、事务、生态和运维能力。IoT DC3 当前通过 TsdbStore 隔离时序存储,默认 TimescaleDB 适配器复用主 PostgreSQL 实例中的 history 数据源;TDengine、InfluxDB 与 IoTDB 是可选适配器,具体能力通过适配器协商而不是假定完全等价。
- PostgreSQL:统一事务与 SQL 生态,适合先建立正确模型;规模增长后可用分区、批写和索引优化。
- TimescaleDB、InfluxDB 等时序方案:在特定写入、压缩和降采样场景有优势,但需要用目标工作负载验证并承担额外版本与运维边界。
- 搜索与对象存储:分别适合检索和低成本归档,通常是补充层而不是默认替代主存储。
默认 TimescaleDB 复用 PostgreSQL 运维体系,可以减少独立组件数量;是否沿用仍应由容量测试决定。替换适配器前要用同一工作负载验证聚合、保留、分页、超时和一致性语义。
下面的 SQL 仅展示通用位号值建模思路,不是 DC3 当前建表语句;create_hypertable 属于 TimescaleDB 适配器的能力,换用其他适配器时不能照搬:
-- 例子:DC3 位号值存储的核心字段
CREATE TABLE point_values (
time TIMESTAMPTZ NOT NULL, -- 采样时间点
device_id VARCHAR(64) NOT NULL, -- 设备ID
point_id VARCHAR(64) NOT NULL, -- 位号ID(如"温度_01")
value DOUBLE PRECISION, -- 数值
text_value TEXT, -- 字符串值(位号类型不同时使用)
unit VARCHAR(16), -- 单位,如℃、kPa、V
tenant_id VARCHAR(32) NOT NULL -- 租户ID,用于多租户数据隔离
);
SELECT create_hypertable('point_values', 'time'); -- 转为时序超表,自动分区每条记录都带租户上下文,确保多租户场景下的数据隔离。
数据分发与历史查询
持久化不是终点。不同消费者需要不同的数据出口,但应以当前 API 和消息契约为准:
- Agentic Center:通过已注册只读 Tool 调用 Data 查询,不直接连接数据库。
- 实时监控:通过平台支持的 WebSocket、轮询或专用消费服务获得数据,不让浏览器直接订阅内部 RabbitMQ。
- 规则与告警扩展:消费版本化事件,并把告警状态与重复抑制独立持久化。
在默认主链中,RabbitMQ 适配器承接 Driver 发布的位号值,Data 消费后经 TsdbStore 持久化。换用其他 Broker 时,应按能力矩阵重新核对路由、确认、延迟、死信和重放语义;不能把内部消息拓扑默认当成公共数据总线。
对于历史数据查询,Data 中心对外提供 REST 接口,支持时间范围、位号筛选和聚合函数。例如,查询某设备过去 1 小时内温度的最大值、平均值、最小值,接口路径大致为:
GET /data/history/{deviceId}/{pointId}?start=2025-03-01T00:00:00Z&end=2025-03-01T01:00:00Z&aggregate=avg,max,min&interval=5m返回结构和聚合能力必须以当前 Data API 与 TsdbStore 能力为准。time_bucket 是 TimescaleDB 适配器的实现细节,其他适配器应使用各自原语或由门面层降级,业务代码不能直接依赖某一数据库函数。
时序数据压缩与保留策略
时序数据的增长速度很快。一个拥有 1 万位号的智能工厂,若每 5 秒采集一次,每日新增记录就超过 1.7 亿条。这个数字可以沿着一条算术链逐步复算,链条上的每一环恰好对应本节前文各组件的职责:
- 写入 TPS:10 000 位号 ÷ 5 秒 = 2 000 条/秒。这是时序写入链路需要稳住的平均速率,重传和补采只会带来更高的瞬时峰值;
- 每日入库量:2 000 条/秒 × 86 400 秒 = 1.728 亿条/日,即“每日超过 1.7 亿条”的出处;
- 消息队列吞吐:按单条
PointValue序列化后约 200 字节估算(字段构成见前文建表语句,此为示例假设,实际取决于报文格式),2 000 条/秒 × 200 字节 = 400 KB/秒,折合每日约 34.6 GB 的未压缩消息流量——这是 RabbitMQ 采集交换机与消费者之间要稳定承受的吞吐量级; - 压缩后磁盘占用:34.6 GB/日 的原始数据经 TimescaleDB 列式压缩,按 10∶1 的保守压缩比估算(工程估算值,非产品实测数据),热数据约 3.5 GB/日;叠加表2-5 中“热数据保留 7-30 天”的策略,30 天热窗口的磁盘占用在 100 GB 量级,单节点即可承载。
若不设保留策略,存储成本会持续增长。下表是一种容量设计模板,不是 DC3 默认配置;保留周期、压缩比和归档介质都要以法规、故障分析窗口和实际数据测试确定:
表2-5 数据分层保留策略
| 数据层级 | 存储内容 | 保留周期 | 压缩方式 | 预估压缩比 |
|---|---|---|---|---|
| 热数据(原始) | 原始 PointValue 记录 | 7-30 天 | TimescaleDB 列式压缩 | 大幅降低磁盘占用 |
| 温数据(降采样) | 分钟级聚合(均值、最大、最小) | 1-6 个月 | 列式压缩 | 显著节省空间 |
| 冷数据(长期归档) | 小时级/天级聚合 | 1-3 年 | 冷存储归档(如 S3) | N/A |
降采样必须保留原始数据与聚合数据的血缘,并避免均值掩盖尖峰、告警和缺测。自动删除只可在归档校验、保留策略审批和恢复演练完成后执行。
Data 中心写入接口示例
下面的 REST 控制器只用于比较“同步接收”与“异步持久化”的语义,不是 DC3 当前遥测入口。当前 Driver 通过 RabbitMQ 发布位号值;外部应用不应照此新增旁路写入接口:
展开查看:Data 中心接收数据的 REST 控制器(Java,节选)
// 例子:DC3 Data中心接收数据的 REST 控制器
@RestController
@RequestMapping("/data")
public class DataController {
@PostMapping("/pointValues")
public ResponseEntity<Void> receivePointValues(
@RequestBody List<PointValue> values) {
// 1. 将数据写入 RabbitMQ 队列,指定路由键为 "dc3.data.point"
rabbitTemplate.convertAndSend("dc3.data.point", values);
// 2. 直接返回 202 Accepted, 表示已接收、待异步处理
return ResponseEntity.accepted().build();
}
}
// PointValue 模型的核心字段(deviceId、pointId、value、unit、time、tenantId 等)
// 与前文 point_values 表结构一一对应,此处从略。若某项目实现这种接口,202 Accepted 只代表请求进入异步处理,不能证明消息持久化或数据库写入成功;客户端还需要事件 ID、幂等与状态查询。DC3 当前链路的确认语义应从 RabbitMQ publisher confirm、consumer ack 和 Data 持久化行为分别验证。
实践要点
本小节的核心判断是:DC3 的稳定主链为 Driver → 消息端口 → Data → 时序存储端口,当前默认适配器是 RabbitMQ 与 TimescaleDB;数据质量要保留原值、质量码与处理血缘;替换适配器后仍须通过目标工作负载验证存储、保留、聚合和失败语义。具体运行边界见第 14 章。
2.3.6 Agentic Center:智能决策与执行中枢
Data 中心把设备数据接住、存好、分发出去了。现在回头看看 2.1 节提出的那个问题:谁来做“决策”?谁来把数据变成动作?在经典四层架构里,这一步要么丢给人——操作员盯着监控大屏,手动点击“打开阀门”;要么丢给静态规则——温度超过 30°C 就开空调,写死在代码里。这两种方式面对动态复杂场景都捉襟见肘。IoT DC3 的答案是 Agentic Center(dc3-center-agentic),它把智能层从概念落成了可运行的微服务。
Agentic Center是 2.1.2 节描述的“智能层”在工程上的具体实现。它的职责不限于“分析数据”,而是承担了闭环中的理解、规划与执行三个环节——不是简单的规则引擎,而是让大语言模型(LLM)直接参与运营决策的中枢。
核心能力:从“看数据”到“动设备”
Agentic Center的内核是 Spring AI 框架,它提供了 Tool-Calling 机制。简单说,就是给 LLM 配了一套“工具箱”——每个工具是一个标注了 @Tool 注解的 Java 方法,对应一个平台操作,例如“查询某设备当前温度”、“写入位号值”、“下发设备命令”。LLM 收到用户指令后,自行判断需要调用哪个工具、传入什么参数,然后把结果返回给用户或触发下一个动作。这套机制兼容 OpenAI API 标准,因此可以接入 GPT、Claude、DeepSeek 等主流模型。
这套机制让 Agentic Center具备了三个关键能力:
- 语义理解与推理:用户不需要记住设备 ID 或位号编码,可以直接说“三号产线的电机温度是不是偏高”,Agentic Center负责解析语义、关联元数据、调用查询工具,并给出带上下文的分析结论。
- 多步骤规划:单次查询可以触发一连串操作。例如“把车间温度降到 22°C”,Agentic 会先查当前温度,再与目标值比较,然后决定是调大冷水阀开度还是降风机频率,最后下发多条命令。
- 高风险动作确认:不是所有命令都直接执行。Agentic Center设计了风险分级:读操作自动放行,写操作(尤其是改参数、启停设备)会在交互界面弹出二次确认框,要求操作员审核后再执行。
下面是一个 Agentic Center处理用户指令的伪代码。这段代码不是 DC3 的源码,但概括了其工作逻辑。
展开查看:Agentic 执行决策伪代码(节选)
// 例子:用户发指令"把A楼空调温度调到24度"
function handle_user_intent(intent):
// 1. 解析意图,提取实体:设备位置=A楼,设备类型=空调,目标温度=24
entity = llm_parse(intent)
// 2. 查询设备元数据(Manager 中心 API)→ 设备ID="AC_001"
device_info = api_call("query_device", {location, device_type})
// 3. 查询当前温度(Data 中心 API)
current_temp = api_call("query_point_value", {device_id, point_id: "temp"})
// 4. 规划动作:计算温差,决定需要调整多少度
delta = entity.target_temp - current_temp
// 5. 风险判断:写操作,需要确认
if risk_level("write") == "high":
user_confirm(...)
if not confirmed: return "操作已取消"
// 6. 执行:调用工具,写入位号值;7. 反馈结果给用户
tool_call("write_point_value", {device_id, point_id: "temp_setpoint", value})
return "A楼空调温度已设置为 " + entity.target_temp + "°C"这段伪代码只展示 Agent Runtime 的职责分解,不代表 IoT DC3 当前已经注册了同名工具或允许模型自动写设备。真实系统中,查询可由只读工具完成;任何写操作还要经过独立的授权、参数校验、风险分级、人工确认或确定性 Workflow,再进入平台既有命令链路。
与 Data 中心的交互:数据是决策的养料
Agentic Center 不是数据平台。它需要通过受权工具调用 Data 或其他业务服务,典型交互包括:
- 读取当前状态:工具查询 Data 中心保存的最新位号值;响应时间必须通过部署实测,不能预设“毫秒级”或假定存在特定缓存。
- 查询历史与证据:工具按时间窗取得历史序列、质量标记和设备元数据。LLM 可以解释趋势或生成排查假设,但异常检测、因果判断和控制条件应由可验证算法、规则或人工确认承担。
回看 2.1.2 节的闭环图,Agentic Center 位于“证据查询—解释与规划—受控行动”链路上,但实时遥测不经过它:Driver 经 RabbitMQ 把位号值交给 Data,Agentic 仅在任务需要时通过工具读取。这样可以避免模型调用阻塞高频数据链路。
例子:温室环境自动控制
下面通过一个例子来完整走一遍 Agentic Center的运作流程。场景设定为一个采用 IoT DC3 平台管理的智能温室。
背景与触发:Manager 中心已配置设备、模板和位号,Driver 负责接收温湿度数据并经 RabbitMQ 送入 Data。凌晨 3 点,确定性规则发现温度连续低于业务阈值,创建一条待分析事件。一个额外部署的巡检任务调用 Agentic Center,请它读取现场状态、解释风险并提出调整建议。这个任务是教学扩展,不是 IoT DC3 默认 Compose 自带的实时链路。
Agentic Center的推理流程(本书示例场景,相关数值用于说明工程判断,非通用统计结论):
- 查询状态:通过
@Tool调用 Data 中心的接口,获取当前传感器位号值。返回结果:温度 12°C(阈值下限 15°C),湿度 80%(正常范围 60-85%)。 - 判断问题:LLM 分析数据,识别出温度低于设定阈值,属于“温度过低”告警。
- 生成建议:模型给出“检查通风状态并评估是否启用补光”的候选步骤,同时附上所用读数、时间窗和不确定性;它不能自行把相关性写成根因。
- 策略与确认:Workflow 校验作物、设备互锁、动作范围和指令有效期。只读分析可自动运行;写操作默认进入人工确认。只有经过风险评估、限幅和故障演练的低风险动作,才可配置为条件自动执行。
- 受控执行与审计:确认后的 Action 通过 Data 命令接口进入 RabbitMQ,再由目标 Driver 转成现场协议操作;请求、审批、参数、回执和执行后读回结果写入审计存储。Agentic 不直接连接设备,也不把“API 已接受”当成物理动作成功。
若该动作仍处于人工确认级别,夜间任务只生成告警与建议;若经过现场验证后被纳入低风险自动化白名单,系统也必须保留策略版本、执行回执和执行后读回值。两种模式的边界由安全分析和运行证据决定,不能由模型自行升级权限。
反馈机制与自我优化
Agent Runtime 需要记录建议是否被接受、动作是否执行、设备读回值是否达到目标以及人工为何改判。这些记录可进入版本化评测集,但不能未经治理就自动成为训练样本:其中可能含有个人信息、错误操作和受版权或保密约束的数据。MCP 用于暴露经过授权的工具,不是执行数据导出协议;离线分析应走明确的数据导出、脱敏和审批流程。
边界与权衡
Agentic Center并非万能。它的设计有几条明确的假设:
- 适用场景:决策逻辑复杂、需要自然语言交互或上下文理解的场景。纯确定性控制(如“压力超过 10MPa 就开泄压阀”)交给规则引擎更轻量。
- 延迟:调用 LLM 有网络耗时。端到端的一次指令解析与执行,从用户提问到设备响应,延迟通常在秒级(具体取决于模型和网络),不适合亚秒级的控制回路。
- 依赖:它依赖 Data 中心与管理中心,无法在平台离线时独立工作。
这套设计遵循“确定性控制不依赖概率模型”的边界:PLC、SIS 或经过验证的边缘规则承担硬实时与安全联锁;Agentic Center 处理秒级以上的查询、解释、方案生成和受控编排。模型位于云还是边缘由数据、时延、成本和可用性决定,不能用一句“云侧训练、边缘推理”概括所有项目。
2.3.7 网关与四中心协同运作:从设备注册到智能控制的完整流程
前几节拆解了 Gateway、Auth、Manager、Data 和 Agentic 的职责。本节只描述 2026-08 当前仓库能够从代码与配置确认的主链路,并把可选智能扩展单独标出。设备遥测不经过平台侧 Gateway,设备也不向 Auth 申请会话后再上报:现场协议由 Driver 处理,Driver 通过 gRPC 向 Manager 注册业务信息,并通过 RabbitMQ 与 Data 交换位号值、命令和回执;Gateway 是 Web 与外部 API 的统一 HTTP 入口。
流程概览:智能灌溉系统的设备管控
仍以土壤湿度传感器和电磁阀为例。这里不预设“低于阈值即自动开阀”,而是先跑通采集和命令链路,再由项目的规则或审批 Workflow 决定何时允许控制。主链路分为六步。
第一步:运维侧登录,Driver 注册。 运维人员和外部应用通过 Gateway 调用 Auth 获取平台访问凭据,再经 Gateway 管理元数据。协议 Driver 启动后,使用平台内部 gRPC 业务注册机制向 Manager 报告自身能力与状态。现场设备是否需要证书、用户名或协议令牌,由具体 Driver 和现场协议负责,不等同于平台用户登录。
第二步:Manager 维护设备元数据。 运维人员经 Gateway 调用 Manager,配置模板、设备实例、位号和驱动属性。以土壤湿度传感器为例,需要:
- 选择驱动模板(假设用 Modbus 协议驱动)
- 创建设备实例,填入名称、序列号、地理位置
- 定义位号列表:湿度(
humidity),数据类型float,单位%,读区间 0–100 - 为后续规则或 Workflow 提供阈值、单位、质量要求和允许动作范围;控制策略不应假定由 Manager 自动同步到 Data 执行
配置完成后,Driver 按自身运行机制取得所需配置。规则引擎或 Workflow 若由项目额外部署,应明确其所有者、输入数据、版本与执行边界,不能写成当前 Data 内置能力。
第三步:设备经 Driver 上报位号值。 Driver 连接设备或上游数据源,完成协议编解码和点位映射,生成标准位号值并发布到消息端口。Data 消费消息并经 TsdbStore 持久化;默认部署对应 RabbitMQ 与 TimescaleDB。原始报文、换算值、采集时间、接收时间和质量状态应区分保存;Gateway 不在这条遥测链路上。
第四步:应用或 Agentic 按需查询。 Web、业务应用或 Agentic 中明确注册的只读 Tool,经 Gateway 和平台鉴权查询当前值或历史值。若引入天气等外部证据,必须记录来源、时间与失败策略。模型可以提出“建议灌溉”的假设,但不能把预测直接转换为设备命令。
第五步:策略与人工确认生成 Action。 规则或 Agent 建议先经过值域校验、设备状态检查、互锁、权限和风险策略。高风险动作必须由人确认;符合预先批准条件的低风险动作才可自动形成带目标、参数、截止时间和幂等键的 Action。Agentic 不直接连接设备。
第六步:Data 经 RabbitMQ 把命令交给 Driver。 确认后的命令由 Data 发布到 RabbitMQ,目标 Driver 消费后转成 Modbus、MQTT 或其他现场协议操作,并把回执返回 Data。调用方还应读取执行后的实际位号,区分“平台接受”“Driver 已发送”“设备确认”和“物理状态达成”四种状态。Gateway 只承接外部 API 请求,不转发现场协议命令。
完整协同流程
下面用时序图的形式呈现整个交互序列。这张图既可作为架构文档的核心插图,也能在开发新人入职时解释“设备数据怎么变成设备动作”。
对照时序图,有三个边界需要记住:遥测和命令都以 Driver、RabbitMQ、Data 为主链;Gateway/Auth 只位于外部 HTTP 访问与平台用户鉴权链路;Agentic 是按需调用的上层能力,不在高频数据通道内。任何额外规则引擎、调度器或模型服务都应标为项目扩展,并单独说明故障降级。
闭环的关键:位号值的上下文传递
链路能够被治理,依赖统一的位号定义以及可追踪的数据与命令标识。上报值至少要能关联设备、位号、采集时间、接收时间和质量状态;命令要关联 Action、调用者、参数、截止时间、幂等键和回执。单位、量程等语义来自 Manager 管理的元数据,不意味着每一条消息都重复携带全部标签。
工程检查清单
实地部署网关与四中心协作时,下表列出常见问题和建议做法,供架构评审和系统调优时参考。
| 序号 | 问题 | 建议做法 |
|---|---|---|
| 1 | 平台用户与现场设备是否共用认证? | 不默认共用;平台用户走 Gateway/Auth,设备身份由具体 Driver 与现场协议治理 |
| 2 | 规则引擎放 Manager 还是 Data? | 当前核心链路不预设内置规则引擎;项目扩展应按时延、安全和所有权独立设计 |
| 3 | Agentic 推理失败怎么办? | 不让模型位于安全控制主链;超时则终止任务或返回人工处理,确定性规则继续独立运行 |
| 4 | 指令下发可靠性怎么保证? | 用消息队列异步解耦,配合回执确认和重试机制 |
| 5 | 多租户隔离怎么做? | 在 API、消息、元数据和存储各层验证租户上下文;是否分库由风险与规模决定 |
链路断在哪里,先看哪类证据。 Auth 异常时,登录和需要在线鉴权的北向请求可能失败;遥测是否继续取决于 Driver—消息端口—Data 链,与“网关本地验签”不能混为一谈。Broker 积压时,要比较生产、消费、未确认和最老消息年龄,不能先假定数据仍会入库。时序库变慢时,同时观察 Data 消费、写入失败、重试和查询延迟。界面症状只能帮助定位,最终结论要由当前适配器指标和日志证明。
这个例子给出的不是所有物联网平台的唯一拓扑,而是一张有版本边界的 DC3 当前链路图。第 6 章会解释服务和消息边界,第 7 章补上 Agent Runtime 的治理,第 14 章再用当前仓库命令验证 Driver 注册、数据上报、命令回执与只读工具调用。