更新时间:2020-10-13 来源:黑马程序员 浏览量:
和一般的Web
Server类似,我们需要接收请求、处理并输出响应。而对于请求我们需要获取如请求参数、请求头、Body体等信息;而对于处理就是调用相应的Lua代码即可;输出响应需要进行响应状态码、响应头和响应内容体的输出。因此我们从如上几个点出发即可。
获取nginx变量:ngx.var
server { listen 8080; location / { #定义nginx变量 set $b $host; default_type text/html; content_by_lua_block { local var = ngx.var; -- 获取nginx变量 ngx.say("ngx.var.b : ", var.b, "<br/>") ngx.var.b = 2; -- 设置变量值 ngx.say("ngx.var.b : ", var.b, "<br/>") ngx.say("<br/>") } } }
获取请求头:ngx.req.get_headers()
server { listen 8080; location / { #定义nginx变量 set $b $host; default_type text/html; content_by_lua_block { local headers = ngx.req.get_headers() ngx.say("headers begin", "<br/>") ngx.say("Host : ", headers["Host"], "<br/>") ngx.say("user-agent : ", headers["user-agent"], "<br/>") ngx.say("user-agent : ", headers.user_agent, "<br/>") ngx.say("=======================================","</br>") for k,v in pairs(headers) do if type(v) == "table" then ngx.say(k, " : ", table.concat(v, ","), "<br/>") else ngx.say(k, " : ", v, "<br/>") end end ngx.say("headers end", "<br/>") ngx.say("<br/>") } } }
get请求uri参数:ngx.req.get_uri_args()
server { listen 8080; location / { #定义nginx变量 set $b $host; default_type text/html; content_by_lua_block { ngx.say("uri args begin", "<br/>") local uri_args = ngx.req.get_uri_args() ngx.say("param:username=",uri_args['username'], "<br/>") ngx.say("param:password=",uri_args['password'], "<br/>") ngx.say("uri args end", "<br/>") ngx.say("<br/>") } } }
post请求参数:ngx.req.get_post_args()
server { listen 8080; location / { #定义nginx变量 set $b $host; default_type text/html; content_by_lua_block { ngx.say("uri args begin", "<br/>") -- 获取请求体中的数据 ngx.req.read_body() local uri_args = ngx.req.get_post_args() --获取key-value格式的数据 ngx.say("param:username=",uri_args['username'], "<br/>") ngx.say("param:password=",uri_args['password'], "<br/>") ngx.say("uri args end", "<br/>") ngx.say("<br/>") } } }
其他请求相关的方法:
获取请求的http协议版本:ngx.req.http_version()
获取请求方法:ngx.req.get_method()
获取请求头内容:ngx.req.get_headers()
获取请求的body内容体:ngx.req.get_body_data()
server { listen 8080; location / { default_type text/html; content_by_lua_block { --写响应头 ngx.header.a = "1" --多个响应头可以使用table ngx.header.b = {"2", "3"} --输出响应 ngx.say("a", "b", "<br/>") ngx.print("c", "d", "<br/>") --200状态码退出 return ngx.exit(200) } } } }
响应相关方法:
ngx.header.xx = yy:输出响应头;
ngx.print():输出响应内容体;
ngx.say():同ngx.print()一样,但是会最后输出一个换行符;
ngx.exit():指定状态码退出;
ngx.send_headers():发送响应状态码,当调用ngx.say/ngx.print时自动发送响应状态码;
ngx.headers_sent( ): 判断是否发送了响应状态码。
重定向
server { listen 8080; location / { default_type text/html; content_by_lua_block { ngx.redirect("http://jd.com", 302); } } }
使用过如Java的朋友可能知道如Ehcache等这种进程内本地缓存,Nginx是一个Master进程多个Worker进程的工作方式,因此我们可能需要在多个Worker进程中共享数据,那么此时就可以使用ngx.shared.DICT来实现全局内存共享。
1、首先在nginx.conf的http部分定义一个全局内存,并指定内存大小。
#共享全局变量,在所有worker间共享,如下:定义了一个名为shared_data的全局内存,大小为1m lua_shared_dict shared_data 1m;
2、使用全局内存
server { listen 8080; location / { default_type text/html; content_by_lua_block { --1、获取全局共享内存变量 local shared_data = ngx.shared.shared_data --2、获取字典值 local i = shared_data:get("i") if not i then i = 1 --3、惰性赋值 shared_data:set("i", i) ngx.say("lazy set i ", i, "<br/>") end --递增 i = shared_data:incr("i", 1) ngx.say("i=", i, "<br/>") } } }
3、全局内存常用方法介绍
ngx.shared.DICT
获取共享内存字典项对象
语法:dict = ngx.shared.DICT dict = ngx.shared[name_var] 其中,DICT和name_var表示的名称是一致的,比如上面例子中,shared_data = ngx.shared.shared_data 就是dict = ngx.shared.DICT的表达形式, 也可以通过下面的方式达到同样的目的: shared_data = ngx.shared['shared_data']
ngx.shared.DICT:get(key)
获取共享内存上key对应的值。如果key不存在,或者key已经过期,将会返回nil;如果出现错误,那么将会返回nil以及错误信息。
ngx.shared.DICT:get_stale(key)
与get方法类似,区别在于该方法对于过期的key也会返回,第三个返回参数表明返回的key的值是否已经过期,true表示过期,false表示没有过期。
ngx.shared.DICT:set(key, value, exptime?, flags?)
“无条件”地往共享内存上插入key-value对,这里讲的“无条件”指的是不管待插入的共享内存上是否已经存在相同的key。
三个返回值的含义:
success:成功插入为true,插入失败为false
err:操作失败时的错误信息,可能类似"no memory"
forcible:true表明需要通过强制删除(LRU算法)共享内存上其他字典项来实现插入,false表明没有删除共享内存上的字典项来实现插入。
exptime参数表明key的有效期时间,单位是秒(s),默认值为0,表明永远不会过期;
flags参数是一个用户标志值,会在调用get方法时同时获取得到
ngx.shared.DICT.safe_set(key, value, exptime?, flags?)
与set方法类似,区别在于不会在共享内存用完的情况下,通过强制删除(LRU算法)的方法实现插入。如果内存不足,会直接返回nil和err信息"no
memory"
ngx.shared.DICT.add(key, value, exptime?, flags?)
与set方法类似,与set方法区别在于不会插入重复的键(可以简单认为add方法是set方法的一个子方法),如果待插入的key已经存在,将会返回nil和和err="exists"
ngx.shared.DICT.safe_add(key, value, exptime?, flags?)
与safe_set方法类似,区别在于不会插入重复的键(可以简单认为safe_add方法是safe_set方法的一个子方法),如果待插入的key已经存在,将会返回nil和和err="exists"
ngx.shared.DICT.replace(key, value, exptime?, flags?)
与set方法类似,区别在于只对已经存在的key进行操作(可以简单认为replace方法是set方法的一个子方法),如果待插入的key在字典上不存在,将会返回nil和错误信息"not
found"
ngx.shared.DICT.delete(key)
无条件删除指定的key-value对,其等价于ngx.shared.DICT:set(key, nil)
ngx.shared.DICT.incr(key, value)
对key对应的值进行增量操作,增量值是value,其中value的值可以是一个正数,0,也可以是一个负数。value必须是一个Lua类型中的number类型,否则将会返回nil和"not
a number";key必须是一个已经存在于共享内存中的key,否则将会返回nil和"not found".
ngx.shared.DICT.flush_all()
清除字典上的所有字段,但不会真正释放掉字段所占用的内存,而仅仅是将每个字段标志为过期。
ngx.shared.DICT.flush_expired(max_count?)
清除字典上过期的字段,max_count表明上限值,如果为0或者没有给出,表明需要清除所有过期的字段,返回值flushed是实际删除掉的过期字段的数目。
注意:
与flush_all方法的区别在于,该方法将会释放掉过期字段所占用的内存
ngx.shared.DICT.get_keys(max_count?)
从字典上获取字段列表,个数为max_count,如果为0或没有给出,表明不限定个数。默认值是1024个
注意:
强烈建议在调用该方法时,指定一个max_count参数,因为在keys数量很大的情况下,如果不指定max_count的值,可能会导致字典被锁定,从而阻塞试图访问字典的worker进程。
猜你喜欢: