快速导航
![](https://i-blog.csdnimg.cn/blog_migrate/d931ebaa9c0e401daa3b484d023ffb9c.jpeg)
初始的配置文件
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
# 加载lua模块
lua_package_path "/usr/local/openresty/lualib/?.lua;;";
# 加载c模块
lua_package_cpath "/usr/local/openresty/lualib/?.so;;";
# 在这里配置,这样当前http块内需要用到cjson模块时,都不需要独自加载了
init_by_lua_block{
-- 注意,这里面是lua语法,注释是两个杠 不是井号
cjson=require 'cjson';
-- mysql=require("resty.mysql");
-- redis=require 'resty.redis';
}
server {
listen 9000;
location / {
default_type text/html;
content_by_lua '
ngx.say("<p>Hello, World! second test!</p>")
';
}
location /abc {
lua_code_cache off;
# default_type text/html;
default_type application/json;
content_by_lua_file lua/a.lua;
}
}
}
从url获取参数,如果其他rest请求参数在url也可以使用此获取
修改a.lua文件
-- 读取所有url参数
local arg = ngx.req.get_uri_args()
ngx.say("读取的参数类型是:"..type(arg)) -- table
-- 遍历table并打印参数
for k,v in pairs(arg) do
ngx.say("[GET ] key:", k, " v:", v)
end
-- 只取name,取不到就是nil
ngx.say(arg["name"])
-- 取单个参数: ngx.var.arg_XXX
ngx.say(ngx.var.arg_name)
请求:ip:9000/abc?name=zhangsan
![](https://i-blog.csdnimg.cn/blog_migrate/3b641322bdbdab437276041ea842fcb0.png)
Post请求 读取参数
-- 解析 body 参数之前一定要先读取 body
ngx.req.read_body()
-- 获取数据,目标数据也是一个table
local arg = ngx.req.get_post_args()
local data = ngx.req.get_body_data()
for k,v in pairs(arg) do
ngx.say("[POST] key:", k, " v:", v)
end
ngx.say('')
ngx.say("**********下面是我后期更新的*********")
ngx.say('')
if data ~= nil then
ngx.say(type(data)) -- type is string
ngx.say(data)
end
测试有不同的结果,form-data数据是混乱的,x-www-form-urlencoded才是正常的!
![](https://i-blog.csdnimg.cn/blog_migrate/3c11c3faae3ecf8d16f14fb69aa922aa.gif)
post完成!我想了一下post有各种content-type形式,form-data可以是键值对、文件等。x-www-form-urlencode只能是键值对。这也解释了为什么接口muiltfile无法生成上传文件等swagger接口文档!
@RequestParam — from 表单形式取值
app软件里面常用下面⬇️
@RequestBody —- json 形式取值
使用post常用nginx的api
-- 解析 body 参数之前一定要先读取 body
ngx.req.read_body()
-- 获取数据,目标数据也是一个table
local arg = ngx.req.get_post_args()
-- 获取数据,返回string类型的数据,不方便我们获取
local data = ngx.req.get_body_data()
获取请求类型
ngx.var.request_method,返回大写的请求类型:GET
-- 只能使用一次,使用过后,第二次执行就是nil
local method = ngx.var.request_method;
-- local nilMethod = ngx.var.request_method;
if method == "GET" then
ngx.say("is GET")
else
ngx.say(method)
end
利用openresty发起请求 建议用方案二
方案一:子请求ngx.location.capture
官网说:子请求只是模仿 HTTP 接口,但不涉及额外的 HTTP/TCP 流量或IPC。一切都在内部高效地在 C 级别上运行。应该就是性能不错!
ngx内部有函数,可以支持发起ngx.location.capture
的内部子查询方式发起(不支持ip与端口),但是我们proxy_pass 来实现发起对外部请求!如果你仅仅需要本机内部,则不需要proxy_pass实现对上游访问!
修改nginx.conf文件
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
# 加载lua模块
lua_package_path "/usr/local/openresty/lualib/?.lua;;";
# 加载c模块
lua_package_cpath "/usr/local/openresty/lualib/?.so;;";
# 在这里配置,这样当前http块内需要用到cjson模块时,都不需要独自加载了
init_by_lua_block{
-- 注意,这里面是lua语法,注释是两个杠 不是井号
cjson=require 'cjson';
-- mysql=require("resty.mysql");
-- redis=require 'resty.redis';
}
upstream diyServer{ # ban _ tomcat not spuuort
hash $request_uri; # 让每个请求/item/id=001 访问到固定server,这样可以实现固定url去找固定server。(这样我Aserver的缓存,就不会请求Bserver了)
server 192.168.31.204:8080; # ① 自己springboot写一个请求返回(证明openresty发送了http请求)
keepalive 50; # ② 一定要添加keepalive保持长链接,减少连接导致的性能损失
# 一个长连接处理最大请求数(定期释放内存,防止内存溢出)
keepalive_requests 8192;
}
server {
listen 9000;
location / {
default_type text/html;
content_by_lua '
ngx.say("<p>Hello, World! second test!</p>")
';
}
location /abc {
lua_code_cache off;
# default_type text/html;
default_type application/json;
content_by_lua_file lua/a.lua;
}
location /useForOtherUrlRequest{
internal; # 只允许被内部访问,外部访问就是404
proxy_pass http://diyServer/user/api/v1/hello/;
}
}
}
保存后记得重载nginx配置文件
修改a.lua文件
-- res是个table 有header,body,status, https://github.com/openresty/lua-nginx-module#ngxlocationcapture 所有配置都在github说明了
local res = ngx.location.capture('/useForOtherUrlRequest',
{
method = ngx.HTTP_POST, -- defult is GET
body = "names=wangwu", -- 指定子请求的请求正文(仅限字符串值)x-www-urlencoding
args = {names=lisi,age=aa}, -- 指定子请求的 URI 查询参数(字符串值和 Lua 表都被接受)
-- always_forward_bodybody = true,
-- copy_all_vars = true
}
)
ngx.say(res.status)
ngx.say(res.body)
后端接口,实际就要一个names字段,不要担心我上文使用的是RestController,返回的是json
@RequestMapping("/hello")
public HashMap sayhello(String names){
HashMap<String,Object> hashMap = new HashMap<>();
hashMap.put("name",names);
hashMap.put("age",20);
return hashMap;
}
测试吧!这里有个bug,只要body不选x-www-urlencoded,并且随便添加任何一个值,java就取不到names,实际取到的是lua中body的wangwu!与url连接的内容无关!openresty1.21.4.1
![](https://i-blog.csdnimg.cn/blog_migrate/4a60ca447441be5ee4a7dc4ab4ba6b42.gif)
好在这种方式贼他妈拉跨,bug我问了也没人回答,如果有人知道联系我q:740969606
我们采用第二种方法 当前只适合从url中拼接好才能有效请求 如ip:9000/user/api/v1/hello?names=zhangsan
-- 千万不要少,我们是post请求这个lua,如果要读取数据就有这个,不然你回发现你的请求59秒都没响应
ngx.req.read_body()
local args, err = ngx.req.get_uri_args()
local res = ngx.location.capture('/useForOtherUrlRequest',
{
method = ngx.HTTP_POST,
body = args.data
}
)
ngx.say(res.status)
ngx.say(res.body)
![](https://i-blog.csdnimg.cn/blog_migrate/2a9fb3edf3c5750a966f6ea4eab88b2b.png)
方案二:cosocket 这个不是openresty的本库内容
官网地址:https://github.com/ledgetech/lua-resty-http
安装cosocket
opm get ledgetech/lua-resty-http
重启openresty,使我们配置文件生效
# 重启配置文件(前提得启动过)
sudo /usr/local/openresty/nginx/sbin/nginx -p /www -c conf/nginx.conf -s reload
重新编写a.lua文件
ngx.req.read_body()
local args, err = ngx.req.get_post_args()
-- 遍历table并打印参数
for k,v in pairs(args) do
ngx.say("key:", k, " v:", v)
end
ngx.say('单独读取到的names是:',args.names)
local body = 'names='..args.names..'&age='..args.age -- 封装请求参数
local http = require "resty.http" -- ① 引入模块 执行opm get ledgetech/lua-resty-http后,重启openresty才能生效
local httpc = http.new()
local res, err = httpc:request_uri( -- ② 发起请求
"http://192.168.31.204:8080/user/api/v1/hello",
{
method = "POST",
body = body,
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
},
}
)
if res ~= nil and 200 == res.status then
ngx.say('请求成功!',res.body)
else
ngx.say('请求失败!',err)
end
测试
![](https://i-blog.csdnimg.cn/blog_migrate/48be7fb8ad57086752d1e23a08e24d72.gif)
完成!