等啊等,盼啊盼,11月份终于来了,在11月01日的00:00分,你可以清空掉所有的预售订单,还有购买商家所推出的限时折扣如前十五分钟购买5折等,买的人很开心,商家也很开心。然而程序员们不开心了,提供应用服务的团队、提供监控服务的团队、提供基础设施服务的团队都绷着一根神经,生怕是自己这一环挂了,导致整个服务链路崩塌,最后被老板祭天了。
而今天我们给大家带来了一剂良药,那便是针对高并发的解决方案。所谓高并发指的是请求突然大量地袭来,比如双十一整点抢购这种,服务器正常情况下的流量请求是50000个,双十一来了500000个,这叫人服务器咋扛得住嘛。而应对高并发,我们也有三大法宝:缓存、降级、限流。所谓缓存就是把用户最常访问的数据放起来,用户请求来时,先访问缓存中的数据,如果缓存没有命中,再访问后端数据,一定程度缓解了高并发。所谓降级就是非核心服务不让访问了、核心服务返回上一级页面,用户请求来时,最重要的页面就是支付,其余的积分啥的都不重要,因此集中资源给到支付模块使用。所谓限流就是限制流量,原来可以支撑50000个请求,突然来了500000个请求,限制只有60000个请求可以正常访问,其余的都暂时先访问不了。
在限流中,常用的算法有两个:漏桶算法、令牌桶算法。漏桶算法就像是一个漏掉的水桶一样,水桶底部是空的,无论上面倒多少水下来,漏出去的水都是固定的。漏桶算法如下所示,在流量场景中,BurstyFlow代表流量,在0-2秒内突然来了12Mbps的突发流量,中间2-7秒没有流量过来,7-10秒是平稳的流量,可以看到数据不是平稳的,通过漏桶可以将数据变得平稳,每秒出去的流量是3Mbps。
它的伪代码实现如下,我们定义了一个漏桶的demo,定义了桶容量、水流出速度、当前水量、时间,通过水量与容量的差来看看是否继续加水(也就是流量是否还可以继续进来),如果小于总容量,则请求可以继续进来,如果大于则请求无法进来了。
另一个限流算法是令牌桶算法,它与漏桶算法的区别在于允许流量一定程度的改变,不像漏桶算法始终是固定的流量。那么什么是令牌桶算法呢?
令牌桶算法就是在桶里面有一定令牌,我们可以往桶里不断的去添加令牌,请求到来时拿到令牌就可以进入下一阶段去处理了,拿不到令牌的请求就会处于等待状态。
它的伪代码实现如下,我们定义了令牌桶的大小,令牌放入的速度,当前的令牌量,执行算法不断的去添加令牌,如果大于桶容量则停止增加,反之则继续增加令牌,如果当前令牌数小于1,则不发放令牌,拒绝请求,如果大于1则发放令牌,处理请求。
讲完了两个限流算法后,我们看看在业务中是如何去实现限流。在微服务架构下,我们把一个大的应用分为多个微服务,服务与服务之间通过远程调用进行通信,服务与数据库之间通过数据库连接池进行连接,服务内部则通过接口相互调用来实现功能。因此整个限流的层次也包含应用层级限制、资源层级限制、接口层级限制。
在应用层级的限制,主要是总并发数的限制,如果超过了阈值则不响应用户请求,比如tomcat自带的设置,如MaxConnector设置最大连接数、MaxThreads设置最大线程数。在资源层级的限制,可以使用数据库连接池、线程池等技术,超过线程池数则不能连接数据库,无法响应服务。在接口层级可以对核心接口的调用进行限制,单位时间内(如每秒/每分钟/每小时)最大允许调用量,超过之后则调用失败。表层的限制策略都是依托于深层的算法,而这算法可以是漏桶或者令牌桶算法。
无论是漏桶算法还是令牌桶算法,都只是工具,最终要服务于业务,通过原理与伪代码的结合,你明白如何做实现了嘛?赶紧在你的业务中码起来吧。无论是直接面对用户的业务部门,还是服务于业务的基础设施部门,都必须要对高并发谨慎起来,做好缓存降级限流措施。
网友评论