更新时间: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进程。
猜你喜欢: