高可用性(HA)是指尽可能减少系统无法提供服务的时间,追求系统持续稳定运行,提供服务的目标。理论上,如果系统始终能够保持工作状态并对外提供服务,那么系统的可用性可以达到100%。大多数公司并不会如此乐观地预期,因此提出如三个九、四个九的目标,即全年系统可用性达到99.9%或99.99%。
那么如何确保系统的高可用性呢?核心思想在于防止单点故障并增加冗余机制。我们先来了解一下传统架构中的潜在风险点。
在传统架构中,每个环节都是单点的话,会存在诸多风险。任何一个环节的故障都可能导致整个系统瘫痪。例如,缓存失效可能会导致数据库被拖垮。为了解决这个问题,我们需要为系统的每个部分增加冗余。
对于客户端到Web应用的部分,我们可以增加Web应用并引入反向代理层,即负载均衡器如Nginx。只部署一个Nginx可能形成单点故障。为了解决这个问题,我们可以部署多台Nginx,其中一台作为主服务器提供服务,其他作为备用服务器。通过keepalived等方式监控主服务器的状态,一旦主服务器发生故障无法提供服务时,可以动态将虚拟IP切换到备用服务器上,以确保服务继续运行。
在负载均衡到Web应用的部分,我们可以搭建多个Web应用并在负载均衡器如Nginx中配置多个Web端的地址。可以监控多个Web端的存活状态,当发现某台应用挂掉时,Nginx将不再将请求分发到该机器上。
在Web应用到服务层的部分,有多种实现方式。例如,服务层前端可以挂负载均衡,或者采用客户端内的负载均衡。这里,Web应用作为客户端配置多个服务层的地址。每次请求都按照一定的规则选择连接来访问下游服务,并使用service-connection-pool监控服务层应用的存活状态。还可以使用服务注册发现的方式,只有提供服务的应用才会出现在注册中心。
对于服务层到缓存的部分,缓存的存在本身就是一种冗余。缓存层也可以通过集群来解决高可用问题。以Redis为例,它支持主从同步,并且有sentinel哨兵机制来进行存活检测。
数据库一般会采用主从架构来保证高可用。对于数据库的读操作,通常使用db-connection-pool来保证自动故障转移;而对于写操作,则需要结合keepalived和虚拟IP进行自动切换。
除了上述措施外,还有一些策略可以在系统资源有限的情况下保证系统的高可用性。例如限流、降级、熔断和灰度发布。
限流是指限制系统的并发请求数量或访问人数,当超过一定阈值时,对超出部分的请求进行限制。常见的限流算法包括漏桶和令牌桶。
降级是指在面临高并发或故障时,为了保障核心功能的稳定运行,牺牲一些非核心的业务功能。
熔断是指当服务链路中的某个服务响应时间过长或失败时,进行服务的降级并熔断该节点服务的调用,快速返回错误信息。虽然熔断策略在实际应用中并不常见,但其作为一种保障机制仍然具有重要意义。