主请求、子请求
# 主请求
* http请求,从nginx外部进行反问
# 子请求
* 从nginx内部发起,不是外部的http请求,
* 将主请求分解为多个子请求,向指定的location发起访问,最后将结果汇总
ngx.location.capture:单一子请求
语法格式:res = ngx.location.capture(uri, options?)
环境:rewrite_by_lua*、access_by_lua*、content_by_lua*
# res:子请求返回结果,为table类型
* res.status:子请求的http响应状态
* res.header:子请求接收到的响应头,为table类型
* res.body:子请求接收到的响应体,数据可能会被截断,为table类型
* res.truncated:子请求是否截断,如果截断一般是由客户端连接断开、子请求超时导致
# options:请求参数,为table类型
* method:请求方法,可选值:ngx.HTTP_GET、ngx.HTTP_POST、ngx.HTTP_PUT、
ngx.HTTP_HEAD、ngx.HTTP_DELETE、ngx.HTTP_OPTIONS
* args:请求路径参数,如:args={a=1, b=2},<==> uri?a=1&b=2
* body:请求体,如:body = "gtlx"
* copy_all_args=true:是否将主请求的全部变量传递给子请求,默认false
* vars:设置传递给子请求的变量(需要先在nginx中设置),如:vars={m="gtlx", n="hzw"}
* share_all_vars:主请求是否与子请求共享变量,不推荐使用
如果共享,子请求改变变量之后,主请求的变量值也会改变
* always_forward_body:默认false
* false:如果不设置body,当请求类型为post、put时,子请求会将主请求的body出去
* true:无论请求方法是什么,如果不设置body,都会将主请求的body发送出去
* ctx:子请求上下文,table类型,可以使主请求、子请求共享上下文
ngx.location.capture_multi:并发子请求
语法格式:res, res2 = ngx.location.capture({ {uri, options?},
{uri2, options2?},
... })
环境:rewrite_by_lua*、access_by_lua*、content_by_lua*
# res:子请求返回结果,为table类型
* res.status:子请求的http响应状态
* res.header:子请求接收到的响应头,为table类型
* res.body:子请求接收到的响应体,数据可能会被截断,为table类型
* res.truncated:子请求是否截断,如果截断一般是由客户端连接断开、子请求超时导致
# options:请求参数,为table类型
* method:请求方法,可选值:ngx.HTTP_GET、ngx.HTTP_POST、ngx.HTTP_PUT、
ngx.HTTP_HEAD、ngx.HTTP_DELETE、ngx.HTTP_OPTIONS
* args:请求路径参数,如:args={a=1, b=2},<==> uri?a=1&b=2
* body:请求体,如:body = "gtlx"
* copy_all_args=true:是否将主请求的全部变量传递给子请求,默认false
* vars:设置传递给子请求的变量(需要先在nginx中设置),如:vars={m="gtlx", n="hzw"}
* share_all_vars:主请求是否与子请求共享变量,不推荐使用
如果共享,子请求改变变量之后,主请求的变量值也会改变
* always_forward_body:默认false
* false:如果不设置body,当请求类型为post、put时,子请求会将主请求的body出去
* true:无论请求方法是什么,如果不设置body,都会将主请求的body发送出去
* ctx:子请求上下文,table类型,可以使主请求、子请求共享上下文
default.conf
server {
listen 80;
server_name localhost;
location /main {
set $m "gtlx";
set $n "";
content_by_lua_block {
local res = ngx.location.capture(
"/sub", {
method = ngx.HTTP_GET,
body = "瓜田李下",
args = {a="1", b="2"},
vars = {n = "hzw"},
copy_all_args = true
}
)
ngx.say("res headers ==>")
for key,value in pairs(res) do
ngx.say(key)
end
ngx.say("\nres.key ==> value(type)") --ngx.say不能直接输出table
ngx.say("res.status:", res.status);
ngx.say("res.header:", type(res.header));
ngx.say("res.body:", res.body);
ngx.say("res.truncated:", res.truncated)
ngx.say("\nres.header ==>")
for key,value in pairs(res.header) do
ngx.say(key, " ==> ", value)
end
}
}
location /main2 {
content_by_lua_block {
local res, res2 = ngx.location.capture_multi({{"/sub2"}, {"/sub3"}})
ngx.say("res.body:", res.body);
ngx.say("res2.bosy:", res2.body);
}
}
location /sub {
internal; #该location只用于内部访问
content_by_lua_block {
ngx.req.read_body();
local body = ngx.req.get_body_data();
ngx.print("request body:", body);
ngx.print("request args:", ngx.var.args);
ngx.print("request var m:", ngx.var.m);
ngx.print("request var n", ngx.var.n);
echo "test";
}
}
location /sub2 {
internal;
echo "gtlx";
}
location /sub3 {
internal;
echo "hzw";
}
#error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/openresty/nginx/html;
}
}
创建容器
docker run -it -d -p 2002:80 \
-v /Users/huli/lua/openresty/conf8/default.conf:/etc/nginx/conf.d/default.conf \
--name open6 lihu12344/openresty
使用测试
# 单一子请求
huli@hudeMacBook-Pro conf8 % curl localhost:2002/main
res headers ==>
header
status
truncated
body
res.key ==> value(type)
res.status:200
res.header:table
res.body:request body:瓜田李下request args:b=2&a=1request var m:request var nhzw
res.truncated:true
res.header ==>
Content-Type ==> application/octet-stream
# 并发子请求
huli@hudeMacBook-Pro conf8 % curl localhost:2002/main2
res.body:gtlx
res2.bosy:hzw