【源码】openresty 限流
小结:
1、在连接环节计数,有清零环节
有3个参量
max
burst
unit_delay
https://github.com/openresty/lua-resty-limit-traffic/blob/master/README.md
-- limit the requests under 200 req/sec with a burst of 100 req/sec,
-- that is, we delay requests under 300 req/sec and above 200
-- req/sec, and reject any requests exceeding 300 req/sec.
-- the following call must be per-request.
-- here we use the remote (IP) address as the limiting key
local key = ngx.var.binary_remote_addr
local delay, err = lim:incoming(key, true)
if not delay then
if err == "rejected" then
return ngx.exit(503)
end
ngx.log(ngx.ERR, "failed to limit req: ", err)
return ngx.exit(500)
end
if delay >= 0.001 then
-- the 2nd return value holds the number of excess requests
-- per second for the specified key. for example, number 31
-- means the current request rate is at 231 req/sec for the
-- specified key.
local excess = err
-- the request exceeding the 200 req/sec but below 300 req/sec,
-- so we intentionally delay it here a bit to conform to the
-- 200 req/sec rate.
ngx.sleep(delay)
end
delay
the delay in seconds (the caller should sleep before processing the current request)
https://github.com/openresty/lua-resty-limit-traffic/blob/master/lib/resty/limit/count.md
syntax: delay, err = obj:incoming(key, commit)
Fires a new request incoming event and calculates the delay needed (if any) for the current request upon the specified key or whether the user should reject it immediately.
This method accepts the following arguments:
key is the user specified key to limit the rate.
For example, one can use the host name (or server zone) as the key so that we limit rate per host name. Otherwise, we can also use the authorization header value as the key so that we can set a rate for individual user.
Please note that this module does not prefix nor suffix the user key so it is the user's responsibility to ensure the key is unique in the lua_shared_dict shm zone).
commit is a boolean value. If set to true, the object will actually record the event in the shm zone backing the current object; otherwise it would just be a "dry run" (which is the default).
The return values depend on the following cases:
If the request does not exceed the count value specified in the new method, then this method returns 0 as the delay and the remaining count of allowed requests at the current time (as the 2nd return value).
If the request exceeds the count limit specified in the new method then this method returns nil and the error string "rejected".
If an error occurred (like failures when accessing the lua_shared_dict shm zone backing the current object), then this method returns nil and a string describing the error.
在nginx粒度度限制,各个worker
The limiting works on the granularity of an individual NGINX server instance (including all its worker processes). Thanks to the shm mechanism; we can share state cheaply across all the workers in a single NGINX server instance.
限流是nginx粒度的,不是woker粒度的,需分析量化对qps的降低的影响程度
清零
https://github.com/openresty/lua-resty-limit-traffic/blob/master/lib/resty/limit/req.lua
-- we do not handle changing rate values specifically. the excess value
-- can get automatically adjusted by the following formula with new rate
-- values rather quickly anyway.
excess = max(tonumber(rec.excess) - rate * abs(elapsed) / 1000 + 1000,0)
if conn > max + self.burst then
conn, err = dict:incr(key, -1)
if not conn then
return nil, err
end
return nil, "rejected"
end
self.committed = true
https://github.com/openresty/lua-resty-limit-traffic/blob/master/lib/resty/limit/conn.lua
function _M.incoming(self, key, commit)
local dict = self.dict
local max = self.max self.committed = false local conn, err
if commit then
conn, err = dict:incr(key, 1, 0)
if not conn then
return nil, err
end if conn > max + self.burst then
conn, err = dict:incr(key, -1)
if not conn then
return nil, err
end
return nil, "rejected"
end
self.committed = true else
conn = (dict:get(key) or 0) + 1
if conn > max + self.burst then
return nil, "rejected"
end
end if conn > max then
-- make the exessive connections wait
return self.unit_delay * floor((conn - 1) / max), conn
end -- we return a 0 delay by default
return 0, conn
end function _M.is_committed(self)
return self.committed
end function _M.leaving(self, key, req_latency)
assert(key)
local dict = self.dict local conn, err = dict:incr(key, -1)
if not conn then
return nil, err
end if req_latency then
local unit_delay = self.unit_delay
self.unit_delay = (req_latency + unit_delay) / 2
end return conn
end
【源码】openresty 限流的更多相关文章
- Sentinel 源码分析-限流原理
1. git clone senetinel 源码到本地,切换到release1.8分支 2. 找到FlowQpsDemo.java, 根据sentinel自带的案例来学习sentinel的原理 3. ...
- Spark Streaming源码解读之流数据不断接收全生命周期彻底研究和思考
本期内容 : 数据接收架构设计模式 数据接收源码彻底研究 一.Spark Streaming数据接收设计模式 Spark Streaming接收数据也相似MVC架构: 1. Mode相当于Rece ...
- .27-浅析webpack源码之事件流make(2)
上一节跑到了NormalModuleFactory模块,调用了原型方法create后,依次触发了before-rsolve.factory.resolver事件流,这节从resolver事件流开始讲. ...
- .26-浅析webpack源码之事件流make(1)
compilation事件流中,依然只是针对细节步骤做事件流注入,代码流程如图: // apply => this-compilation // apply => compilation ...
- .24-浅析webpack源码之事件流compilation(2)
下一个compilation来源于以下代码: compiler.apply(new EntryOptionPlugin()); compiler.applyPluginsBailResult(&quo ...
- .23-浅析webpack源码之事件流compilation(1)
正式开始跑编译,依次解析,首先是: compiler.apply( new JsonpTemplatePlugin(options.output), // start new FunctionModu ...
- .22-浅析webpack源码之事件流compilation总览
呃,终于到了这地方-- newCompilation(params) { // ... this.applyPlugins("this-compilation", compilat ...
- .21-浅析webpack源码之事件流this-compilation
上一节生成Compilation实例后,添加了一些属性,随后触发this-compilation事件流,如下: Compiler.prototype.newCompilation = (params) ...
- .34-浅析webpack源码之事件流make(3)
新年好呀~过个年光打游戏,function都写不顺溜了. 上一节的代码到这里了: // NormalModuleFactory的resolver事件流 this.plugin("resolv ...
随机推荐
- centos7创建共享文件夹
0.检查是否已经安装samba rpm -qi samba 1.未安装,安装samba, 如果已安装,请忽略: yum -y install samba samba-client 2.共享一个目录,使 ...
- mysql的2种备份mysqldump 和 Xtrabackup
mysqldump备份方式 备份 mysqldump -uroot -p 数据库名 > 备份的文件名 恢复(先关闭数据库) mysql -uroot -p 数据库名 < 备份的文件名 Xt ...
- Java中实现图片的上传
这边直接存放在c盘的指定目录,在property中指定了一个目录 没有花时间写用户操作的上传页面,直接用swagger2插件,可以上传 默认图片大小超过1mb就不可以上传,可以如下更改 server. ...
- 关于zsh-autosuggestions插件导致粘贴内容很慢的问题
zsh开启autosuggestions 插件的时候,在终端中粘贴大量的内容的时候,会粘贴的很慢,基本上是一个字符一个字符的粘贴的. 解决方案 在.zshrc文件中配置以下内容: # This spe ...
- linux网络编程之socket编程(十三)
今天继续学习socket编程,从今天起开始学习UDP,具体内容如下: ①.无连接 UDP协议它内部并没有维护端到端的一些连接状态,这跟TCP是不同的,TCP是基于连接的,而在连接的时候是需要进行三次握 ...
- P1352 没有上司的舞会[树形dp]
题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...
- idea中Git配置,Git的非命令操作
1.更换Git账户 在idea中File-->Settings-->Appearance-->System Settings-->Passwords,选择不保存密码(Do no ...
- 0019SpringBoot使用异步任务(多线程)与定时任务
SpringBoot开启异步任务只需要两步配置: 1.在主类上加上注解@EnableAsync开启异步功能 2.在service层的方法上加上注解@Async指定调用方法时是异步的 SpringBoo ...
- web上常见的攻击方式及简单的防御方法
SQL注入最常见的攻击方式,所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露VIP会员密码大 ...
- Nginx入门(二)——双机热备
upstream backend { server ; server backup; } server { listen ; server_name localhost; #charset koi8- ...