就秒杀接口来讲,当访问频率或者并发请求超过其承受范围的时候,这时候咱们就要考虑限流来保证接口的可用性,以防止非预期的请求对系统压力过大而引发的系统瘫痪。一般的策略就是拒绝多余的访问,或者让多余的访问排队等待服务。下面是几种常见的限流技术算法
1、限流算法
经常使用的限流算法有:令牌桶,漏桶
1.令牌桶
令牌桶算法是网络流量整形和速率限制中最常使用的一种算法。典型状况下,令牌桶算法用来控制发送到网络上的数据的数目,并容许突发数据的发送。tomcat
在秒杀活动中,用户的请求速率是不固定的,这里咱们假定为10r/s,令牌按照5个每秒的速率放入令牌桶,桶中最多存放20个令牌。仔细想一想,是否是总有那么一部分请求被丢弃。
2.漏桶
漏桶算法的主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。漏桶算法提供了一种机制,经过它,突发流量能够被整形以便为网络提供一个稳定的流量服务器
2、应用限流
Tomcat
在Tomcat容器中,咱们能够经过自定义线程池,配置最大链接数,请求处理队列等参数来达到限流的目的。
Tomcat默认使用自带的链接池,这里咱们也能够自定义实现,打开/conf/server.xml文件,在Connector以前配置一个线程池:网络
name:共享线程池的名字。这是Connector为了共享线程池要引用的名字,该名字必须惟一。默认值:None;
namePrefix:在JVM上,每一个运行线程均可以有一个name 字符串。这一属性为线程池中每一个线程的name字符串设置了一个前缀,Tomcat将把线程号追加到这一前缀的后面。默认值:tomcat-exec-;
maxThreads:该线程池能够容纳的最大线程数。默认值:200;
maxIdleTime:在Tomcat关闭一个空闲线程以前,容许空闲线程持续的时间(以毫秒为单位)。只有当前活跃的线程数大于minSpareThread的值,才会关闭空闲线程。默认值:60000(一分钟)。
minSpareThreads:Tomcat应该始终打开的最小不活跃线程数。默认值:25。
配置Connectorsession
• executor:表示使用该参数值对应的线程池;
• minProcessors:服务器启动时建立的处理请求的线程数;
• maxProcessors:最大能够建立的处理请求的线程数;
• acceptCount:指定当全部可使用的处理请求的线程数都被使用时,能够放处处理队列中的请求数,超过这个数的请求将不予处理。并发
3、API限流
秒杀活动中,接口的请求量会是平时的数百倍甚至数千倍,从而有可能致使接口不可用,并引起连锁反应致使整个系统崩溃,甚至有可能会影响到其它服务。
那么如何应对这种忽然事件呢?这里咱们采用开源工具包guava提供的限流工具类RateLimiter进行API限流,该类基于"令牌桶算法",开箱即用。分布式
自定义定义注解工具
自定义切面spa
4、分布式限流线程
Nginx
如何使用Nginx实现基本的限流,好比单个IP限制每秒访问50次。经过Nginx限流模块,咱们能够设置一旦并发链接数超过咱们的设置,将返回503错误给客户端。
配置说明
imit_conn_zone
是针对每一个IP定义一个存储session状态的容器。这个示例中定义了一个100m的容器,按照32bytes/session,能够处理3200000个session。
limit_rate 300k;
对每一个链接限速300k. 注意,这里是对链接限速,而不是对IP限速。若是一个IP容许两个并发链接,那么这个IP就是限速limit_rate×2。
burst=5;这至关于桶的大小,若是某个请求超过了系统处理速度,会被放入桶中,等待被处理。若是桶满了,那么抱歉,请求直接返回503,客户端获得一个服务器忙的响应。若是系统处理请求的速度比较慢,桶里的请求也不能一直待在里面,若是超过必定时间,也是会被直接退回,返回服务器忙的响应。