高可用架构浅谈(week 11)

每个系统的可用性是不一样的。像我们平时使用的微信、淘宝、抖音,好像是一直可用,随时可用,但其实这并不是说它们就是100%一直可用的。而像其他一些小的网站或应用,经常会碰到系统宕机不可用。那么我们如何度量一个系统的可用性?系统不可用是怎么造成的?怎样才能提高系统的可用性?

可用性度量

 我们用数字9来表示一个系统的可用性,比方说QQ的可用性是4个9,也就是一年中QQ有99.99%的时间是可用的。对一个系统来说,2个9是基本可用,3个9是较高可用,4个9就属于具有自动恢复能力的高可用了。5个9是极高可用,这个有点理想化,因为这个只允许一年内有大概五分钟的不可用时间,这个是需要运气的。

 为什么5个9的极高可用需要运气?大厂也都不保证能达到?究其原因,就是可以造成系统故障的因素太多了。

影响系统高可用的因素

影响系统高可用的主要有软件bug、硬件故障、系统发布、并发压力、网络攻击、外部灾难。

软件bug,没有哪个系统是没有bug的,只不过严重不同而已。很多大的系统故障,往往来源于一些不太大的软件bug。

硬件故障,对一个大的网络系统,往往有大量的服务器组成。随着服务器数量的增加,硬件故障几率就越来越高,进而不可避免。

系统发布,系统发布新版本时需要暂停现系统使用,然后再进行升级。有时看到一个网站“正在维护/升级中”,就是这种情况。当然还有更糟糕的新版本发布失败造成的系统不可用。

并发压力,在资源有限的情况下,如果出现了超过系统预计支持的高并发,会影响系统可用性,严重会引起系统崩溃。

网络攻击,如果发生网络攻击,系统可用性肯定会受到影响。

外部灾难,像机房发生火灾地震等灾难。

面对这么多不可避免的因素,我们应该如何应对,来保证系统的高可用呢?

高可用系统的架构

高可用架构的思路主要有三个,

  1. 应对软件故障时的隔离策略,避免一个bug引起级联传导效应影响其他服务;
  2. 应对硬件故障的冗余备份策略,在部分硬件出问题后还可以靠启用备份来继续提供服务;
  3. 应对高并发的自我保护策略,在超出资源承载能力的高并发下仅对部分请求提供服务。

应对软件故障,要在系统软件设计上解耦,应用面向对象设计、领域驱动设计等技术来设计高内聚、低耦合的组件和微服务等。解耦可以使模块职责更清晰、相互依赖关系更明确更少。

应对软件故障,要在架构上多用异步,反应式编程、异步通信网络编程、事件驱动异步架构等等,这些方式可以去除模块间直接依赖调用,减小软件故障的级联传导效应。

应对软件故障,还要在系统部署时隔离,业务子系统间隔离、生产者与消费者隔离、虚拟机与容器隔离,这些隔离进一步把软件故障局限在小范围内而不影响其他的服务。

应对硬件故障,对服务器来说主要是使用集群技术,对数据库则主要是冗余复制、提供多备份。无论服务器集群、还是数据库复制,一个保证发生硬件故障后不影响系统使用的关键技术是失效转移,也就是一个服务器故障失效后,如何快速把请求都转到备份服务器上。做到失效转移,服务需是无状态的,不然不能凭空转移到另一个服务器上。设计无状态服务,是失效转移的一个前提要求。

应对由于外部灾难产生的硬件故障,主要的技术是异地多活,也就是在不同的地方建立数据中心,一个地方遭遇灾难,其他地方可以保证继续使用。这个的难点是如何保证多数据中心间的数据一致性。

应该高并发,主要的方式有熔断、限流、降级。

  • 熔断是指阻止请求进入存在故障的服务,避免该服务耗尽资源或引起级联失效;
  • 限流是指系统随机拒绝一些请求,从而保证系统现有资源不被压垮、可以给接收的请求提供服务。限流是保证部分用户的可用性。
  • 降级是指关闭系统部分非核心功能,以节省系统资源用于核心功能,保证系统核心功能的高可用性。

当然,除了上述三个主要方面外,设计一个高可用系统还需要考虑其他因素,像网络通信的随机失败等。应对这些因素,高可用系统一般会在实现时加入请求重试功能,以减少随机网络失败的因素。服务本身要时幂等的,以保证被多次调用时不产生副作用。

高可用系统的运维

影响系统高可用性的还有一个重要因素,系统发布、运维。一个系统上线新功能、发布新版本时是最容易出现问题,引起系统不可用的时刻。所以如何去除(或者减少)这个阶段的故障,是需要一套不同于系统架构的策略。主要的策略有:

  1. 新版本上线前:自动化测试、预发布验证。预发布验证是指将新版本发布到一个只有内部人员才能访问到的生产环境上去,由内部人员先行测试验证,通过后再部署到生产环境的其他服务器上去。
  2. 新版本上线中:自动化部署、热升级、灰度发布。热升级是指保证正常对外提供服务的基础上一个服务器一个服务器升级,到达最终全部升级。灰度发布是指,先升级部分服务器,过一段时间没发现问题,然后再升级一部分,这样慢慢一部分一部分的升级,直至全部升级。这样在过程中发现任何问题,都只影响部分服务器。
  3. 上线后:监控系统、报警系统、自动失效转移、自动扩容、自动限流。系统一定要由监控、报警,这是高可用的最后一道防线。监控系统可以根据硬件故障情况自动失效转移、根据资源使用情况自动扩容、根据请求负载自动限流;在所有这些措施都失效的情况下最后报警系统还可以通知运维人员或开发人员系统现状,以减少不可用时间。

总结

保持系统高可用涉及到的技术众多,有架构的也有运维的,但是高可用本身更多是一个非技术问题。一个系统究竟需要做到多么高可用,完全是根据系统的业务决定的。设计高可用系统时要注意投入产出比,无需一味追求高可用而浪费过多人力物力。设定可用性指标时,要目标明确,知道系统在特定环境下的具体问题具体风险,设计简单明了的方案来达成目标。

原文地址:https://www.cnblogs.com/susy/p/14094993.html