OpenResty并发限流技术

对于一个网站来说,尽管做了多级缓存,但是,当某一时间内有大量的并发同时访问时,依旧会面临着一些问题,例如,之前上学的时候每次进行评教,都需要按照学院分批进行评教,否则就会可能导致系统崩溃;另外,限流对于防止DDOS攻击也是非常有效的一种解决方案,根据IP限制用户对网站的访问速率。这一点和实际生活中的地铁限流很类似,入站口设置一个弯弯曲曲的通道来限制入站的速率,这样,无论多少连接进来,都保证地铁内部不会过于拥挤,保证系统的正常运行。

本章内容紧接着上篇:OpenResty简介与缓存测试

Nginx限流策略有两种:

  • 根据访问速率限制,漏桶算法是该策略的具体实现,它能够有效防止了雪崩灾难的发生;
  • 根据并发连接数限制。

1. 访问速率限制

#1.定义限流策略
#限流设置:根据用户的IP进行限流,同时contentRatelLimit表示缓存空间,其大小为10m;
#另外,限制用户访问速率为每秒钟两个请求,即平均每0.5秒才能访问一次。
limit_req_zone $binary_remote_addr zone=contentRatelLimit:10m rate=2r/s;
#2.使用限流配置
#在映射地址配置中添加配置
limit_req zone=contentRatelLimit;

这里,接着以广告信息缓存为基础场景:

电商项目中的网站首页需要展示大量的广告,这些广告通常是变化频率较低的,我们可以通过OpenResty服务器的两级缓存来提高系统的并发能力。和之前不同的是,为了防止恶意攻击,现在需要对其进行限流,具体的OpenResty的配置过程如下:

#打开配置文件
vi /usr/local/openresty/nginx/conf/nginx.conf
#添加上面提到的配置
#
#重启OpenResty
/bin/systemctl restart openresty.service

在这里插入图片描述

配置完成之后有什么效果呢?之前提到过,上述配置会限制每个用户平均每0.5秒才能访问一次,如果刷新够快,就会看到下图所示的503错误页面。

在这里插入图片描述

下面我们再使用比较专业的测试工具Jmeter测试一下,这里添加15个线程来模拟并发操作这里只是简单演示,实际场景中并发量远远高于这个数量。

在这里插入图片描述

可以看到很多请求都返回了503错误,当然,将上面的限制放大错误的数量就会大大地降低,这里不做演示。

当请求到达的速率高于OpenResty配置的请求处理速率时,我们最好是将请求暂时放到一个队列中排队,而不是简单地直接拒绝访问。OpenResty缓存周期就是做这个事情的,即配置请求路径的限流规则limit_req zone=contentRatelLimit burst=4;和之前不通过的是,burst这里是用来控制总的并发数量,也就是说总并发数量最多为4,上面配置的请求处理速率是1s两个请求,当4个请求同时到达时,有两个请求将会正常访问数据,另外两个将会在队列中等待。记得重启OpenResty。

在这里插入图片描述

很明显,加了队列之后请求成功的个数比之前多了一些。将请求线程数量更改为4时,发现所有的请求都是能够正常访问。

在这里插入图片描述

上面的结果实际上已经差不多了,但是OpenResty默认是只有当一个请求处理完成之后才会从队列中取出下一个请求,为了进一步提高访问的效率,这里配置并行执行limit_req zone=contentRatelLimit burst=4 nodelay;

2. 并发连接数限制

上述配置基本上能够做到的效果是:某一用户访问数据库或后台程序的速率稳定。然而,还只是能够解决限制某一个用户的访问,而不能限制系统的总并发量,为了在遇到突然的流量时也能够保证系统的正常运行,可以进行一下的配置。

#打开配置文件
vi /usr/local/openresty/nginx/conf/nginx.conf
#根据连接的IP地址进行限制,存储内存设置为10M
limit_conn_zone $binary_remote_addr zone=addr:10m;
#添加反向代理的地址配置
location /brand {
    proxy_pass http://192.168.137.1:9300/brand;#代理地址
    limit_conn addr 2;
}
#重启OpenResty
/bin/systemctl restart openresty.service

配置反向代理之后,访问linux虚拟机时获得数据。而在配置之前,访问linux虚拟机时是失败的,这说明反向代理配置成功。

在这里插入图片描述

为了模拟并发,这里以debug的方式运行,并在对应的Controller方法内设置一个断点,保证程序暂停执行。

在这里插入图片描述

设置请求的路径为/brand,线程数为15,。最终我们看到,只有两个请求到达了后台,因为断点只需要放行两次。另外,从下图可以看出,只有两个请求执行成功。

在这里插入图片描述

上面的配置限制了每个客户端IP与服务端的连接数,那么,是否可以配置限制与虚拟服务器的连接总数。答案当然是肯定的,配置如下:

#打开配置文件
vi /usr/local/openresty/nginx/conf/nginx.conf
#根据连接的IP地址进行限制,存储内存设置为10M
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
#添加反向代理的地址配置
location /brand {
    proxy_pass http://192.168.137.1:9300/brand;
    limit_conn perip 2;#限制单个客户端IP与服务器的连接数;
    limit_conn perserver 100;#限制与虚拟服务器的总链接数。
}
#重启OpenResty
/bin/systemctl restart openresty.service

这里不做演示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值