3. 医疗系统高可用架构原则

高可用不是某一项技术的名字,而是一组可以反复套用的设计原则。医疗系统的特殊性在于:它既要求“尽量不停”,又要求“停的时候不能乱”。挂号、医嘱、检验、影像、收费、医保结算这些业务彼此耦合,任何一处设计失当,都可能把局部故障放大成全院级事故。本节把高可用架构原则归纳为六条:冗余、隔离、无单点、故障域划分、优雅降级、快速恢复。它们不是并列的口号,而是互相约束的一组设计决策。

冗余:消除“唯一”,而不是简单复制

冗余的本质是让关键能力存在可替换的实例。医疗系统里需要冗余的对象通常分四层:计算(应用实例)、数据(数据库主从或多副本)、网络(双上行链路、双交换机)、以及依赖(HIS 与 LIS、PACS 之间的接口通道)。冗余不等于“多部署一套”,而要看它是否真正可切换。例如应用层部署 3 个实例,但三个实例都连同一个数据库单点,那么应用冗余对数据库故障毫无帮助。

冗余有两种常见形态:主备(Active-Standby)与双活/多活(Active-Active)。主备实现简单、数据一致性容易保证,但切换期间有中断;双活能同时承载流量,但要求数据层支持多写或分片,复杂度显著上升。医疗核心交易库(如挂号、医嘱)通常优先选择“一主两从 + 自动选主”,读请求分散到从库,写请求集中在主库,主库故障时由仲裁机制选出新主。

隔离:让故障“传不过去”

隔离的目标是切断故障传播路径。医疗系统中最有效的隔离手段有三类:资源隔离(不同业务使用独立线程池、连接池、容器资源配额)、部署隔离(核心交易与查询报表分集群部署)、依赖隔离(对第三方医保、支付、短信接口设置独立熔断与超时)。

一个典型反例是:报表统计与门诊挂号共用同一个数据库连接池。月末报表跑批占满连接,挂号请求排队超时,患者无法挂号。正确做法是给报表单独的数据源与限流,即使报表变慢,也不影响挂号。隔离的代价是资源利用率下降,因此要按业务重要性分级,而不是对所有模块一律隔离。

无单点:从“有没有备份”到“能不能自动接管”

无单点(No Single Point of Failure, SPOF)要求系统中不存在“它坏了整个业务就停”的组件。识别单点可以用一个简单方法:对每个组件问两个问题——“它失效时哪些业务不可用?”“它有没有可自动接管的替代者?”如果第二个问题答案是否定的,它就是单点。

医疗系统中容易被忽略的单点包括:DNS 解析、负载均衡器、时钟同步服务、证书、统一认证(SSO)、以及机房出口路由器。这些组件平时“看不见”,一旦失效往往导致全院无法登录。消除单点的手段包括:负载均衡双机 + 虚拟 IP(VIP)、DNS 多记录、NTP 多源、证书提前轮换。需要强调的是,无单点不等于零故障,而是故障时系统能自动或半自动切换到备用路径。

故障域划分:把“一起坏”变成“分开坏”

故障域(Failure Domain)是指“一个故障能同时影响的最大范围”。划分故障域的核心思想是:不要让所有关键组件共享同一个可能失效的物理或逻辑边界。常见的故障域边界有:机架、机房、可用区(AZ)、供电、网络段、数据库实例、甚至同一个中间件集群。

以某三甲医院为例,其 HIS 核心库部署在同城两个机房,采用半同步复制,主库在 A 机房,备库在 B 机房。这样,A 机房断电时,B 机房备库可提升为主库,业务在分钟级恢复。若两个库都放在同一机房同一机柜,则机柜掉电即全院停摆。故障域划分的粒度要与业务恢复目标(RTO)匹配:RTO 要求越短,故障域就要切得越细、冗余成本越高。

优雅降级:功能可以少,但不能崩

优雅降级(Graceful Degradation)指在资源不足或依赖故障时,系统主动关闭非核心功能,保留核心链路可用。医疗系统的核心链路通常是:挂号 → 就诊 → 开医嘱 → 收费 → 发药。非核心功能包括:报表、历史查询、消息推送、部分统计大屏。

降级需要提前设计“开关”和“阈值”。例如:当数据库连接池使用率超过 85% 时,自动关闭报表查询接口;当医保接口超时率超过 20% 时,切换为“先自费结算、后补医保”模式,并记录待补传队列。降级不是临时拍脑袋,而是要在配置中心预置降级策略,并经过演练验证。降级期间必须保证数据不丢、可追溯,否则会引发财务与合规问题。

快速恢复:把“恢复”当成一等公民

快速恢复包含三个可度量指标:RTO(恢复时间目标)、RPO(恢复点目标)、以及MTTR(平均修复时间)。医疗系统通常要求核心交易 RTO ≤ 5 分钟、RPO ≈ 0(不允许丢已收费数据);查询类业务可放宽到 RTO ≤ 30 分钟、RPO ≤ 5 分钟。

实现快速恢复的关键动作有:自动故障检测(健康检查 + 心跳)、自动切换(VIP 漂移、主从提升)、数据可回滚(备份 + binlog)、以及恢复演练。很多团队有备份却从未恢复过,真正故障时才发现备份不可用。建议每季度做一次“单机房断电”演练,记录实际 RTO 与 RPO,并据此调整架构。

医疗系统高可用六原则与故障域关系 故障域 A:主机房(AZ-A) 负载均衡(双机) VIP 漂移 · 健康检查 应用集群(3 实例) 挂号 · 医嘱 · 收费 主数据库(Primary) 写请求 · 半同步复制 从库(Replica) 读请求 · 报表隔离 优雅降级开关(配置中心) 连接池 > 85% 关报表 · 医保超时切自费 故障域 B:同城备机房(AZ-B) 备用负载均衡 待接管 VIP 备用应用集群 冷备 / 热备 备数据库(Standby) 可提升为主库 备份与 binlog RPO ≈ 0 快速恢复目标 核心 RTO ≤ 5 min · 查询 RTO ≤ 30 min 半同步复制 故障切换 六条原则的协同关系 冗余 多实例可替换 隔离 资源/依赖分开 无单点 自动接管 故障域划分 机架/机房/AZ 优雅降级 保核心链路 快速恢复 RTO/RPO 达标

六条原则如何协同:一个可落地的判断顺序

这六条原则不是并列清单,而是有先后依赖的。实际设计时,建议按以下顺序推进:

  1. 先划分故障域:明确哪些组件可以一起坏、哪些必须分开。故障域决定了冗余和隔离的边界。
  2. 再消除单点:在每个故障域内,找出没有替代者的组件,补齐冗余。
  3. 然后做隔离:把核心交易与非核心查询、内部依赖与外部依赖分开,防止故障传播。
  4. 接着设计降级:为每个非核心功能定义降级开关和触发阈值。
  5. 最后验证恢复:用演练测量 RTO/RPO,反向修正前面的设计。
实践提示:医疗系统的高可用设计要特别关注“数据一致性”与“业务连续性”的平衡。例如,挂号收费数据不允许丢失(RPO≈0),因此主备切换必须确认备库已同步;而报表查询可以容忍短暂不可用,适合优先降级。把业务按“可丢/不可丢、可停/不可停”分类,是落地六原则最有效的起点。
常见误区:把“部署了双机”等同于“无单点”。如果双机共享同一个存储、同一个电源、同一个交换机,它们仍处于同一故障域,故障时一起失效。判断冗余是否有效,要看它是否跨越了故障域边界。