专业剑 : 应对高并发的方法

缓存,限流,降级,消息队列,扩容,大数据量(清理和分箱),负载均衡。

 

缓存

包括分布式缓存和本地缓存,比如Guava,Redis,Hazelcast,减少数据库访问的瓶颈。

通过消息队列,实现服务之间的解耦。把同步操作改变为异步操作。

 

限流

主要应对高并发访问下对单个微服务的冲击。(Guava,Redis,RateLimiter,网关)。限流应该结合服务扩容使用。

限流的目的是为了保护系统不被大量请求冲垮,通过限制请求的速度来保护系统。在电商的秒杀活动中,限流是必不可少的一个环节。

限流的方式,可以在Nginx的层面限流,也可以在应用中限流,比如在API网关中。

限流可以分为单点限流和集群限流,区分在于使用本地缓存还是分布式缓存。

还可以根据实施的环节和粒度,区分为网关限流,服务限流,实例限流,接口限流。

 

常见的限流算法有:令牌桶、漏桶。计数器也可以进行限流实现。

一、令牌桶

令牌桶存放固定容量上限的令牌。

一个定时服务按照固定速率往桶里面添加令牌,直到上限。该速率控制了并发量和流量。

当一个请求到达时,从桶里面取走一个令牌。如果获取不到则等待或者放弃。

 

二、漏桶

请求可以是任意的速率到达(超出漏桶容量的直接抛弃),但是只能以固定的速率被消费。

应对突发的并发请求的场景不够好,因为出口的流速是匀速的。

 

限流和txw-typhon的区别:

限流的思路是,一个米缸,按照一定的速率往米缸里面投米,比如每秒一粒米,并为米缸设置最大上限。当有老鼠(请求)过来时,先看米缸里面有没有米,如果有,一个老鼠拿走一粒米,如果没有,则老鼠等待。如果超过一定时间(超时时间),则等待的老鼠饿死(返回超时)。可以看出来,老鼠等待多长时间被饿死主要由调用方设置的超时时间决定。

Typhon不同,typhon按照一定的速率计数,比如每秒10粒米。当有老鼠过来时,在1秒钟之内,前面10只老鼠拿走米,第11只老鼠开始,typhon会主动毙掉(返回请求失败),直到该时间周期结束。

txw-typhon类似于接口限流,txw-typhon支持单点和集群。比如txw-typhon类似于令牌桶算法,有一个固定的速率。

 

https://www.jianshu.com/p/5d4fe4b2a726

 

 

 

服务降级

在高并发下暂停非主要业务,释放资源,维持主要业务。(Docker+k8s,网关)。

服务降级的方式有多种,最好的方式通过docker实现。当需要对某个服务进行降级,直接将这个服务所有的容器停掉,需要恢复的时候重启容器。

也可以在API网关层处理。当需要对某个服务进行降级,前端过来的对这个服务的请求网关直接拒绝掉,不再往内部转发。比如通过zuul+云配置实现动态服务降级。

从请求参数中获取serviceId。查询配置,该serviceId是否在需要降级的服务列表。如果是,直接返回该服务已被降级。

 

灰度发布

灰度发布(金丝雀发布),是指在服务的两个新旧版本之间,实现平滑过渡的一种发布方式。在其上,可以实现A/B testing,即让一部分用户继续使用产品特性A,一部分用户开始使用新的产品特性B,测试用户对产品特性B的反馈。如果符合预期,则扩大用户范围,直到把所有用户迁移到B。如果有问题,则及时调整修复问题,限制其影响度。

灰度发布的原理是对请求进行分流(用户分流或IP分流),让指定的用户(或请求来源IP)访问指定的新版本的服务(实例),而其他用户还是访问当前版本的服务。

灰度发布在系统需要发布新功能的版本时用到。当前所有服务实例的版本为版本V1。

1、首先将机器A的服务开始发布新版本V2,发布过程前,需要先隔离所有的请求。

2、发布结束后,满足条件的请求分流到该机器A。

对请求的分流可以在API网关中统一处理。

1、 将要做灰度发布的服务设置成灰度发布状态,从正常服务列表中移除。

2、 获取当前请求的用户ID,如果是灰度发布用户,从可用服务中获取对应的灰度发布的用户。

 

扩容和缩容,(Docker+k8s)

 

 

负载均衡

通过分流应对高并发下的访问和调用。可以通过中间层(F5,Nginx,Openresty,NodeJS),也可以做在调用端(Ribbon,服务注册和发现)。

 

分流

比如对入口进行分流,比如移动端(细分Android端和IOS端),网页端,API调用端等。因为不同端的技术栈不同。也方便统计不同端的流量。

 

还有对接口的分流,把高并发下重载的接口分离出来,作为单独的服务,单独实现扩容。