管理中台篇五:Aspire、Gateway、DataWorker 与容器部署

管理中台要能本地开发,也要能部署交付。IIoT.CloudPlatform 不是一个单独 API 进程。它需要数据库、缓存、消息队列、迁移程序、HTTP API、网关、后台 worker 和前端一起运行。项目用 Aspire 组织本地开发运行环境,再用 compose 模板承接部署。

如果只把它当成一个后端服务,部署时容易漏掉数据库初始化、Redis、RabbitMQ、DataWorker、网关路径和前端静态资源。管理中台承载设备身份、配方版本、生产归档和后台查询,运行拓扑本身就是业务可靠性的一部分。

Aspire 运行视图

这张 Aspire 运行视图对应的是管理中台的运行拓扑。能看到多个资源和服务同时存在,而不是只有一个后端接口。这个视图证明了系统边界:HttpApi、Gateway、DataWorker、数据库、缓存和消息队列各自有位置。

AppHost 组织运行环境

IIoT.AppHost 里可以看到当前管理中台的核心运行资源:

  • PostgreSQL/TimescaleDB:业务数据和时序/生产归档数据基础。
  • Redis:缓存与部分运行态能力。
  • RabbitMQ:事件总线和异步消息。
  • MigrationWorkApp:迁移和初始化。
  • HttpApi:业务接口和上传入口。
  • Gateway:统一入口和路径转发。
  • DataWorker:后台归档、Outbox、消息消费等异步工作。
  • iiot-web:Vue 前端,承载登录、生产概览、人员、设备、配方、产能、日志、过站和权限页面。
flowchart TD AppHost["IIoT.AppHost"] --> Pg["PostgreSQL / TimescaleDB"] AppHost --> Redis["Redis"] AppHost --> Rabbit["RabbitMQ"] AppHost --> Migration["MigrationWorkApp"] AppHost --> Api["HttpApi"] AppHost --> Gateway["Gateway"] AppHost --> Worker["DataWorker"] AppHost --> Web["iiot-web"]

这个结构把管理中台拆成了可观察的运行单元。数据库、缓存、消息、迁移、API、网关、worker、前端都能在 Aspire 里看到启动状态。开发期看拓扑,交付期按同一拓扑准备容器和环境变量,减少“本地能跑,部署缺依赖”的问题。

云端登录页

登录页现在也属于交付边界。它不是静态宣传页,而是管理中台的后台入口:工号密码登录、双语切换、生产预览和同步状态都在同一个前端运行时里。部署时如果 Web 容器没有真正 serve 构建后的 dist,后台人员就无法进入这些管理能力。

Gateway 收口入口

Gateway 的职责是统一入口和路径分流。IIoT.Gateway 通过 YARP 反向代理把请求转到 HttpApi。业务路径包括 /api/v1/human/*/api/v1/edge/*/api/v1/bootstrap/* 等。

这几类路径对应不同入口:

  • human:后台人员使用的管理中台接口。
  • edge:上位机设备侧上传和查询接口。
  • bootstrap:边缘设备启动寻址和设备身份确认入口。

Gateway 把这些路径先收口,再转给后端业务服务。认证、代理、路径管理和外部访问口径集中处理。业务规则仍然放在应用服务和领域层,Gateway 不承载设备、配方、产能等业务判断。

DataWorker 承接后台节奏

DataWorker 的存在和产线数据上传有关。

现场上位机上传数据时,入口链路要短。HttpApi 负责接收、校验、幂等和事件投递。设备日志、小时产能、过站数据这些归档动作,通过 RabbitMQ 和 DataWorker consumer 承接。代码里能看到 DeviceLogConsumerHourlyCapacityConsumerPassStationConsumer<TEvent>,也能看到 DataWorker 注册 MassTransit 和对应队列。

这种拆分避免把后台慢任务压到上传入口上。现场上传链路需要稳定返回,后台处理需要能重试、能观察、能扩展。DataWorker 单独运行,正好承接这类工作。

部署模板也是系统边界

部署不是最后补一个脚本。管理中台能否交付,取决于部署模板是否把运行依赖讲清楚。

项目部署里要关注几个点:

  • PostgreSQL 数据卷默认保留,不能因为更新服务误删历史数据。
  • 迁移容器需要 JWT、种子管理员账号等初始化参数。
  • Web 容器要实际 serve 构建后的 dist
  • Gateway 对外端口要和现场部署约定一致。
  • 环境变量要在 .env.env.example 中保持一致。

这些内容属于交付边界的一部分。设备身份、配方版本、生产归档都在云端,一次错误部署可能直接影响现场数据可用性。AppHost 负责开发期组织,compose 模板负责交付期落地,两者共同构成管理中台的运行边界。

开发期用 Aspire 看清服务关系,部署期用容器模板固定运行依赖。管理中台不是一个单进程后台,而是一组围绕上位机管理、生产归档和设备身份运行的服务拓扑。

AppHost 解决的是本地开发和部署一致性

管理中台不是只有一个 API 服务。它依赖数据库、缓存、消息队列、迁移程序、前端、网关和后台 worker。AppHost 把这些资源放进同一个编排入口,本地开发时能看到每个资源的运行状态,部署时也能把服务边界带到容器结构里。

这个结构对后期收尾很有用。云端主体能力封存后,后续新增工序默认只做必要 DTO、Command、Validator、事件契约、持久化表、查询接口和前端展示字段。AppHost、Gateway、DataWorker、PostgreSQL/TimescaleDB、Redis、RabbitMQ 这些主链路不应该因为新增一个字段被重开。

Gateway 和 HttpApi 的分工

Gateway 是外部入口收口层,HttpApi 是业务接口承接层。/api/v1/human/*/api/v1/edge/*/api/v1/bootstrap/* 这类入口集中到 Gateway 后,外部访问路径更稳定。HttpApi 内部处理人员、设备、配方、bootstrap、上传和查询等业务能力。

这样拆的收益是部署和演进都更清楚。入口策略、转发、跨域和前端访问路径可以在 Gateway 侧收敛;业务规则、DTO、Command 和 Controller 保持在 HttpApi 内。后续如果只改生产数据接入,不需要改变所有外部访问口径。

容器部署要保留数据边界

容器部署不能只看进程能不能起来,还要看数据是否安全保留。PostgreSQL/TimescaleDB 保存管理中台的主数据和历史归档,Redis 和 RabbitMQ 承担缓存与消息,DataWorker 负责消费处理。部署更新时默认保留数据库卷,不应把清库当成普通修复手段。

当前部署基线还要求外部 gateway 端口保持 GATEWAY_HTTP_PORT=81,迁移服务必须拿到 JWT、种子管理员账号、密码和真实姓名等环境变量。这些不是细枝末节,而是管理中台能否稳定启动和初始化的交付条件。

为什么部署也属于架构设计

部署不是项目收尾时才补的脚本。管理中台的服务边界如果在部署里丢掉,本地开发时的结构就无法稳定交付。Gateway、HttpApi、DataWorker、MigrationWorkApp 和前端分别承担不同职责,容器部署需要保留这些边界,不能为了少几个进程把它们混回一个入口。

环境变量也属于交付口径。JWT 密钥、种子管理员、数据库连接、gateway 端口和前端运行方式都直接影响系统能不能启动、能不能登录、能不能接收上位机数据。部署模板里缺一个关键变量,不应该被解释成运行时小问题,而是交付缺口。

AppHost 和容器结构对齐后,后续新增业务接入就有稳定落点。本地能观察服务,部署能按同样边界运行,问题定位也能从具体资源入手,而不是在一个黑盒进程里猜。

posted @ 2026-04-30 15:02  LJHArchitecture  阅读(17)  评论(0)    收藏  举报