线程池Executors探究
--[[
执行过载限流策略
--]] -- 当执行限流时,Nginx 返回的状态码
err_code = local limit_config = {
user_limit = {rate = , brust = }, --用户限流维度桶设置
priority_uri_limit = { --指定 URI 限流维度桶设置
['/elis_smp_portal_dmz/do/cms/getLittleRedDotInfo'] = {rate = , brust = },
['/elis_smp_portal_dmz/do/esa/portal.msgcenter.unreadv2'] = {rate = , brust = },
['/elis_smp_portal_dmz/do/home/getUpgradeReminder'] = {rate = , brust = },
['/elis_smp_portal_dmz/do/userLogin/checkPluginVersion'] = {rate = , brust = },
['/elis_smp_portal_dmz/do/createRYMSession'] = {rate = , brust = },
['/elis_smp_portal_dmz/do/zone/queryZoneConfig'] = {rate = , brust = }
},
error_status = err_code, --请求被限流时返回状态码
nodelay = no --是否需要不延迟处理
} --定义限流策略方法名称
local limit_user_method = "limit_by_user"
local limit_uri_method = "limit_by_priority_uri" local limit_req = require "resty.limit.req" ngx.req.read_body() --过载保护策略总开关,若开关关闭,则全部策略失效
local limit_req_store = ngx.shared.limit_req_store
local overload_protection_switch = limit_req_store:get("overload_protection_switch")
if (overload_protection_switch ~= nil and overload_protection_switch == "N") then
ngx.log(ngx.INFO, "nginx limit strategy has been shutdown.")
return
end -- 获取当前请求 URI
local cur_uri = ngx.var.uri -- 执行过载操作
local is_in_black_list = limit_req_store:get("black_list:"..cur_uri)
local is_rejected_uri = reject_uri_tab["rejected"..cur_uri]
if (is_in_black_list ~= nil or is_rejected_uri ~= nil) then
-- 拦截比例,默认全部拦截
local request_limit_percent = limit_req_store:get("reject_request_percent")
if request_limit_percent == nil then
request_limit_percent =
end
local random_num = math.random()
if random_num <= tonumber(request_limit_percent) then
ngx.log(ngx.ERR,"nginx limit strategy current uri=",cur_uri," has been rejected.")
ngx.exit(ngx.HTTP_FORBIDDEN)
end
end -- 执行限流策略,入参:key 和 commit,commit 默认为 true
local function execute_limit_strategy(lim, key, commit, method)
-- 请求流入,如果你的请求需要被延迟则返回delay>0
local delay, err = lim:incoming(key, commit)
if (not delay and err == "rejected") then
ngx.log(ngx.ERR, "nginx limit strategy: ",method,", key: ", key, " request rate was exceeded, current request was rejected.")
ngx.exit(limit_config.error_status)
end -- 根据需要决定延迟或者不延迟处理
if delay > then
if limit_config.nodelay then
-- 直接突发处理
-- ngx.log(ngx.ERR, "nginx limit strategy: ", method, ", key: ", key, " request rate was exceeded, current request was rejected. delay")
-- ngx.exit(error_status)
else
--延迟处理
ngx.sleep(delay)
end
end
end -- 获取限流策略的共享内存
local function get_shared_dict(shared_dict_name, rate, burst)
local limit_shared_dict, err = limit_req.new(shared_dict_name, rate, burst)
if not limit_shared_dict then --没定义共享字典
ngx.log(ngx.ERR, "Nginx limit shared dict:", shared_dict_name, " has not been set.")
ngx.exit(error_status)
end
return limit_shared_dict
end -- 初始化 URL 限流策略 table
local uri_limit_tab = {} local user_lim if limit_config == nil then
ngx.log(ngx.ERR, "nginx request limit has no config info.")
return
else
local user_limit_config = limit_config.user_limit
ngx.log(ngx.DEBUG,"limit config user rate:", user_limit_config.rate, ", brust:", user_limit_config.brust)
user_lim = get_shared_dict("limit_req_store",user_limit_config.rate, user_limit_config.brust)
local priority_uri_limit_config = limit_config.priority_uri_limit
for key, value in pairs(priority_uri_limit_config) do
local rate = value.rate
local brust = value.brust
ngx.log(ngx.DEBUG,"limit config uri:", key, ", rate:", rate,", brust:",brust)
local lim = get_shared_dict("limit_req_store",rate,brust)
uri_limit_tab[key]=lim
end
end -- 执行指定 URI 限流策略
if uri_limit_tab[cur_uri] ~= nil then
execute_limit_strategy(uri_limit_tab[cur_uri], cur_uri , true , limit_uri_method)
end -- 获取客户端请求 IP
local remote_ip = ngx.var.remote_addr
local user_id
local device_id
local key_by_user -- 获取用户ID 或 设备号
local request_method = ngx.var.request_method
if "GET" == request_method then
user_id = ngx.req.get_uri_args()["uid"]
device_id = ngx.req.get_uri_args()["deviceId"]
ngx.log(ngx.DEBUG, "nginx request limit module GET parameter user_id: ",user_id, " header:",device_id)
elseif "POST" == request_method then
-- 获取请求头信息,如果缺少请求头信息判断,遇到上传文件操作时,会引起ngx.req.get_post_args()操作异常。
local receive_headers = ngx.req.get_headers()
local body_data = ngx.req.get_body_data()
if not body_data or (receive_headers["content-type"] ~= nil and string.sub(receive_headers["content-type"],,) == "multipart/form-data;") then
ngx.log(ngx.WARN,"nginx request limit module uri: ",cur_uri, " header:",receive_headers["content-type"],", body data:",body_data)
return
end
user_id = ngx.req.get_post_args()['uid'];
device_id = ngx.req.get_post_args()['deviceId'];
ngx.log(ngx.DEBUG, "nginx request limit module POST parameter user_id: ",user_id, " device_id:",device_id)
end -- 调试日志
ngx.log(ngx.ERR, "nginx request limit module cur_uri:",cur_uri, ", user_id: ",user_id) if (user_id ~= nil or device_id ~= nil) then
if user_id ~= nil then
key_by_user = user_id
else
key_by_user = device_id
end
execute_limit_strategy(user_lim,key_by_user..":"..remote_ip, true, limit_user_method)
end
线程池Executors探究的更多相关文章
- 线程池-Executors
合理使用线程池能够带来三个好处 减少创建和销毁线程上所花的时间以及系统资源的开销 提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行 提高线程的客观理性.线程是稀缺资源,如果无限制的创 ...
- Java实现“睡排序”——线程池Executors的使用
前提 之前在知乎上看见一个有意思的排序算法——睡排序. 睡排序最早好像是4chan上一个用户用shell脚本实现的: 算法思想简洁明了:利用进程的sleep来实现 越大的数字越迟输出. 虽然像2L说的 ...
- 线程池——Executors
一 Executor框架 为了更好地控制多线程,JDK提供了一套线程框架Executor,帮助开发人员有效的进行线程控制.它们都在java.util.concurrent包中,是JDK并发包的核心.其 ...
- java 线程之executors线程池
一.线程池的作用 平时的业务中,如果要使用多线程,那么我们会在业务开始前创建线程,业务结束后,销毁线程.但是对于业务来说,线程的创建和销毁是与业务本身无关的,只关心线程所执行的任务.因此希望把尽可能多 ...
- 为什么阿里巴巴要禁用Executors创建线程池?
作者:何甜甜在吗 juejin.im/post/5dc41c165188257bad4d9e69 看阿里巴巴开发手册并发编程这块有一条:线程池不允许使用Executors去创建,而是通过ThreadP ...
- 为什么尽量不要使用Executors创建线程池
看阿里巴巴开发手册并发编程这块有一条:线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,通过源码分析禁用的原因. 线程池的优点 管理一组工作线程,通过线程池 ...
- [转]为什么阿里巴巴要禁用Executors创建线程池?
作者:何甜甜在吗 链接:https://juejin.im/post/5dc41c165188257bad4d9e69 来源:掘金 看阿里巴巴开发手册并发编程这块有一条:线程池不允许使用Executo ...
- java核心知识点学习----重点学习线程池ThreadPool
线程池是多线程学习中需要重点掌握的. 系统启动一个新线程的成本是比较高的,因为它涉及与操作系统交互.在这种情形下,使用线程池可以很好的提高性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考 ...
- Android学习笔记之ExecutorService线程池的应用....
PS:转眼间就开学了...都不知道这个假期到底是怎么过去的.... 学习内容: ExecutorService线程池的应用... 1.如何创建线程池... 2.调用线程池的方法,获取线程执行完毕后的结 ...
随机推荐
- Redis 集群解决方案比较
调研比较了三个Redis集群的解决方案: 系统 贡献者 是否官方Redis实现 编程语言 Twemproxy Twitter 是 C Redis Cluster Redis官方 是 C Codis 豌 ...
- mx51的三个framebuffer,mxc_ipuv3_fb.c分析
转载:http://blog.csdn.net/jack_a8/article/details/43309169 mx51支持三个framebuffer:fb0, fb1, fb2 /dev/grap ...
- PHP mktime函数获取今天的开始和结束时间戳
php 获取今日.昨日.上周.本月的起始时间戳和结束时间戳的方法,主要使用到了 php 的时间函数 mktime(). mktime函数用法如下:mktime(hour,minute,second,m ...
- Android使用Apache的httpmime包post提交数据
/** * 启动线程向服务器post提交数据 */ public void upLoadPic(final Intent data) { ToastUtils.toastWithMessage(get ...
- JavaScript中prompt()函数的用法。
定义和用法 prompt()方法用于显示一个带有提示信息,并且用户可以输入的对话框. 语法 prompt(text,defaultText); 参数 描述 text 可选.要在对话框中显示的提示信息( ...
- SQLite学习网址
http://www.runoob.com/sqlite/sqlite-data-types.html
- CocoaPods 报错 [!] The dependency `JSONModel (~> 1.2.0)` is not used in any concrete target.
当用CocoaPods pod install 时出现了下面的错误时: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; col ...
- thinkphp 注册验证
遇到用户注册等情况时,如果等用户输入所有信息,点击注册按钮提交后,再验证输入是否正确,体验很不好,而且很浪费用户的时间,增加注册成本,这里提供一个例子,演示了怎么使用ajax进行单步验证,使用thin ...
- placeholder的美化
之前在介绍HTML5的placeholder属性时,曾实现了一些页面例子让大家参考,但这些例子里的背景文字都是灰色的,样式很单一,其实它们可以做的更好看.CSS3里提供了专门的规则属性来美化用plac ...
- js---DOM元素节点
创建新的 HTML 元素如需向 HTML DOM 添加新元素,您必须首先创建该元素(元素节点),然后向一个已存在的元素追加该元素. 实例1: <!DOCTYPE html> <htm ...