3. 系统集成架构设计
线上诊疗系统并不是一个单体应用,它同时承载挂号、问诊、处方、支付、药品配送、随访、监管上报等多条业务链,还要与院内 HIS、LIS、PACS、医保结算、第三方支付、CA 签名、短信/推送等外部系统对接。如果把这些能力全部塞进一个进程,任何一处改动都会牵动全链路,接口耦合、发布风险、故障扩散都会迅速失控。因此本节采用微服务 + 事件驱动的组合架构:用微服务划分稳定的业务边界,用事件驱动解耦跨服务的状态传播与异步协作,再通过统一的集成层收敛外部系统差异。
一、服务边界:按业务能力而非按技术分层切分
服务边界的划分原则是“高内聚、低耦合、数据自治”。每个微服务拥有自己的数据库,不共享表,跨服务只通过接口或事件交互。结合线上诊疗的实际业务,可划分为以下核心服务:
- 患者服务:患者档案、实名认证、就诊人管理、健康卡绑定。
- 排班与预约服务:医生排班、号源池、预约锁号、取消与改约。
- 问诊服务:图文/视频问诊会话、病情描述、医患消息、问诊状态机。
- 处方服务:处方开具、合理用药校验、药师审方、处方状态流转。
- 订单与支付服务:问诊费、药费订单、支付回调、退款。
- 药品与配送服务:药品目录、库存、药房调剂、物流轨迹。
- 病历与档案服务:电子病历、诊断记录、随访计划。
- 集成网关服务:对接 HIS/LIS/PACS/医保/CA 等外部系统,做协议转换与数据映射。
- 通知服务:短信、App 推送、微信模板消息。
- 监管上报服务:按监管要求上报问诊、处方、医师资质等数据。
边界判断的一个实用标准是:如果一个能力的变化频率、数据所有权、扩缩容需求明显不同,就应独立成服务。例如处方审方需要对接药师工作站和合理用药库,其变更节奏与问诊会话完全不同,因此必须拆开。
二、通信协议:同步查询走 REST/gRPC,状态传播走事件
通信方式的选择直接决定系统的耦合度与一致性模型。总体策略是:需要立即拿到结果的读操作走同步调用,需要通知多个下游的状态变更走异步事件。
- 同步调用:对外 API 采用 HTTPS + JSON(REST),便于前端和第三方接入;服务间高频、低延迟的内部调用采用 gRPC(HTTP/2 + Protobuf),例如问诊服务查询医生排班、订单服务校验处方有效性。
- 异步事件:采用 Kafka 作为事件总线,事件以“领域事件”命名,如
appointment.created、consultation.finished、prescription.approved、order.paid、delivery.shipped。事件体包含事件 ID、发生时间、聚合根 ID、版本号和业务载荷。 - 事件契约:所有事件使用统一的信封结构,业务载荷用 JSON Schema 约束,新增字段必须向后兼容,禁止修改已发布字段的含义。
下面这张图展示了线上诊疗系统从预约到配送的完整集成拓扑:左侧是接入层,中间是微服务与事件总线,右侧是外部系统,底部是数据与基础设施。
三、数据流:以“问诊完成”为例的事件链
事件驱动架构的价值在于把一次业务动作引发的多个下游反应解耦。以“医生完成问诊并开具处方”为例,数据流如下:
- 问诊服务将会话状态置为
finished,写入本地库,并向 Kafka 发布consultation.finished事件,载荷包含consultationId、patientId、doctorId、diagnosisCode。 - 处方服务订阅该事件,创建待开方任务;医生提交处方后,处方服务执行合理用药校验,通过后发布
prescription.approved。 - 订单支付服务订阅
prescription.approved,生成药费订单并调用第三方支付;支付回调成功后发布order.paid。 - 药品配送服务订阅
order.paid,触发药房调剂与物流下单,状态变更时发布delivery.shipped。 - 通知服务订阅上述所有事件,向患者推送“处方已通过”“支付成功”“药品已发出”等消息。
- 病历档案服务订阅
consultation.finished与prescription.approved,归档电子病历;监管上报服务按批次上报。
这里的关键设计是事件只描述“已经发生的事实”,不描述“希望对方做什么”。例如发布 order.paid 而不是 ship.drug,配送服务是否发货、何时发货由它自己决定。这样新增一个“积分服务”只需订阅事件,无需修改订单服务。
四、部署拓扑:按可用性等级分层部署
部署上采用 Kubernetes 多命名空间隔离:gateway、core-services、integration、infra。核心服务至少 2 副本,跨可用区反亲和调度;Kafka 采用 3 副本,min.insync.replicas=2,保证单节点故障不丢消息。数据库按服务独立实例,通过读写分离和连接池控制。集成网关单独部署,配置出站白名单,只允许访问指定的院内和第三方地址。
五、一致性、幂等与可观测性
跨服务不引入分布式事务,而是采用本地事务 + 事件表 + 最终一致。每个服务在写业务数据的同时,把待发事件写入本地 outbox 表,由独立的投递器读取并发送到 Kafka,避免“数据库提交成功但事件发送失败”。消费端必须实现幂等:以 eventId 做去重,业务表加唯一约束,重复消费不产生副作用。
可观测性方面,所有服务统一输出结构化日志,日志中携带 traceId、consultationId、orderId 等业务标识;通过 OpenTelemetry 采集链路,Prometheus 采集指标,重点监控事件积压量、消费延迟、支付回调失败率、处方审方超时率。当 order.paid 事件积压超过阈值时,应优先检查配送服务消费能力,而不是盲目扩容订单服务。
综上,本节给出的集成方案可以概括为:边界按业务能力切、同步走 REST/gRPC、异步走 Kafka 领域事件、外部差异收敛到集成网关、部署按可用性分层、一致性靠 outbox + 幂等消费。这套结构既支撑当前线上诊疗的业务闭环,也为后续接入更多院区和监管接口预留了扩展点。