4. 平台总体架构设计

医疗设备资产管理平台面向医院设备科、临床科室、维保服务商和监管方,业务横跨设备台账、采购验收、计量检定、巡检保养、故障维修、效益分析和报废处置。若把全部功能塞进一个单体应用,任何一次计量规则调整都可能牵动维修工单模块,发布风险高、扩容粒度粗。因此本平台采用微服务架构,但微服务不是目的,而是为了让“设备全生命周期”这条主线上不同变化频率、不同数据一致性要求的业务各自独立演进。

一、模块划分:按业务能力而非技术分层切分

划分微服务时最容易犯的错误是按“Controller 层、Service 层、DAO 层”切,结果每个服务都要跨库联表。正确做法是按业务能力边界切分。本平台可划分为以下核心服务:

  • 设备台账服务(asset-service):设备主数据、二维码/RFID 标识、位置与责任人变更,是全局被引用的基础域。
  • 采购验收服务(procure-service):采购申请、到货验收、供应商与合同信息。
  • 计量检定服务(metrology-service):检定计划、证书、有效期预警,强合规、强时间约束。
  • 运维工单服务(workorder-service):报修、派工、维修记录、备件消耗,写入频繁。
  • 效益分析服务(analysis-service):开机率、收入、成本核算,读多写少、可容忍延迟。
  • 文件与报表服务(file-service):证书扫描件、维修照片、PDF 报表的存取。

其中设备台账服务是“被依赖方”,其他服务只保存 assetId 引用,不复制设备明细,避免主数据不一致。计量检定与运维工单之间通过事件解耦:检定不合格的设备发布 DeviceCalibrationFailed 事件,工单服务订阅后自动生成停用与维修工单,而不是让计量服务直接调用工单接口。

医疗设备资产管理平台总体架构 前端层(前后端分离) 设备科 Web 管理端 · 临床科室移动端 · 维保商小程序 · 大屏看板 API 网关(Spring Cloud Gateway) 路由转发 · JWT 鉴权 · 限流熔断 · 灰度发布 · 统一日志埋点 服务注册发现(Nacos) 服务实例注册 · 健康心跳 · 负载均衡寻址 配置中心(Nacos Config) 环境隔离 · 动态刷新 · 版本回滚 业务微服务层 设备台账服务 asset-service 采购验收服务 procure-service 计量检定服务 metrology-service 运维工单服务 workorder-service 效益分析服务 analysis-service 文件与报表服务 file-service 消息队列(RabbitMQ) 检定不合格 · 工单状态变更 · 预警通知 文件存储(MinIO 对象存储) 检定证书 · 维修照片 · PDF 报表 数据层 MySQL 主从(业务库) · Redis 缓存(会话/热点) · Elasticsearch(设备检索)

二、前后端分离与 API 网关

前端采用 Vue 3 + Vite 构建单页应用,通过 REST/JSON 与后端交互,静态资源部署在 Nginx 或 CDN。前后端分离的关键约定是:接口契约先行,用 OpenAPI 3.0 描述,前端据此生成 TypeScript 类型,避免字段名靠口头对齐。网关是唯一入口,承担五件事:路由转发、JWT 鉴权、限流熔断、灰度发布、统一日志埋点。

以设备查询为例,网关路由配置片段如下:

spring:
  cloud:
    gateway:
      routes:
        - id: asset-service
          uri: lb://asset-service
          predicates:
            - Path=/api/asset/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 50
                redis-rate-limiter.burstCapacity: 100

其中 lb://asset-service 表示网关不写死 IP,而是从注册中心按服务名负载均衡。限流参数示例为每秒补充 50 个令牌、突发容量 100,属于教学示例值,实际应按压测结果调整。

三、服务注册发现与配置中心

服务启动时向 Nacos 注册自身 IP、端口和健康检查路径,默认每 5 秒发送一次心跳,超过 15 秒未收到心跳标记为不健康,超过 30 秒剔除。网关和 Feign 客户端通过服务名寻址,实例上下线对调用方透明。配置中心则把数据库连接、MQ 地址、预警阈值等外置。例如计量证书到期预警天数,可在 Nacos 中配置 metrology.cert.warn-days=30,修改后通过 @RefreshScope 动态生效,无需重启服务。

配置中心按 namespace(环境)→ group(业务域)→ dataId(服务名) 三级隔离,开发、测试、生产环境互不干扰,避免把测试库地址带到生产。

四、消息队列与文件存储的选型组合

消息队列选用 RabbitMQ,原因是本平台事件量中等、需要可靠投递和延迟队列(如证书到期前 30 天提醒),RabbitMQ 的 TTL + 死信队列即可实现,运维成本低于 Kafka。核心事件包括:DeviceCalibrationFailed、WorkOrderStatusChanged、CertExpiringSoon。生产端开启 publisher confirm,消费端手动 ack,防止消息丢失。

文件存储选用 MinIO,兼容 S3 协议,可私有化部署在医院内网,满足医疗数据不出院的要求。检定证书、维修照片以对象形式存储,数据库只保存 objectKey 和元数据。上传流程为:前端向 file-service 申请预签名 URL,直传 MinIO,成功后回调登记元数据,避免大文件穿透业务服务。

五、组合后的调用链示例

一次“检定不合格自动停用”的完整链路是:计量服务写入检定结果 → 发布 DeviceCalibrationFailed 到 RabbitMQ → 工单服务消费并生成维修工单 → 调用台账服务将设备状态置为“停用” → 通过 WebSocket 推送临床科室。整条链路中,网关负责入口鉴权,Nacos 负责寻址,配置中心控制预警阈值,MinIO 保存证书原件,各组件职责清晰、可独立替换。

微服务拆分不是越细越好。设备台账与采购验收若拆得过细,会导致验收时频繁跨服务查询设备信息。建议初期按上述 6 个服务落地,待团队和运维能力成熟后再考虑进一步拆分。