高可用笔记
Keepalived
一个开源的工具,基于VRRP协议,Virtual Router Redundancy Protocol,即虚拟路由冗余协议。多台服务器安装keepalived后,通过虚拟ip可以实现自动主备切换而保持虚拟ip不变,在阿里云中,可以申请虚拟ip(HaVip)。
双主热备
解决主从架构下,从节点不处理任何请求而导致的资源浪费问题。
DNS配置2个虚拟ip,两台机器都安装keepalived并互相配置为主备,这样两台机器都能处理请求并且故障后能够自动实现切换。
几种load balancer比较
F5
硬件load balancer
LVS
Linux virtual server. 工作在网络4层,基于VRRP协议
HAProxy
支持两种代理模式:TCP(四层)和HTTP(七层),支持虚拟主机。
Nginx
工作在网络7层,可以针对http应用做一些分流的策略。1.10.X版本之后引入了对四层tcp转发的支持,默认:不开启。
概念
- 冷备: 备用机房只用于备份数据,不提供服务
- 热备:备用机房部署着同样的全套应用和数据库,切换之后,需要人工启动备用机房的服务
- 同城双活:两个机房的ip都加入DNS,同时提供服务
- 两地三中心:两个城市,3个机房,其中 2 个机房在同一个城市,并且同时提供服务,第 3 个机房部署在异地,只做数据灾备。
- 异地双活:异地两个机房的数据库都是主库,而且双向同步。
- RTO: Recovery time objective, 事故发生后多久能恢复
- RPO: Recovery point objective, 事故发生后最多可以允许丢失多久的数据
限流算法
计数器
计算某个时间段内请求个数,再判断是否超过一个阈值,进而决定是否拒绝请求。
固定窗口计数器
存在问题:在某个时刻激增的请求进来,将无法限流。比如规定一分钟只能处理100个请求,如果在第前面59秒一个请求都没有,在最后一秒的时候突然来了100个请求,并且在下一秒也突然进来 100个请求,则在这2秒内就接收到了200个请求且限流器没有拒绝,这就可能超过了下游系统的处理能力了。
滑动窗口计数器
将一个固定窗口划分为很小的小窗口,每隔一小段时间就滑动一次,这样能够缓存固定窗口计数器算法无法应对激增请求的问题,但是依旧在小窗口内部存在该问题。
漏桶算法
设计一个固定容量的桶(队列),请求来了就放进桶里面,超过桶容量就丢弃,再以固定速率从桶中取出请求以进行处理。漏桶算法与计数器算法最大的区别:
- 计数器算法下,处理请求的速率是不确定性的,以真实场景为准
- 漏桶算法下,送给下游系统的请求的速率是固定的,可以实现削峰的作用
存在的问题:如果后端处理能力提升,需要修改出水速率,则需要修改配置,上线。这就不灵活了。另外,不同请求的处理速度是不同的,而漏桶算法却使用固定速率从桶中处理请求,这就不一致。
令牌桶算法
设计一个固定容量的桶(队列),并以固定的速率往里面添加令牌,满了就不添加。当请求来了之后,就拿一个令牌,并继续交给后端处理,如果拿不到令牌,则拒绝。Guava的RateLimitter用的就是令牌桶算法。
如何解决激增请求?
比如规定一分钟只能处理100个请求,如果在第前面59秒一个请求都没有,在最后一秒的时候突然来了100个请求,则这100个请求可以拿到令牌并处理完成,若下一秒又来了100个请求,由于令牌还没那么快产生,则有可能拒绝掉其中99个请求,就实现了对激增请求的限流。
如何动态适应后端处理能力
由于放行的速率是没有限制的,只要桶里面还有令牌,后端系统处理完有空闲了,就可以继续处理。
实现
Redission的RRateLimitter可以方便实现分布式的限流器,再自己写个annotation就可以实现API级别的限流。
如果要使用单机限流,则resilience4j非常好用,可以使用现成的annotation放在函数上面,只要添加合适的配置就可以。