11.5 高可用:提升系统可用性的架构方案
用什么样的架构,提升系统的可用性?
1.解耦
高内聚,低耦合的组件设计原则--6 种原则
面向对象基本设计原则--5 大原则
面向对象设计模式--23 种设计模式
领域驱动建模--
2.隔离
业务与子系统隔离
微服务与中台架构
生产者与消费者隔离
虚拟机与容器隔离
3.异步
多线程编程
反应式编程
异步通信网络编程
事件驱动异步架构
4.备份
集群设计
数据库复制
CAP 原理
5.Failover(失效转移)
数据库主主失效转移
负载均衡失效转移
如何确认失效,需要转移?doris。 zookeeper 选取主服务器。
设计无状态的服务
6.幂等
服务重复调用和调用一次产生的结果是相同的,即服务的幂等性。交易操作:通过交易编号等信息调用有效性校验,只有有效的操作才能继续执行。
7.事务补偿
传统事务的 ACID
原子性(Atomicity),一致性(Consistency),隔离性(Isolation,又称独立性),持久性(Durability)
分布式事务的 BASE:
基本可用(Basic Availablity),软状态(Soft-state),最终一致性(Eventual consistency)
事务补偿:通过执行业务逻辑逆向操作,使事务回滚到事务前状态。
8.重试
远程服务可能会由于线程阻塞,垃圾回收或者网络抖动,而无法及时返还响应,调用者可以通过重试的方式修复单次调用的故障。
上游调用者超时时间要大于下游调用者超时时间之和。
9.熔断
当某个服务出现故障,响应延迟或者失败率增加,继续调用这个服务会导致调用者请求阻塞,资源消耗增加,进而出现服务及联失效,这种情况下使用断路器阻断对故障服务的调用。
断路器的三种状态:关闭,打开,半开。
10.限流
高并发场景下,如果系统的访问量超过了系统的承受能力,可以通过限流对系统进行保护。
限流是指对进入系统的用户请求进行流量限制,如果访问量超过了系统的最大处理能力,
就会丢弃一部分用户请求,保证整个系统可用,保证大部分用户时可以访问系统的。
这样,虽然有一部分用户请求被丢弃,产生了部分不可用,但是好过整个系统崩溃,所有的用户都不可用要好。
限流的几种算法:
计数器算法(固定窗口,滑动窗口)
令牌桶算法
漏桶算法
10.1 计数器(固定窗口)算法
使用计数器在周期内累加访问次数,当达到设定的限流值时,触发限流策略。下一个周期开始时,清零,重新计数。
固定算法的临界点问题:假设 1min 内服务器的负载能力为 100,因此一个周期的访问量限制在 100,
然而在第一个周期的最后 5 秒和下一个周期开始 5 秒的时间段内,分别涌入 100 的访问量,虽然没有超出每个周期的限制量,
但是整体上 10 秒内已经达到 200 的访问量,已经远远超过服务器的负载能力。
10.2 计数器(滑动窗口)算法
将时间周期分为 N 个小周期,分别记录每个小周期内访问次数,并且根据时间滑动删除过期的小周期。
假设时间周期为 1min,将 1min 再分为 2 个小周期,统计每个小周期的访问数量,则可以看到,第一个时间周期内,访问数量为 75,
第二个时间周期内,第二个时间周期内,访问数量 1 百,超过 100 的访问则被限流。
10.3 令牌桶算法
以固定的速度向令牌桶增加令牌,知道令牌桶满,请求到达时向令牌桶请求令牌,如果获取到令牌则通过请求,否则触发限流策略。
10.4 漏桶算法
访问请求到达时直接放入漏桶,如果当前容量已经达到限流值,则丢弃请求。漏桶以固定的速率释放访问请求,知道漏桶为空。
11.降级
有一些系统功能是非核心的,但是它也给系统产生了非常大的压力,比如说在电商系统中有确认收货功能,即便我们不去确认收货,系统也会超时自动确认收货。
但实际上“确认收货”是个非常重要的操作,因为它会对数据库产生很大的压力:他要更改订单状态,完成支付确认,评价等一系列操作。
如果再系统高并发的时候去完成这些操作,那么会对系统雪上加霜,是系统的处理能力更加恶化。
解决办法就是在系统高并发的时候,比如向淘宝双 11 的时候,当前可能这个系统都处于一种极限的高并发访问压力下,这个时候可以将确认收货,评价这些非核心功能关闭,
将宝贵的系统资源留下来,给正在购物的人,让他们完成交易。
12.异地多活
如果整个数据中心都不可用,比如说:数据中心所在城市地震,机房火灾或者停电,这样的话,不管系统设计的多么高可用,系统依然是不可用的。
为了解决这个问题,同时也为了提供系统的处理能力和改善用户体验,很多大型互联网应用采用了异地多活的多机房架构策略,
也就是说数据中心分布在不同地点的机房里,这些机房都可以对外提供服务,用户可以连接任意一个机房访问,这样每个机房都可以提供完整的系统服务,
即使某个机房不可使用,依然保持可用。
异地多活的难点是数据一致。
评论