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,并据此调整架构。
六条原则如何协同:一个可落地的判断顺序
这六条原则不是并列清单,而是有先后依赖的。实际设计时,建议按以下顺序推进:
- 先划分故障域:明确哪些组件可以一起坏、哪些必须分开。故障域决定了冗余和隔离的边界。
- 再消除单点:在每个故障域内,找出没有替代者的组件,补齐冗余。
- 然后做隔离:把核心交易与非核心查询、内部依赖与外部依赖分开,防止故障传播。
- 接着设计降级:为每个非核心功能定义降级开关和触发阈值。
- 最后验证恢复:用演练测量 RTO/RPO,反向修正前面的设计。