nginx,我已添加了lua模块。我要用lua在nginx的conf文件里面配置负载均衡
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nginx,我已添加了lua模块。我要用lua在nginx的conf文件里面配置负载均衡相关的知识,希望对你有一定的参考价值。
我是通过对请求的运算,然后在一table里面 找IP,然后实现负载均衡,这个table比较大,有将近2万个IP,我想问的是,我如何在请求过来的时候,不用每次都创建这个大table,而是在nginx启动的时候 创建一次,然后每次请求的时候直接查询就可以了?
说实话 你这样提问确实挺难回答的因为我没用过nginx
不太清楚里面table是怎么使用的
不过我推荐你使用的方法是
在一开始创建一个table 然后使用ip作为table的索引
将内容放在table存储
比方
local tab =
for i = 1,len do
local value = xxx(某个userdata 或其他类型的值)
local ip = xxx.ip
tab[ip] = value
end
一开始这样存储一下 后面只要使用tab[ip]来访问追问
呵呵,我也是初学nginx,现在基本已经解决了,你说的这些虽然没用,但你回答的很辛苦,就给你分了。
参考技术A 这篇文章貌似写得还蛮详细的。。。除了nginx还有其他的配置介绍。。。。http://www.liulangxiong.com/archives/11/追问
不是配置,配置很简单,我是要编译,然后添加一些功能模块,还有一些功能。
Nginx结合Lua实现限流
采用的是openresty的lua-resty-limit-traffic模块,这个模块不需要随着nginx安装时进行添加,在使用时直接引入即可,还是比较方便的。
获取请求参数
根据参数在策略中查找并获取相应的阀值,若不存在则采用默认值。
使用lua-resty-limit-traffic进行限流。
两个工具类
一个是字符串分割,一个nginx缓存的设置和获取。
字符串分割 splitutil.lua
1/** Created by Erick.
2** DateTime: 2019-1-4 16:59
3**/
4local _M = {}
5function _M.split(str,delim)
6 if type(delim) ~= "string" or string.len(delim) <= 0 then
7 return
8 end
9 local start = 1
10 local tab = {}
11 while true do
12 local pos = string.find(str,delim,start,true)
13 if not pos then
14 break
15 end
16 table.insert(tab,string.sub (str,start,pos-1))
17 start = pos+string.len(delim)
18 end
19 table.insert(tab,string.sub(str,start))
20 return tab
21end
22return _M
缓存的get和set,sharedoperutil.lua
1/** Created by Erick.
2** DateTime: 2019-1-9 16:52
3** operate shared_dic
4**/
5local _M = {}
6/** get value in dic
7** dic : nginx shared dic name
8** key : the nginx shared dic's key
9**/
10function _M.shared_dic_get(dic , key)
11 local value = dic:get(key)
12 return value
13end
14
15/** set value in dic
16** dic : defined nginx shared dic name
17** key : the nginx shared dic's key
18** value : reset value
19** exptime : the key and value exp time
20**/
21function _M.shared_dic_set(dic , key , value , exptime)
22 if not exptime then
23 exptime = 0
24 end
25 local succ , err = dic:set(key , value , exptime)
26 return succ
27end
28return _M
初始化策略信息
初始化限流策略信息limitdata_init.lua初始化限流策略信息limitdata_init.lua
1/** Created by Erick.
2** DateTime: 2019-1-4 16:35
3** 初始化文件限流数据到table中
4**/
5local limit_table = ngx.shared.my_limit_store
6local splitutil = require("splitutil")
7file = io.open("../lua/syslimitrate.txt","r")
8if nil == file then
9 ngx.log(ngx.INFO, "文件读取失败,将采用默认值进行赋值")
10 local suc,err = limit_table:set("default" , "15-15")
11else
12 for line in file:lines() do
13 local splitTable = splitutil.split(line , "-")
14 local sysFlag = splitTable[1]
15 local limitRate = splitTable[2]
16 local bursts = splitTable[3]
17 local tableVal = string.format("%s-%s" , limitRate , bursts)
18 ngx.log(ngx.INFO, "sysFlag = " , sysFlag , "限流阀值:流速-桶容量:" , tableVal)
19 limit_table:set(sysFlag , tableVal)
20 end
21end
22file:close()
初始化数据主要是从文件中读取然后放到nginx的定义的内存空间ngx.shared.my_limit_store中,若是读取文件失败则设置一个默认值。
syslimitrate.txt文件内容
1/**格式为:渠道-每秒处理并发量-缓存容量**/
2taobao-10-200
3baidu-50-200
获取请求参数
获取请求参数并查询对应的限流阀值进行限流limitrate_access.lua
1/** Created by Erick.
2** DateTime: 2019-1-8 16:14
3**/
4// 获取请求参数
5local splitutil = require("splitutil")
6ngx.req.read_body()
7local args, err = ngx.req.get_post_args()
8local sysFlag = args["sys"]
9local limit_table = ngx.shared.my_limit_store
10local limitRate = limit_table:get(sysFlag)
11if not limitRate then
12 ngx.log(ngx.INFO, "sysFlag can not found so set defalut value")
13 limitRate = limit_table:get("default")
14end
15// 获取到的值进行拆分并限流
16local limitValue = splitutil.split(limitRate,"-")
17local rate = tonumber(limitValue[1])
18local burst = tonumber(limitValue[2])
19local limit_req = require "resty.limit.req"
20ngx.say("rate====" , rate , "---burst=====",burst)
21// 根据配置项创建一个限流的table。
22local lim, err = limit_req.new("my_limit_req_store", rate, burst)
23if not lim then
24 ngx.log(ngx.ERR,
25 "failed to instantiate a resty.limit.req object: ", err)
26 return ngx.exit(500)
27end
28// 根据渠道标识进行限流
29local delay, err = lim:incoming(sysFlag, true)
30if not delay then
31 if err == "rejected" then
32 ngx.say("rejected access service..............")
33 ngx.log(ngx.INFO,"rejected access service..............",err)
34 return ngx.exit(503)
35 end
36 ngx.log(ngx.INFO, "failed to limit req: ", err)
37 return ngx.exit(500)
38end
39ngx.log(ngx.INFO,"access received..............")
40ngx.say("access received..............")
动态调整阀值
动态调整阀值limitvaluereset_content.lua
1/** Created by Erick.
2** DateTime: 2019-1-9 14:27
3** this lua script can reset limitrate value
4**/
5local splitutil = require("splitutil")
6local sharedoperutil = require("sharedoperutil")
7// get request param
8local args, err = ngx.req.get_uri_args()
9local limitvalue = args["limitvalue"]
10ngx.say("-----------limitvalue-----------" , limitvalue)
11local limitParam = splitutil.split(limitvalue , "-")
12local sysFlag = limitParam[1]
13ngx.say(sharedoperutil.shared_dic_get(ngx.shared.my_limit_store,sysFlag))
14local rateBurst = string.format("%s-%s" , limitParam[2] , limitParam[3])
15ngx.say("-------------rateBurst:" , rateBurst)
16sharedoperutil.shared_dic_set(ngx.shared.my_limit_store , sysFlag , rateBurst , 0)
17ngx.say("---------------" , sharedoperutil.shared_dic_get(ngx.shared.my_limit_store,sysFlag))
以上是所有关于Lua脚本的内容,下面与nginx进行整合。
nginx.conf配置文件
1worker_processes 2;
2pid logs/nginx.pid;
3
4events {
5 worker_connections 10240;
6}
7error_log logs/access.log info;
8
9http {
10 // 定义以及引入限流模块
11 lua_shared_dict my_limit_store 10m;
12 lua_shared_dict my_limit_req_store 100m;
13 lua_package_path "nginx-1.12.1/lua-resty-limit-traffic-0.05/lib/?.lua;nginx-1.12.1/nginx-1.12.1/lua/?.lua;;";
14
15 include mime.types;
16
17 log_format main '$remote_addr - $time_local - $request_method - $request_uri - $status - $body_bytes_sent - $request_time';
18 access_log logs/access.log main;
19
20 sendfile on;
21 tcp_nopush on;
22 tcp_nodelay on;
23
24 keepalive_timeout 10;
25 keepalive_requests 500;
26
27 client_header_timeout 60;
28 client_body_timeout 60;
29 send_timeout 60;
30
31 open_file_cache max=1024 inactive=120s;
32 open_file_cache_valid 30;
33 open_file_cache_min_uses 5;
34
35 gzip on;
36 gzip_http_version 1.0;
37 gzip_comp_level 2;
38 gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript application/json;
39 gzip_disable msie6;
40
41 client_body_in_file_only off;
42 client_body_temp_path http_body_dir 1 2;
43 client_body_in_single_buffer on;
44 client_max_body_size 10m;
45 client_body_buffer_size 128k;
46 client_header_buffer_size 4k;
47 large_client_header_buffers 4 16k;
48 // ---------初始化限流信息start-------------
49 init_by_lua_file lua/limitdata_init.lua;
50 // ---------初始化限流信息end-------------
51 // 这部分用到一个自动上线下的模块,在文章最后简单说下
52 upstream myupstream {
53 zone zone_for_myupstream 1m;
54 server 192.168.1.10:8080;
55 server 192.168.1.11:8080;
56 }
57 server {
58 listen 8890;
59 server_name localhost;
60
61 location /dynamic {
62 #allow 127.0.0.1;
63 #deny all;
64 dynamic_upstream;
65 }
66 location /limit{
67 #allow 127.0.0.1;
68 #deny all;
69 // --------重置限流阀值start--------
70 content_by_lua_file lua/limitvaluereset_content.lua;
71 //-------重置限流阀值end----------
72 }
73 location / {
74 //--------访问控制进行限流start---------
75 access_by_lua_file lua/limitrate_access.lua;
76 //---------访问控制进行限流end-----------
77 proxy_pass http://myupstream;
78 root html;
79 index index.html index.htm;
80 }
81 error_page 500 502 503 504 /50x.html;
82 location = /50x.html {
83 root html;
84 }
85 }
86}
在使用lua脚本的地方增加了注释,至此限流的基本功能说完了,大家可以参考进行测试,在讲解的过程中涉及到一个自动上下线的功能用到了一个模块ngx_dynamic_upstream,调用api接口可以实现例如服务器的上线,下线,配置权重,增加/删除机器,调整后不用修改比较方便。
2.
3.
4.
一码不扫,
可以扫天下?
以上是关于nginx,我已添加了lua模块。我要用lua在nginx的conf文件里面配置负载均衡的主要内容,如果未能解决你的问题,请参考以下文章