限流的分类:
1)合法性验证限流:比如验证码、IP 黑名单等,这些手段可以有效的防止恶意攻击和爬虫采集;
2)容器限流:比如 Tomcat、Nginx 等限流手段,其中 Tomcat 可以设置最大线程数(maxThreads),当并发超过最大线程数会排队等待执行;而Nginx提供了两种限流手段:一是控制速率,二是控制并发连接数;
3)服务端限流:比如我们在服务器端通过限流算法实现限流。
6种具体的实现限流的手段:
1)Tomcat 使用 maxThreads来实现限流。
2)Nginx的limit_req_zone和 burst来实现速率限流。
3)Nginx的limit_conn_zone和 limit_conn两个指令控制并发连接的总数。
4)时间窗口算法借助 Redis的有序集合可以实现。
5)漏桶算法可以使用Redis-Cell来实现。
6)令牌算法可以解决Google的guava包来实现。
需要注意的是借助Redis实现的限流方案可用于分布式系统,而guava实现的限流只能应用于单机环境。如果你觉得服务器端限流麻烦,可以在不改任何代码的情况下直接使用容器限流(Nginx或Tomcat),但前提是能满足项目中的业务需求。
Tomcat限流
Tomcat 8.5 版本的最大线程数在 conf/server.xml 配置中,如下所示:
其中 maxThreads 就是 Tomcat 的最大线程数,当请求的并发大于此值(maxThreads)时,请求就会排队执行,这样就完成了限流的目的。
注意:
maxThreads 的值可以适当的调大一些,Tomcat默认为 150(Tomcat 版本 8.5),但这个值也不是越大越好,要看具体的服务器配置,需要注意的是每开启一个线程需要耗用 1MB 的 JVM 内存空间用于作为线程栈之用,并且线程越多 GC 的负担也越重。
最后需要注意一下,操作系统对于进程中的线程数有一定的限制,Windows 每个进程中的线程数不允许超过 2000,Linux 每个进程中的线程数不允许超过 1000。
Nginx 限流
Nginx 提供了两种限流方法:一种是控制速率,另一种是控制并发连接数。
控制速率
我们需要使用 limit_req_zone 用来限制单位时间内的请求数,即速率限制,示例配置如下:
上面配置的意思是,限制单个IP访问的速度为 2r/s,因为Nginx的限流统计是基于毫秒的,我们设置的速度是 2r/s,转换一下就是500毫秒内单个IP只允许通过1个请求,从501ms开始才允许通过第2个请求。
我们使用单IP在10ms内发并发送了6个请求的执行结果如下图:
从以上结果可以看出它的执行符合我们的预期,只有 1 个执行成功了,其他的 5 个被拒绝了(第 2 个在 501ms 才会被正常执行)。
控制速率优化版
上面的速率控制虽然很精准但是在生产环境未免太苛刻了,实际情况下我们应该控制一个IP单位总时间内的总访问次数,而不是像上面那样精确到毫秒,我们可以使用 burst 关键字开启此设置,配置如下:
burst=4意思是每个IP最多允许4个突发请求,单个IP在10ms内发送6次请求的结果如下图:
从以上结果可以看出,有1个请求被立即处理了,4个请求被放到 burst 队列里排队执行了,另外1个请求被拒绝了。
控制并发数
利用 limit_conn_zone 和 limit_conn 两个指令即可控制并发数,示例配置如下:
其中 limit_conn perip 10 表示限制单个 IP 同时最多能持有 10 个连接;limit_conn perserver 100 表示 server 同时能处理并发连接的总数为 100 个。
注意:只有当 request header 被后端处理后,这个连接才进行计数。
好了,今天先介绍这三种方式,服务端限流的三种方案下回讲。
架构师小跟班,技术类综合网站,是本站长出于个人爱好,搭建的纯公益性质的博客网站,旨在为各位站长,程序员、学生提供免费的开发软件,视频教程,系统源码,网站模板等。
本站做过多次优化,解决了网站打开慢,谷歌浏览器报不安全提示等问题。
本站每周会有多次更新,内容完全免费,尤其是系统源码、毕业设计、视频教程等,没有任何套路,请大胆收藏和推荐。
但请粉丝们注意:
本站部分内容是站长从网络搜集所得,没有著作权,请勿用于商业用途,请下载后24小时内删除。谢谢合作!
领取专属 10元无门槛券
私享最新 技术干货