http://www.xxx.com/test/a?a=1&age=1
location /test {
default_type text/html;
echo "uri:$document_uri;args:$args;param.age=$arg_age;";
echo "client ip:$remote_addr";
echo "status:$status;user:$remote_user;$connection_requests";
}
output
uri:/test/a;args:a=1&age=1;param.age=1; client ip:172.17.0.1 status:200;user:;12
上面是一个很乱的输出,简单说下请求参数, <span class="katex">args是请求的参数,arg_age是后面具体的某个参数值
有时候需要判断文件是否存在
server {
root /var/www/example.com;
location / {
if (!-f $request_filename) {
break;
}
}
}
更好的写法
server {
root /var/www/example.com;
location / {
try_files $uri $uri/ /index.html;
}
}
请求 http://www.xxx.com/test/ <pre>
不能识别此Latex公式: request_filename:/data/www/xxx/pay/test/ </pre>
uri: /test/ try_files优先尝试是否存在<pre>不能识别此Latex公式: uri,如果不存在尝试</pre>
uri/ 否则转向index.html
下面正式进入主题
location /test {
default_type text/html;
content_by_lua '
ngx.say("Hello Openrestry")
ngx.say(ngx.localtime() )
';
}
打印字符串 返回当前时间
简单的内部调用
location = /getname {
#此处表示属于内部调用,外部无法直接访问
internal;
default_type text/html;
content_by_lua '
local params = ngx.req.get_uri_args();
ngx.print(params.name);
';
}
location = /test {
default_type text/html;
content_by_lua '
local res = ngx.location.capture(
"/getname", {args={name=ngx.var["arg_name"],age=18}}
)
ngx.say(ngx.var["arg_name"]);
ngx.say("status:", res.status, " response:", res.body)
';
}
请求url: http://www.xxx.com/test?name=bbb
output : bbb status:200 response:bbb
关键词: ngx.location.capture 发起请求, ngx.var["arg_name"]访问uri参数变量, ngx.say和ngx.print都属于输出数据,但ngx.say会自动在后面加\n ngx.location.capture 是非阻塞的,ngx.location.capture也可以用来完成http请求,但是它只能请求到相对于当前nginx服务器的路径,不能使用之前的绝对路径进行访问
方法1
location = /getname {
internal;
default_type text/html;
content_by_lua '
local params = ngx.req.get_uri_args();
ngx.print(params.name);
';
}
方法2
location = /getage {
internal;
default_type text/html;
content_by_lua '
local params = ngx.req.get_uri_args();
ngx.print(params.age);
';
}
并行调用并输出返回值
location = /test {
default_type text/html;
content_by_lua '
local res1,res2 = ngx.location.capture_multi{
{"/getage",{args="age=16&sex=1"}},
{"/getname",{args={name=ngx.var["arg_name"]}}}
}
ngx.say("status:", res1.status, " response:", res1.body)
ngx.say("status:", res2.status, " response:", res2.body)
';
}
可使用ngx.sleep(0.1) 延迟测试,ngx.now()获取毫秒级时间戳,ngx.time()返回秒级别
location = /getname {
default_type text/html;
content_by_lua '
ngx.say(123)
';
}
http重定向302跳转
location = /test {
default_type text/html;
rewrite_by_lua '
return ngx.redirect("/getname")
';
}
内部执行
location = /test {
default_type text/html;
rewrite_by_lua '
return ngx.exec("/getname")
';
}
ngx.exec 方法与 ngx.redirect 是完全不同的,前者是个纯粹的内部跳转并且 没有引入任何额外 HTTP 信号
获取一个 uri 有两个方法: ngx.req.get_uri_args 、ngx.req.get_post_args
location = /test {
default_type text/html;
content_by_lua '
ngx.say("hello")
';
rewrite_by_lua '
ngx.say("rewirite")
';
access_by_lua '
ngx.say("access")
';
}
会执行rewrite_by_lua,因为它的优先级比 其他要高
location = /test {
default_type text/html;
content_by_lua_file /usr/server/openresty/nginx/conf/vhost/content.lua;
}
content.lua
ngx.say("hello world")
其他access_by_lua_file、access_by_lua_file用法类似
main.conf
init_by_lua '
cjson = require "cjson"
';
server {
....
}
contnet.lua
ngx.say(cjson.encode({dog=5,cat=6}))
--output {"dog":5,"cat":6}
ngx.exit(ngx.HTTP_OK)
ngx.exit(404)
value = ngx.HTTP_CONTINUE (100) (first added in the v0.9.20 release)
value = ngx.HTTP_SWITCHING_PROTOCOLS (101) (first added in the v0.9.20 release)
value = ngx.HTTP_OK (200)
value = ngx.HTTP_CREATED (201)
value = ngx.HTTP_ACCEPTED (202) (first added in the v0.9.20 release)
value = ngx.HTTP_NO_CONTENT (204) (first added in the v0.9.20 release)
value = ngx.HTTP_PARTIAL_CONTENT (206) (first added in the v0.9.20 release)
value = ngx.HTTP_SPECIAL_RESPONSE (300)
value = ngx.HTTP_MOVED_PERMANENTLY (301)
value = ngx.HTTP_MOVED_TEMPORARILY (302)
value = ngx.HTTP_SEE_OTHER (303)
value = ngx.HTTP_NOT_MODIFIED (304)
value = ngx.HTTP_TEMPORARY_REDIRECT (307) (first added in the v0.9.20 release)
value = ngx.HTTP_BAD_REQUEST (400)
value = ngx.HTTP_UNAUTHORIZED (401)
value = ngx.HTTP_PAYMENT_REQUIRED (402) (first added in the v0.9.20 release)
value = ngx.HTTP_FORBIDDEN (403)
value = ngx.HTTP_NOT_FOUND (404)
value = ngx.HTTP_NOT_ALLOWED (405)
value = ngx.HTTP_NOT_ACCEPTABLE (406) (first added in the v0.9.20 release)
value = ngx.HTTP_REQUEST_TIMEOUT (408) (first added in the v0.9.20 release)
value = ngx.HTTP_CONFLICT (409) (first added in the v0.9.20 release)
value = ngx.HTTP_GONE (410)
value = ngx.HTTP_UPGRADE_REQUIRED (426) (first added in the v0.9.20 release)
value = ngx.HTTP_TOO_MANY_REQUESTS (429) (first added in the v0.9.20 release)
value = ngx.HTTP_CLOSE (444) (first added in the v0.9.20 release)
value = ngx.HTTP_ILLEGAL (451) (first added in the v0.9.20 release)
value = ngx.HTTP_INTERNAL_SERVER_ERROR (500)
value = ngx.HTTP_METHOD_NOT_IMPLEMENTED (501)
value = ngx.HTTP_BAD_GATEWAY (502) (first added in the v0.9.20 release)
value = ngx.HTTP_SERVICE_UNAVAILABLE (503)
value = ngx.HTTP_GATEWAY_TIMEOUT (504) (first added in the v0.3.1rc38 release)
value = ngx.HTTP_VERSION_NOT_SUPPORTED (505) (first added in the v0.9.20 release)
value = ngx.HTTP_INSUFFICIENT_STORAGE (507) (first added in the v0.9.20 release)
ngx.log(ngx.ERR,"error!error!error!")
ngx.STDERR
ngx.EMERG
ngx.ALERT
ngx.CRIT
ngx.ERR
ngx.WARN
ngx.NOTICE
ngx.INFO
ngx.DEBUG
查看错误日志 : 2018/07/02 13:52:23 [error] 141#0: *19 [lua] content.lua:2: error!error!error! 在 Nginx 内核中硬编码限制了单条错误信息最长为 2048 字节。这个长度包含了最后的换行符和开始的时间戳。如果信息长度超过这个限制,Nginx 将把信息文本截断
这个 Lua 表可以用来存储基于请求的 Lua 环境数据,其生存周期与当前请求相同 (类似 Nginx 变量)。
location /test {
rewrite_by_lua_block {
ngx.ctx.foo = 76
}
access_by_lua_block {
ngx.ctx.foo = ngx.ctx.foo + 3
}
content_by_lua_block {
ngx.say(ngx.ctx.foo) --output : 79
}
}
ocation = /getname {
default_type text/html;
content_by_lua '
ngx.req.read_body()
ret = ngx.req.get_body_data() --获取body体,包含post数据
ret = cjson.decode(ret)
ngx.say(ret.a,ret.b)
';
}
主程(post请求)
res = ngx.location.capture(
'/getname',
{ method = ngx.HTTP_POST, body = '{"a":123,"b":345}' }
)
ngx.say("status:", res.status, " response:", res.body) --输出
output : status:200 response:123345 cjson包 cjson.encode 将table转成json, cjson.decode 将json转成table
redis = {ip='127.0.0.1'}
function redis:new()
ngx.say(self.ip)
end
redis:new()
: 调用会将自己传递赋给self
local credis = require('resty.redis')
local redis = credis:new()
redis:set_timeout(1000) -- 1 sec
local ok,err = redis:connect('*****',11368)
if not ok then
ngx.say(err)
ngx.eof()
end
local res, err = redis:auth('123456');
if not res then
ngx.say("failed to authenticate: ", err)
return
end
--redis:setex('name',60,'test');
local res, err = redis:get("name")
if not res then
ngx.say("failed to get dog: ", err)
return
end
ngx.say(res)
- -把它放入大小为100的连接池中
-- 10秒最大空闲时间
local ok, err = red:set_keepalive(10000, 100)
if not ok then
ngx.say("failed to set keepalive: ", err)
return
end
-- redis:close()
setex(key,expire_time,value) https://github.com/openresty/lua-resty-redis
local mysql = require "resty.mysql"
local db,err = mysql:new()
if not db then
ngx.say('init failed mysql',err)
end
db:set_timeout(1000)
local ok,err,errcode,sqlstate = db:connect({
host = "******",
port = 3306,
database = "edu_large_data",
user = "**",
password = "****",
charset = "utf8",
max_packet_size = 1024 * 1024,
})
if not ok then
ngx.say("failed to connect: ", err, ": ", errcode, " ", sqlstate)
eturn
end
res, err, errcode, sqlstate =
db:query("select * from flow_user_stat order by id desc limit 2")
if not res then
ngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")
return
end
db:set_keepalive(0, 100)
ngx.say(cjson.encode(res))
[{"uv":1000,"id":4,"one_uv":80,"platform":2,"ip":700,"module":2,"pv":"1500","wait_time":"55555","ymd":20180703},{"uv":800,"id":3,"one_uv":150,"platform":1,"ip":500,"module":2,"pv":"900","wait_time":"66666","ymd":20180703}]
发起请求
local res = ngx.location.capture('/getuser',{
method = ngx.HTTP_POST,
body = '{1,2,3}'
})
ngx.say(res.status,res.body)
因为ngx.location.capture只能访问本地,本地转发远程地址
location = /getuser {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://www.xxx.com/getpostuser;
}
模拟远程地址,只把传来值传回去
location = /getpostuser {
content_by_lua '
ngx.req.read_body()
ngx.say(ngx.req.get_body_data() )
';
}
发起请求方输出 ngx.say(res.status,res.body) : 200 {1,2,3}
上面已经安装了resty.http包,下面直接请求远程的接口(实际还是本机)
local http = require "resty.http"
local httpc = http.new()
local res, err = httpc:request_uri("http://XXXX/getpostuser", {
method = "POST",
body = "a=1&b=2",
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
if not res then
ngx.say("failed to request: ", err)
return
end
ngx.say(res.body)
但是一直是失败的,需要配置 resolver,查看本机DNS
cat /etc/resolv.conf
resolver 192.168.65.1;
init_by_lua '
cjson = require "cjson"
';
server {
...
}
再去远程请求本机访问就可以了