语雀系统崩溃了,并且经过8个多小时才恢复,估计语雀的小伙伴们已经哭晕在厕所里了。
本次稳定性故障再次给架构师敲响警钟:系统高可用一直是架构的重点,它涉及到系统的方方面面,并且是一件持续性的长期工作。
故障起因是“因为运维工具bug,导致存储服务器被下线”。这个味道似曾相识,记得阿里云的一次稳定性故障,也是因为运维bug,将服务器实例下线而产生大面积服务不可用,最后云阿里云CTO不得不自降一级,真是惨不忍睹啊。我也谈一下如何设计高可用系统,从系统设计理念、系统架构的原则、常用技术手段、相关制度保证几个方面简单谈一下如何架构高可用系统。
1、高可用系统设计的理念
(1)面向“失败“的架构
一个分布式系统,需要多个子系统协同才能提供完整的服务或者功能。但是“分布式“的架构,决定了各个系统的服务无法保证100%可靠。所以在架构与设计时,就应该考虑外部依赖服务失败了的情况。架构师要根据可用性要求进行取舍,或者提供如何应对失败的解决方案。
(2)怀疑一切
不要抱有侥幸心理。查找并发现一切可能发生的风险,怀疑他们,并提供相应的预案。尤其是一些强依赖的系统:例如底层中间件、上游主数据等。“黑天鹅事件“一般就出现在这些系统中,而且影响都是致命的。
(3)系统的短板决定了可用性的上限
大家都知道木桶理论,一个木桶可以盛纳的水量取决于最短的那个木板(如下图)。系统可用性也是这样,也许99%的地方都考虑了高可用,但是唯独一个地方漏掉了。那么这个1%的点就成了可用性的“阿喀琉斯之踵“,导致系统可用性极低。在本实例中,架构、设计、编码、测试都做好了,结果把运维工具给忘了,导致数据丢失,所有一切都归零了。因此,要保证系统高可用,需要全方面查找系统的短板,然后修正提高。
2、高可用系统架构的原则
(1)“n+1“的原则。
集群中实例数必须是>=2的,并且方便扩展。只有这样才可以保证系统部分实例不可用时,服务照旧可用,运维人员可以及时进行实例扩展。例如:生产环境中应用的实例数不能低于2个,数据库实例至少是1主1从2个实例。对于高可用系统则需要考虑分布式多活、数据灾备等多中技术手段。对于金融或者资产管理类的系统,一般采用“两地三中心”的部署架构。
(2)可监控可预警
高可用系统都有好的监控体系,不仅可以从多个层面监控系统运行状态,提供可视化的监控工具,而且可以及时报警,方便开发人员第一时间发现问题(先于用户),并提供线索与工具,方便其解决问题。减少系统问题影响范围与持续时间,杜绝其升级成为高可用故障。
(3)可隔离的原则
允许对问题系统进行隔离。当发生问题时,可以将问题束缚在一定的范围内。例如:为核心用户或者关键服务提供单独的资源保障,防止其受到问题系统的干扰。saas产品一般会为高价值用户提供专属环境,并且在IT资源与稳定性保障方面会给与特殊照顾,保证核心用户不会因为公有环境宕机而影响其业务。
(4)可快恢。
强调一个“快”字。在本次语雀系统故障中,数据无法快恢是导致服务长时间不可用的直接原因。从描述中可以看出,语雀应该是做了数据冷备,但不是热备,而且数据量较大,所以数据恢复时间太长,导致服务长时间不可用。
记得在故障处理时,曾经提出过1-5-10的原则,就是1 分钟发现问题, 5 分钟介入问题修复,10 分钟故障恢复。如果能够快速解决故障,故障等级有可能降低
3、监控系统的建设
梳理关键业务流程,监控关键服务,并提供不同级别的预警。一般我们会建立4个监控大盘:
(1)系统监控大盘。监控底层系统运行状态,包括cpu、网络、内存、硬盘的的相关状态信息
(2)应用监控大盘。监控应用系统的运行状态,例如jvm状态、服务rt,服务成功率等。
(3)业务监控大盘。与业务相关的稳定性指标,例如电商系统中的下单成功率
(4)DB监控大盘。这个是企业级系统必须有的大盘,据经验所得,企业级系统50%以上的问题是由DB问题(而且大多数是慢sql)引起的。
4、风险与预案
系统风险多种多样,需要我们识别风险并针对系统风险提前制定好预案。预案需要方便执行,最好是“一点就通“,因为当系统出现故障时,容易手忙脚乱,所以建议有一个好的预案执行工具。
5、全链路压测与灰度环境
全链路压测为我们提供了可以提前预演的可能性。一个好的全链路压测平台,可以最大限度的模拟真实的业务场景,提前暴露系统可用性问题,极大地提高系统可用性。当然,全链路压测平台建设成本也比较大,涉及的系统也很多,包括网络、应用、中间件、数据存储、安全等,并且被压测系统也需要进行适当的改造。
企业级系统在链路压测上可以进行适当的简化,仅仅针对关键链路与核心服务进行压测,通过QPS不断地“摸高“,评估标准产品的吞吐量,量化系统性能,发现可用性瓶颈。
灰度环境是高可用系统的标配, 通过灰度发布可以让小批量用户进行优先试用;不仅仅可以验证功能,万一出现问题也可以控制影响范围。 “无灰度不发布“应该是高可用系统的变更基本准则。
6、相关制度保证
(1)变更管理
为了保证生产系统的稳定性,必须严格控制变更。建立变更审批流程,保证所有的变更都是经过专家check与验证的。
(2)运维管控
运维自动化带来的问题。部分系统运维人员与设计开发人员是两拨人,运维工具/脚本没有经过严格的测试与验证,运维人员对内部执行逻辑不清晰,正常操作流程反而导致系统故障。运维工具意在提效,结果却成为系统杀手。
在平时的开发管理中,大家对系统功能测试都有足够的重视,但是运维工具的测试反而没有那么重视,因此导致系统故障。在本案中,运维升级工具bug导致数据存储服务器被下线,真的让人很无语。
(3)故障管理
建立故障管理制度。包括故障类型定义、故障等级定义,故障扣减分标准;完善故障应对机制,保证对应的处理人能在第一时间迅速解决问题。故障发生后需要及时进行复盘与定责,杜绝故障再次发生。
我是令涛,专注系统架构,尤其是大型企业系统的架构与设计。欢迎与我沟通与交流,我的微信号:x18958102865
转载请注明出处