一 部署方案
系统的部署方案将直接影响系统的可用性;线上环境一般都通过多实例方案确保系统可用性。多实例方案是通过多个备份来保障可用性,即便部分实例失效时,也不会导致整体服务不可用。
1. 主从方案
一般中间件都是用此方案,当主不可用时,让从服务器迅速承接主的工作,或者迅速从从服务器中选举出一个新的主。以下是常用中间件主从方案:
1) RocketMQ
所有消息都发到master服务器,slave服务器保持和master服务器同步;master失效时,消息不能继续发送到master服务器对应的队列,但可以消费slave服务器的数据。
2) Kafka
集群内部维护着ISR列表,将所有与leader同步的服务器放在ISR列表中,当leader失效时,从ISR中选举出一个leader服务器来替代失效的leader。
3) Zookeeper
Zookeeper内置选举算法,通过ZAB协议,当leader失效时快速从所有follower中选举出一个leader服务器,所有flower与leader保持同步。
4) Redis集群
Redis集群有多中部署方式,每种方式的主从方案都有所不同,基本上都是master不可用时,从slave中选举出一个master,来替代失效的master。
5) Mysql集群
Slave保持和master同步,所有写操作都到master库中,可以从slave读取数据。Mysql不提供主从方案,一般需要配合数据库中间件一起使用。
2. 多实例方案
一般而言,生产环境中,公司的服务实例都是多实例的,防止单点故障。
1) 无状态部署方案
所有服务器内部不包括状态信息,当服务能力不足时,通过增加服务器的方式水平扩展服务能力;一台服务器不可用,也可以将流量切到其他的服务器。
业务系统一般都是用此方案,系统内部无状态,水平扩展非常方便。
2) 有状态部署方案
服务器内部有状态,需要通过某些方式确定每个服务器的状态。例如上面讨论的RocketMQ、Kafka、Zookeeper等,服务器内部都有主或从标识,鉴于这些中间件的优秀设计,他们都可以通过水平扩展主服务器,可以线性的提升服务能力。
有些场景中,需要将业务系统设计成有状态的,在方案设计和部署时,需要考虑特别注意,以免系统的水平扩展能力受限。
二 隔离技术
隔离技术的核心是防止压力、异常等在多系统间传导,导致服务不稳定甚至彻底不可用。常见的处理手段有:
1. 业务隔离
营销活动一般变化块,每次活动各不相同,为了防止对常规业务、核心业务产生影响,可以从业务上就区分开,让他们独立运行、互不干扰。
2. 数据隔离
营销活动的db、缓存、消息和核心业务隔离开,避免营销流量较大时,核心业务无法使用。
3. 进程隔离/系统隔离
营销活动单独拆分为一个系统,这样可以避免开发、运行过程中相互影响。
4. 线程隔离
为不同的任务创建不同的线程池,避免争抢相同的资源。
5. 集群、机房隔离
例如:异地多活方案。
6. 读写隔离
例如:db写主库,主、从都可读。
7. 动静分离
静态内容通过cdn缓存,动态内容通过ajax请求,可以极大的降低带宽。
8. 热点/爬虫隔离
识别并将这些流量导引到单独集群或者直接拦截掉。
9. 资源隔离
防止因为抢夺服务器资源而相互影响。
10. 故障隔离
应规避故障向其他系统传导,例如当交易有问题时,商品页面应该能够正常展示,不受影响。
例如,如果常规业务和营销活动使用的是相同的DB实例,当营销活动的流量过大时,有可能影响到其他业务的正常进行;营销活动的需求往往变化频繁,如果放在同一个系统中,可能会相互影响,甚至影响核心业务的稳定;等等。
三 限流技术
限流技术的核心是在流量超过系统承受极限时,以牺牲部分请求为代价,保证大多数请求正常的一种手段;另外,限流也可以用来防刷、
1. 处理机制
1) 拒绝服务
如:定向到错误页或告知资源没有了。
2) 排队或等待
如:比如秒杀、评论、下单。
3) 降级
如返回兜底数据或默认数据,如商品详情页库存默认有货。
2. 限流手段
常见使用场景有:限制远程接口调用速率、限制MQ的消费速率;通过网络连接数、网络流量、CPU或内存负载等来限流。
1) 限制总并发数
如:设置数据库连接池、线程池的最大并发数。
2) 限制瞬时并发数
如nginx的limit_conn模块,用来限制瞬时并发连接数。
3) 限制时间窗口内的平均速率
如Guava的RateLimiter、nginx的limit_req模块,限制每秒的平均速率
3. 限流算法
相关博客见《限流方案》,地址:https://yq.aliyun.com/articles/278092
1) 计数器
有时候我们控制最大并发数、累计调用量,如每个ip、用户调用接口的频率,使用分布是缓存的计数器可以很方便的帮我们实现此需求。
计数器实现的限流器可以有多个变种,可以是某一个维度的限流,如以ip、用户、接口、系统等维度;也可以在这些维度上加上时间窗口,如:每分钟某个ip下的调用量不能超过1000,等等。
2) 令牌桶
令牌桶是按照固定速率往桶中添加令牌,请求是否被处理需要看桶中令牌是否足够,当令牌数减为零时则拒绝新的请求。
令牌桶限制的是平均流入速率,允许突发请求,只要有令牌就可以处理,支持一次拿多个个令牌,并允许一定程度突发流量。
3) 漏桶
漏桶则是按照常量固定速率流出请求,流入请求速率任意,当流入的请求数累积到漏桶容量时,则新流入的请求被拒绝。
漏桶限制的是常量流出速率,即流出速率是一个固定常量值,比如都是1的速率流出,而不能一次是1,下次又是2,从而平滑突发流入速率。
4) 令牌桶 VS 漏桶
令牌桶允许一定程度的突发,而漏桶主要目的是平滑流入速率;两个算法实现可以一样,但是方向是相反的,对于相同的参数得到的限流效果是一样的。
4. 限流种类
1) 接入层限流
限流总并发/连接/请求数,如tomcat中的 Connector配置。
限流总资源数;例如db最大连接池数目。
2) 应用级限流
限流某个接口的总并发/请求数
限流某个接口的时间窗请求数
3) 分布式限流
基于分布式缓存实现。
在nginx层通过openresty通过计数器、令牌桶、漏桶等算法,可以限制请求到达后端服务器。
在业务系统中,收到请求以后根据计数器、令牌桶、漏桶等算法限制请求。
四 降级技术
降级是利用有限资源,保障系统核心功能高可用的一种有损的架构方法。
1. 降级预案设计原则
候选方案要简洁,不要把系统复杂化。
考虑降级的收益和影响成本,设计收益率最高的方案。
降级预案需要定期review:业务复杂度变更;系统重要级别提升。
2. 降级手段
1) 针对上游的降级
梳理上游系统等级;设计限流降级方案和开关。
常见手段有:限流降级;按照用户质量,将高风险用户、爬虫优先降级;按照上游系统等级,将低级别系统的资源调度到高级别系统。
2) 针对下游的降级
梳理依赖的影响程度和范围;设计候选降级方案和开关。
五 熔断技术
Hystrix是目前使用的最多的一个熔断器,其他熔断器的原理和Hystrix也基本类似,所以就不过多讨论。下图是Hystrix的工作原理图,更多详细内容可以参考Hystrix文档。