影像云平台提升高可用性实战简述

/ 2评 / 29

背景

在新公司刚接手负责了一个旧项目,此项目是医疗云影像相关,是将医院传统胶片替换为数字影像云胶片,患者将不需要打印传统胶片,扫码二维码可查看到数字影像。 由于此项目的特点,大部分情况性能要求不高,但对于系统的可用性、安全性、数据存储量的要求较高。
由于历史的原因,原有核心技术人员在之前都已陆续离职,有很多技术上的选型初衷已无法得知。 但目前我们系统面临的情况是,隔三差五由医院或用户反馈,我们系统某些功能不可用,有些功能是正常。 往往在这时技术处于十分被动的情况,我们连系统的真实可用性无法得知,通常忙于紧急救火。

目标

系统核心业务流程高可用提升至4个9 .
不可出现医院或用户比我们更早发现系统核心功能不可用。

识别复杂度

业务架构复杂度:涉及到约50个微服务、C++影像路由处理前置机、数据节点私有云部署。
项目背景复杂度:5年多持续升级旧项目、原核心技术人员已离职、无可追溯的技术架构设计文档。
识别提升可用性关键项,面对庞杂的系统,每一个环节可能都会出现不可用的情况,如何找到关键项及以较低改造成本去提升系统可用性。

除了以上考虑点还需要结合成本、可靠性、安全性、合规性、兼容性等约束及限制去综合评估,特别是安全性及合规性方面, 对应医院内部的影像数据,必须要符合国家三级等保要求及医院信息科内部合规性要求。

原有架构分析

通过现有系统部分服务调用关系概要图【下图】分析,服务间调用虽然有逻辑上分类,但每个请求都必须经过较多服务。
根据定律,只要中间的服务越多,不可用性的可能性越大,且未包括微服务技术设施部分。

因公司保密机制,图片已做模糊化处理

收集以往将近两个月医院或用户反馈的系统不可用性的排查原因,根本性的原因各有千秋,但总归而言就是单微服务可用性差,造成无法给其他服务或外界进行调用,最终造成整个服务都不可用。

提升可用性阶段一方案

经过几轮的技术会议评审,结合业务实际情况,架构重构方案无法一步到位,采取分阶段推行。
1、提升单服务的可用性,夯实微服务基础设施,阶段一需完成。
2、部分服务不可用原因由代码编写不合理造成,则长期进行代码小范围重构。

重构设计指导性原则

1、合适原则

项目重构时考虑引入中间件或框架,不应直接采取业界最高水平,需要团队成员能完全掌握的。 不应出现只会HelloWord的层级,就直接引入到生产级别项目里。


2、演化原则

结合成本、时间、团队规模,无法将架构重构一步到位,明确需要阶段性的目标,也需要清楚知道长久往后架构调整的方向。


3、简单原则

原项目已经足够复杂,复杂度不单单局限在技术纬度,重构需要让现有项目变得更为简单,依赖项应该更少。

方案简要说明

1、微服务基础设施上云

将公共云服务所依赖的基础设施上云,特别核心重点基础设施,如数据库、缓存、MQ、负载均衡等。
而非核心基础实施,则结合成本考虑,会采取部分上云的考虑。

因公司保密机制,图片已做模糊化处理

2、升级服务治理

单体系统拆分为多服务后,最为重要就是服务治理方案是如何的。
现项目服务之间采取gRpc远程通信框架,可能因当初引入版本较低也一直无更新,此版本gRpc不支持负载均衡,只是一个纯粹端到端的远程通信框架。

服务调用示意图

因需要实现服务高可用,核心就是需要冗余,必须将服务A、B等服务部署多份,但由于现有gRpc版本不支持负载均衡功能。 我们当时提出多种解决方案进行详细评估,其中有一些代表性的:

1、服务之间增加Nginx进行反向代理实现负载均衡

优点:开发成本最小,可快速满足负载均衡的诉求。
缺点:带来的运维复杂度与服务治理难度都提升不少,这已偏离我们的重构指导原则了。


2、按照官方gRpc负载平衡的建议,使用one-arm负载均衡器在服务器实例之间分配流量

优点:开发成本中等,符合gRpc生态
缺点:团队现有技术能力未必能完全掌握gRpc,gRpc实现负载均衡未必最佳。


为什么说gRpc实现负载均衡在理论未必最佳?

gRpc使用http/2在同一连接和双工流中复用许多请求,其中的重点是:gRpc 的链接是粘性,当客户端连接到服务端时,相同的连接将尽可能长时间地保留以重复利用。
而我们又是希望服务调用时可根据不同策略去执行,如采取最常用的轮询方式,是否就损失掉gRpc一部分的优势?
另外gRpc还有个优势则是跨平台,使用protocol buffers作为接口描述语言(IDL)以及底层的信息交换格式。


以上两个方案,在于我们当时而言都不是最好的解决方案,而发现现有影像云平台产品虽然有少量C++项目,但与其交互也是采取http协议,并非gRpc。
平衡各种利弊,最终决定采取:去gRpc化,引入Dubbo
优点缺点各有很多,让我做出这样决定,最重要的考虑因素为:团队对技术使用一定需要可控,当时团队对gRpc只停留在使用阶段无大规模生产经验,这就造成在未来出现核心问题时无法在短时间内解决。

3、对系统了如指掌,增强监控机制

抛开所有监控的理论,我们要做到比用户更早知道系统是否出问题?出了什么问题?问题的症状是什么?
唯有增加多维度的监控。 原有系统已用采用Zabbix监控一些系统基础指标,比如:CPU、硬盘、内存之类的。
但只是监控系统基础指标远远满足不了我们现有的要求,监控通常有4种方式:

  1. Logging
  2. Tracing
  3. Metrics
  4. Healthchecks

而在监控体系中,我们又可分为:

  1. 系统层监控
  2. 应用层监控
  3. 业务层监控
  4. 用户端监控

至少我们需要在系统层、应用层、业务层做好相关监控,才能满足我们能比用户更早发现系统是否出现问题及把问题给解决掉。


针对于监控的解决方案:

系统层监控
我们大量服务已经上云,使用阿里云监控体系已经可以很完备监控起ECS、MySQL、Redis、MQ等等指标,并第一时间预警给我们。

应用层与应用层监控
采用了自建Prometheus Grafana + 阿里云健康监控 + 阿里云链路 + 阿里云日志,形成了Logging + Tracing + Metrics + Healthchecks完整的闭环。

为什么不采用阿里云Prometheus?
和阿里云技术沟通后,目前阿里云监控至少有两个产品线,且不统一。收费的Prometheus,按照我们现在服务数来计算,成本过高。


特别需强调的业务数据监控,我们是会定时接收医院PACS推送过来的影像数据,正常的情况下在工作时间,检查数都是稳定的。 如果是发现5分钟没有新的检查数推送过来,我们可第一时间发送预警信息并附带相关Debug数据。

总结

此次只是记录了,当时为期约3个月的提升高可用性的架构重构历程,还需要持续提升系统其他方面的高可用性。
我认为高可用架构,也不能一次性到位,而是需要在业务、时间、成本、收益之间取之平衡。
在系统前期,不需要过度迷信可用性一定需要达到99.999%或99.9999%,但我们至少需要确保是,任何服务不可单一节点,系统出现问题我们技术人员永远都要第一时间知道且快速解决,在此过程中,我们不断提升系统的多方面的可用性。

  1. GTZ说道:

    架构图可以私发参考下吗?

  2. Spring说道:

    我公司一直都在用gRpc没有觉得存在什么问题,这样替换代价太大了

发表评论

您的电子邮箱地址不会被公开。