公司打算把 apache nginx 全换成 openresty!所以查下资料。。研究下
http://house.chaobaihe.net 潮白房产网http://house.chaobaihe.net 潮白房产网
openresty是以ngx_lua模块为核心的nginx套件,详见春哥项目 http://openresty.org/ 。
http://house.chaobaihe.net 潮白房产网
本文章来源于潮白家园网: http://www.chaobaihe.netnginx充分利用epoll,擅长处理高并发;而lua作为天生的胶水语言,开发简单。两者结合起来,可以很容易实现以前PHP几乎不能完成的应用。 最近在某游戏激活码抢号专题中,有个场景并发较高,可虑采用lua做PHP应用层的防火墙。 抢号专题,前期评估预计2万人参加,并发峰值按20k来扛,网页前端采用随机延时发请求来减轻负载,实际产生的并发连接大概在0.5k。 架构方面,两台webserver + 一台mysql,32核,36G内存。其中一台webserver为主,起有memcache作为分布式session以及data cache,redis做队列,使用nginx反代做简单的负载均衡。内核参数皆已调优。 根据各种参数组合的基准压测,发现fpm响应在1ms,单核RPS为1K左右,32核可以跑到30K+,这是我实测见过的最高PHP 单机基准RPS了。但是nginx最高却只跑到25k,多方求解,至今无果。 总得来说,我还是相信nginx比fpm更加健壮以及更少的资源占用。 下面是我们在nginx层面的lua实践。
http://house.chaobaihe.net 潮白房产网
http://bbs.chaobaihe.net 潮白河社区网- vim /usr/local/openresty/nginx/conf/nginx.conf本文章来源于潮白家园网: http://www.chaobaihe.net
- http://fj.chaobaihe.net 潮白河点评网
- http {http://news.chaobaihe.net 潮白新闻网
http://house.chaobaihe.net 潮白房产网- # access dict,初始化使用到的共享内存
http://fj.chaobaihe.net 潮白河点评网 - lua_shared_dict access_whitelist 1m;http://house.chaobaihe.net 潮白房产网
- lua_shared_dict access_blacklist 1m;http://fj.chaobaihe.net 潮白河点评网
- lua_shared_dict access_iplist 40m;http://news.chaobaihe.net 潮白新闻网
- lua_shared_dict access_total 1m;http://fj.chaobaihe.net 潮白河点评网
http://fj.chaobaihe.net 潮白河点评网- # access 访问控制lua脚本http://news.chaobaihe.net 潮白新闻网
- access_by_lua_file /usr/local/openresty/lualib/com/access.lua;
复制代码
http://bbs.chaobaihe.net 潮白河社区网- vim /usr/local/openresty/lualib/com/access.lua
http://news.chaobaihe.net 潮白新闻网
http://news.chaobaihe.net 潮白新闻网- --[[本文章来源于潮白家园网: http://www.chaobaihe.net
- -- access.lua, 访问控制http://house.chaobaihe.net 潮白房产网
- -- @author 楚吟风 <<a href="mailto:chuyinfeng@gmail.com" target="_blank">chuyinfeng@gmail.com</a>>http://fj.chaobaihe.net 潮白河点评网
- -- @version 1.0
http://fj.chaobaihe.net 潮白河点评网 - -- @update 2013-04-25本文章来源于潮白家园网: http://www.chaobaihe.net
- -- @package comhttp://house.chaobaihe.net 潮白房产网
- ]]
本文章来源于潮白家园网: http://www.chaobaihe.net - http://news.chaobaihe.net 潮白新闻网
- -- 静态白名单,从文件加载http://bbs.chaobaihe.net 潮白河社区网
- local whitelist = ngx.shared.access_whitelist
http://bbs.chaobaihe.net 潮白河社区网 - -- 静态黑名单,从共享内存载入http://bbs.chaobaihe.net 潮白河社区网
- local blacklist = ngx.shared.access_blacklist
http://bbs.chaobaihe.net 潮白河社区网 - -- IP计数器,从共享内存载入http://news.chaobaihe.net 潮白新闻网
- local iplist = ngx.shared.access_iplist
本文章来源于潮白家园网: http://www.chaobaihe.net - -- 全局计数器,从共享内存再入
http://news.chaobaihe.net 潮白新闻网 - local total = ngx.shared.access_totalhttp://house.chaobaihe.net 潮白房产网
- -- 获取客户端IP
本文章来源于潮白家园网: http://www.chaobaihe.net - local ip = ngx.var.remote_addr
http://news.chaobaihe.net 潮白新闻网 - -- 单个IP RPS限制http://bbs.chaobaihe.net 潮白河社区网
- local ip_rps = 50
http://fj.chaobaihe.net 潮白河点评网 - -- 单个IP RPS 系统防火墙拦截标准http://bbs.chaobaihe.net 潮白河社区网
- local iptable_rps = 100
本文章来源于潮白家园网: http://www.chaobaihe.net - -- 总RPS限制本文章来源于潮白家园网: http://www.chaobaihe.net
- local total_rps = 3000
http://news.chaobaihe.net 潮白新闻网 - -- 重新载入名单http://bbs.chaobaihe.net 潮白河社区网
- local ctrl_path = '/access_ctrl/reload/'
http://house.chaobaihe.net 潮白房产网 - -- 防火墙静态黑白名单存放路径本文章来源于潮白家园网: http://www.chaobaihe.net
- local file_path = '/usr/local/openresty/lualib/com/access/'http://bbs.chaobaihe.net 潮白河社区网
- -- ip认证本文章来源于潮白家园网: http://www.chaobaihe.net
- local auth = {
http://news.chaobaihe.net 潮白新闻网 - ['/admin/'] = {http://bbs.chaobaihe.net 潮白河社区网
- '192.168.20.15'
http://house.chaobaihe.net 潮白房产网 - }
http://bbs.chaobaihe.net 潮白河社区网 - }
http://house.chaobaihe.net 潮白房产网 - -- ip 认证http://news.chaobaihe.net 潮白新闻网
- local is_banned = falsehttp://news.chaobaihe.net 潮白新闻网
- local uri = string.lower(ngx.var.request_uri)http://house.chaobaihe.net 潮白房产网
- for path, iplist in pairs(auth) do
本文章来源于潮白家园网: http://www.chaobaihe.net - local i, _ = string.find(uri, path)
http://news.chaobaihe.net 潮白新闻网 - if i == 1 thenhttp://bbs.chaobaihe.net 潮白河社区网
- is_banned = truehttp://news.chaobaihe.net 潮白新闻网
- for _, cip in pairs(iplist) do
http://bbs.chaobaihe.net 潮白河社区网 - if string.find(ip, cip) then
本文章来源于潮白家园网: http://www.chaobaihe.net - is_banned = falsehttp://house.chaobaihe.net 潮白房产网
- end
http://fj.chaobaihe.net 潮白河点评网 - endhttp://fj.chaobaihe.net 潮白河点评网
- end
本文章来源于潮白家园网: http://www.chaobaihe.net - end
http://house.chaobaihe.net 潮白房产网 - if is_banned then
http://bbs.chaobaihe.net 潮白河社区网 - --ngx.header['Content-Type'] = 'text/plain'http://house.chaobaihe.net 潮白房产网
- --ngx.say(ip .. ' is banned')
http://bbs.chaobaihe.net 潮白河社区网 - --ngx.exit(ngx.HTTP_OK);
http://house.chaobaihe.net 潮白房产网 - end
http://fj.chaobaihe.net 潮白河点评网
本文章来源于潮白家园网: http://www.chaobaihe.net- -- 从文件载入字典
http://house.chaobaihe.net 潮白房产网 - function load_file_to_dict(file, dict)本文章来源于潮白家园网: http://www.chaobaihe.net
- dict:flush_all()http://bbs.chaobaihe.net 潮白河社区网
- local fh = io.open(file, 'r')
http://fj.chaobaihe.net 潮白河点评网 - for line in fh:lines() do
http://bbs.chaobaihe.net 潮白河社区网 - dict:set(line, '')
本文章来源于潮白家园网: http://www.chaobaihe.net - endhttp://news.chaobaihe.net 潮白新闻网
- fh:close()http://house.chaobaihe.net 潮白房产网
- endhttp://news.chaobaihe.net 潮白新闻网
- http://bbs.chaobaihe.net 潮白河社区网
- -- 载入静态名单http://bbs.chaobaihe.net 潮白河社区网
- if (whitelist:get('0.0.0.0') == nil) or (ngx.var.request_uri == ctrl_path) then本文章来源于潮白家园网: http://www.chaobaihe.net
- load_file_to_dict(file_path .. 'whitelist.txt', whitelist)
本文章来源于潮白家园网: http://www.chaobaihe.net - load_file_to_dict(file_path .. 'blacklist.txt', blacklist)
http://house.chaobaihe.net 潮白房产网 - endhttp://fj.chaobaihe.net 潮白河点评网
- http://fj.chaobaihe.net 潮白河点评网
- --[[http://news.chaobaihe.net 潮白新闻网
- -- is_block, 检测当前IP是否被屏蔽http://fj.chaobaihe.net 潮白河点评网
- ]]
http://news.chaobaihe.net 潮白新闻网 - function is_block()http://house.chaobaihe.net 潮白房产网
- -- 如果在静态白名单,则直接放行http://news.chaobaihe.net 潮白新闻网
- if whitelist:get(ip) thenhttp://house.chaobaihe.net 潮白房产网
- return false
http://fj.chaobaihe.net 潮白河点评网 - end
http://bbs.chaobaihe.net 潮白河社区网 - http://bbs.chaobaihe.net 潮白河社区网
- -- 如果在静态黑名单,则拦截
http://news.chaobaihe.net 潮白新闻网 - if blacklist:get(ip) thenhttp://house.chaobaihe.net 潮白房产网
- return {本文章来源于潮白家园网: http://www.chaobaihe.net
- ['status'] = 1,
http://news.chaobaihe.net 潮白新闻网 - ['tips'] = (ip .. ' is in blacklist, please contact us'),本文章来源于潮白家园网: http://www.chaobaihe.net
- }
http://bbs.chaobaihe.net 潮白河社区网 - end
http://fj.chaobaihe.net 潮白河点评网 - -- 当前IP请求次数加1http://bbs.chaobaihe.net 潮白河社区网
- local ip_times = iplist:incr(ip, 1)
http://news.chaobaihe.net 潮白新闻网 - -- 如果访问记录为空,则设置访问次数为1
http://bbs.chaobaihe.net 潮白河社区网 - if ip_times == nil then
http://house.chaobaihe.net 潮白房产网 - ip_times = 1
http://news.chaobaihe.net 潮白新闻网 - iplist:set(ip, 1, 1)http://house.chaobaihe.net 潮白房产网
- end
http://news.chaobaihe.net 潮白新闻网 - 本文章来源于潮白家园网: http://www.chaobaihe.net
- -- 如果请求频率超过单个IP系统防火墙限制,则写入防火墙名单
http://news.chaobaihe.net 潮白新闻网 - if ip_times == iptable_rps then
本文章来源于潮白家园网: http://www.chaobaihe.net - local file = io.open(file_path .. 'blocklist.txt', 'a')
http://house.chaobaihe.net 潮白房产网 - file:write("\r\n" .. ip)
本文章来源于潮白家园网: http://www.chaobaihe.net - file:close()本文章来源于潮白家园网: http://www.chaobaihe.net
- ngx.say('will in iptables');ngx.exit(ngx.HTTP_OK)
http://news.chaobaihe.net 潮白新闻网 - endhttp://bbs.chaobaihe.net 潮白河社区网
- http://news.chaobaihe.net 潮白新闻网
- -- 如果请求频率超过单个IP限制则封禁,超过多少个封禁多少秒http://fj.chaobaihe.net 潮白河点评网
- if ip_times > ip_rps thenhttp://fj.chaobaihe.net 潮白河点评网
- local sec = (ip_times - ip_rps)http://bbs.chaobaihe.net 潮白河社区网
- iplist:set(ip, ip_times, sec)
http://bbs.chaobaihe.net 潮白河社区网 - return {
http://bbs.chaobaihe.net 潮白河社区网 - ['status'] = 2,
本文章来源于潮白家园网: http://www.chaobaihe.net - ['tips'] = ip .. ' is blocked for ' .. sec .. ' seconds.',http://fj.chaobaihe.net 潮白河点评网
- ['sec'] = sec,本文章来源于潮白家园网: http://www.chaobaihe.net
- }http://fj.chaobaihe.net 潮白河点评网
- endhttp://house.chaobaihe.net 潮白房产网
- http://house.chaobaihe.net 潮白房产网
- -- 全局请求次数加1
http://bbs.chaobaihe.net 潮白河社区网 - local total_times = total:incr('total', 1)
http://bbs.chaobaihe.net 潮白河社区网 - if total_times == nil thenhttp://news.chaobaihe.net 潮白新闻网
- total_times = 1
本文章来源于潮白家园网: http://www.chaobaihe.net - total:set('total', 1, 1)
http://fj.chaobaihe.net 潮白河点评网 - endhttp://house.chaobaihe.net 潮白房产网
- http://news.chaobaihe.net 潮白新闻网
- -- 全局请求拦截
http://house.chaobaihe.net 潮白房产网 - if total_times > total_rps then
http://fj.chaobaihe.net 潮白河点评网 - return {
http://house.chaobaihe.net 潮白房产网 - ['status'] = 3,本文章来源于潮白家园网: http://www.chaobaihe.net
- ['tips'] = total_times .. ' is request, please wait for a moment',http://news.chaobaihe.net 潮白新闻网
- ['total'] = total_times,
本文章来源于潮白家园网: http://www.chaobaihe.net - }
http://fj.chaobaihe.net 潮白河点评网 - endhttp://bbs.chaobaihe.net 潮白河社区网
- endhttp://news.chaobaihe.net 潮白新闻网
- http://house.chaobaihe.net 潮白房产网
- -- 主函数本文章来源于潮白家园网: http://www.chaobaihe.net
- function main()
http://news.chaobaihe.net 潮白新闻网 - local block = is_block()
http://news.chaobaihe.net 潮白新闻网 - if block then
http://house.chaobaihe.net 潮白房产网 - ngx.req.set_header("Content-Type", "text/plain")
http://news.chaobaihe.net 潮白新闻网 - --ngx.say(block['status'])本文章来源于潮白家园网: http://www.chaobaihe.net
- ngx.say(block['tips'])
http://news.chaobaihe.net 潮白新闻网 - ngx.exit(ngx.HTTP_OK)
http://fj.chaobaihe.net 潮白河点评网 - end
本文章来源于潮白家园网: http://www.chaobaihe.net - end
http://fj.chaobaihe.net 潮白河点评网 - main()
复制代码 http://fj.chaobaihe.net 潮白河点评网
压测结果显示,采用ngx_lua,与原生nginx性能几无差别,应用层防护效果非常显著
http://news.chaobaihe.net 潮白新闻网本文章来源于潮白家园网: http://www.chaobaihe.net
|