nginx 如何做限流功能

1,328 views
Skip to first unread message

Kong Chen

unread,
May 19, 2016, 11:26:31 PM5/19/16
to openresty
我有个问题思考很久了,就是用nginx限制访问量来保证系统稳定性。例如某台机器上的nginx最高并发数是1万,但是后端系统最高只能承受1千并发,那么nginx就只给1千的流量通过,其他的9千流量引导到一个页面,该页面显示说"现在访问量大,稍后再访问"。 简单讲就是nginx 如何限流的问题。该问题非常典型,尤其像双十一,或者电商类的抢购都会面临瞬间负载过高的问题,现在大公司已经有很好的解决方案。我查过不少资料,但是没有得到答案。只好请教agentzh以及其他各位大牛了,谢谢。

YuanSheng Wang

unread,
May 20, 2016, 1:28:49 AM5/20/16
to open...@googlegroups.com
nginx 的限制连接模块limit_zone与limit_req_zone

这两个适合固定限速,比较传统和经典。

如果需要动态控制,可以考虑 https://github.com/openresty/lua-resty-limit-traffic



2016-05-20 11:26 GMT+08:00 Kong Chen <hello...@gmail.com>:
我有个问题思考很久了,就是用nginx限制访问量来保证系统稳定性。例如某台机器上的nginx最高并发数是1万,但是后端系统最高只能承受1千并发,那么nginx就只给1千的流量通过,其他的9千流量引导到一个页面,该页面显示说"现在访问量大,稍后再访问"。 简单讲就是nginx 如何限流的问题。该问题非常典型,尤其像双十一,或者电商类的抢购都会面临瞬间负载过高的问题,现在大公司已经有很好的解决方案。我查过不少资料,但是没有得到答案。只好请教agentzh以及其他各位大牛了,谢谢。

--
--
邮件来自列表“openresty”,专用于技术讨论!
订阅: 请发空白邮件到 openresty...@googlegroups.com
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+...@googlegroups.com
归档: http://groups.google.com/group/openresty
官网: http://openresty.org/
仓库: https://github.com/agentzh/ngx_openresty
教程: http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html



--

YuanSheng Wang
---------------------------------------
OpenResty lover ^_^

Guanglin Lv

unread,
May 20, 2016, 5:04:37 AM5/20/16
to openresty
自己用lua+shared DICT写一个,当然架子可以使用https://github.com/openresty/lua-resty-limit-traffic

lua-resty-limit-traffic 已经提供了两个和nginx的ngx_limit_reqngx_limit_conn类似的功能。

只是Nginx的是静态配置策略,lua-resty-limit-traffic 可以动态配置策略;

值得说明的是,这两个都是对平均速率进行控制,并不适合电商防攻击防黄牛场景;


其实电商防攻击的策略都大同小异,瞬时QPS防护,按IP防护,按UID防护,按URL防护,URL黑白名单。

再对这几类防护再进行一些联动策略控制就足够用了;


在 2016年5月20日星期五 UTC+8上午11:26:31,Kong Chen写道:

Yichun Zhang (agentzh)

unread,
May 27, 2016, 6:04:57 PM5/27/16
to openresty
Hello!

2016-05-20 2:04 GMT-07:00 Guanglin Lv:
>
> 值得说明的是,这两个都是对平均速率进行控制,并不适合电商防攻击防黄牛场景;
>

这种说法并不正确。lua-resty-limit-traffic 和 nginx 的 ngx_limit_xxx
模块并不是对平均速率进行控制,而是请求粒度的。瞬时速率提高也是不能通过的。这里使用的是 leaky bucket 算法。

Regards,
-agentzh

Guanglin Lv

unread,
Jun 1, 2016, 4:28:45 AM6/1/16
to openresty




在 2016年5月28日星期六 UTC+8上午6:04:57,agentzh写道:
 的确,瞬时速率提高是不能通过,但问题是会被提前拦截。要知道电商的抢购时期,流量是陡增的,行为和我们用ab模拟类似,瞬时增长到一个峰值,然后持续几分钟;

比如:限制是每秒最多10W请求,用lua-resty-limit-traffic 和 nginx 的 ngx_limit_xxx都会被提前拦截;基本上从第二个请求就会被拦截;

这是不符合预期的,我有参与过电商抢购的LB流量分担业务,使用shared_dict实现了这种场景的限流;

DeJiang Zhu

unread,
Jun 2, 2016, 11:02:43 AM6/2/16
to open...@googlegroups.com
Hello

在 2016年6月1日 下午4:28,Guanglin Lv <anym...@qq.com>写道: 
 的确,瞬时速率提高是不能通过,但问题是会被提前拦截。要知道电商的抢购时期,流量是陡增的,行为和我们用ab模拟类似,瞬时增长到一个峰值,然后持续几分钟;

比如:限制是每秒最多10W请求,用lua-resty-limit-traffic 和 nginx 的 ngx_limit_xxx都会被提前拦截;基本上从第二个请求就会被拦截;

这是不符合预期的,我有参与过电商抢购的LB流量分担业务,使用shared_dict实现了这种场景的限流;

你的意思是第二请求可以放过?
那是不是可以设置一个高一点的 burst 呢

Guanglin Lv

unread,
Jun 5, 2016, 11:22:39 PM6/5/16
to openresty

是的,这个指标更像是每秒允许接入的最大请求数控制;


在 2016年6月2日星期四 UTC+8下午11:02:43,doujiang写道:

Everett Li

unread,
Feb 8, 2017, 3:38:09 AM2/8/17
to openresty
有办法对整个Nginx process的进出的流量做限制吗?例如把进入总流量限制成10M。

YuanSheng Wang

unread,
Feb 10, 2017, 12:31:27 AM2/10/17
to open...@googlegroups.com

2017-02-08 16:38 GMT+08:00 Everett Li <ves...@gmail.com>:
有办法对整个Nginx process的进出的流量做限制吗?例如把进入总流量限制成10M。

貌似没有现成的,需要自己编码实现。

可以在 head filter+body filter 阶段完成流量统计,汇总后更新控制标识。
 


On Saturday, May 28, 2016 at 6:04:57 AM UTC+8, agentzh wrote:
Hello!

2016-05-20 2:04 GMT-07:00 Guanglin Lv:
>
> 值得说明的是,这两个都是对平均速率进行控制,并不适合电商防攻击防黄牛场景;
>

这种说法并不正确。lua-resty-limit-traffic 和 nginx 的 ngx_limit_xxx
模块并不是对平均速率进行控制,而是请求粒度的。瞬时速率提高也是不能通过的。这里使用的是 leaky bucket 算法。

Regards,
-agentzh

--
--
邮件来自列表“openresty”,专用于技术讨论!
订阅: 请发空白邮件到 openresty+subscribe@googlegroups.com
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+unsubscribe@googlegroups.com

xiaol...@gmail.com

unread,
Aug 2, 2017, 11:45:05 PM8/2/17
to openresty


在 2016年6月1日星期三 UTC+8下午4:28:45,Guanglin Lv写道:

--比如:限制是每秒最多10W请求,用lua-resty-limit-traffic 和 nginx 的 ngx_limit_xxx都会被提前拦截;基本上从第二个请求就会被拦截;
    请问这个从第二个请求就会被拦截是什么意思?

   --这是不符合预期的,我有参与过电商抢购的LB流量分担业务,使用shared_dict实现了这种场景的限流;
  可以分享一下思路吗?谢谢

SunYanqun

unread,
Oct 12, 2017, 12:18:16 AM10/12/17
to openresty
查过一些资料,Nginx的ngx_limit_req模块好像是这样进行限流的:
假设你将qps限制为 1000r/s,那Nginx会先算一下 1s除以1000r/s = 1r/ms
所以1ms内只允许通过一次请求,超过1次的都会被拦截(如果设置了burst,会允许一定数量的请求进入请求队列里)
实际测试中发现也基本符合这种情形

不知道我的理解是不是对的;
另外openresty中也是采用的这种方式么?
还请各位大咖指正一下。
谢谢!

在 2016年5月20日星期五 UTC+8上午11:26:31,Kong Chen写道:
我有个问题思考很久了,就是用nginx限制访问量来保证系统稳定性。例如某台机器上的nginx最高并发数是1万,但是后端系统最高只能承受1千并发,那么nginx就只给1千的流量通过,其他的9千流量引导到一个页面,该页面显示说"现在访问量大,稍后再访问"。 简单讲就是nginx 如何限流的问题。该问题非常典型,尤其像双十一,或者电商类的抢购都会面临瞬间负载过高的问题,现在大公司已经有很好的解决方案。我查过不少资料,但是没有得到答案。只好请教agentzh以及其他各位大牛了,谢谢。
Reply all
Reply to author
Forward
0 new messages