jsonrpc-batch: NGINX模块的JSONRPC批处理协议模块
安装
如果您尚未设置RPM仓库订阅,请注册。然后您可以继续以下步骤。
CentOS/RHEL 7或Amazon Linux 2
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-jsonrpc-batch
CentOS/RHEL 8+、Fedora Linux、Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-jsonrpc-batch
要在NGINX中使用此Lua库,请确保已安装nginx-module-lua。
本文档描述了lua-resty-jsonrpc-batch v0.0.1,发布于2015年7月15日。
Lua-Openresty实现的JSON-RPC 2.0批处理请求(http://www.jsonrpc.org/specification#batch)。
批处理请求是非阻塞的,并且是并行进行的,因为此模块利用了ngx_lua的location.capture_multi。因此,性能高而实现简单。
此模块解析批处理请求,验证它,并对上游服务器发起多个子请求。 请注意,您必须有一个上游JSON-RPC服务器,但上游服务器不需要申请JSON-RPC批处理请求。
概述
基本用法
server {
location /api {
# jsonrpc端点
}
location /api/batch {
lua_need_request_body on;
content_by_lua '
local jsonrpc_batch = require "resty.jsonrpc.batch"
client = jsonrpc_batch:new()
local res, err = client:batch_request({
path = "/api",
request = ngx.var.request_body,
})
if err then
ngx.exit(500)
end
ngx.say(res)
';
}
}
高级用法
http {
init_by_lua '
local jsonrpc_batch = require "resty.jsonrpc.batch"
client = jsonrpc_batch.new({
-- 限制批处理请求数组大小
max_batch_array_size = 10,
-- 用于记录上游响应时间
before_subrequest = function(self, ctx, req)
ctx.start_at = ngx.now()
end,
after_subrequest = function(self, ctx, resps, req)
ngx.var.jsonrpc_upstream_response_time = ngx.now() - ctx.start_at
end,
})
';
server {
set $jsonrpc_upstream_response_time -;
location ~ /api/method/.* {
# jsonrpc端点
}
location /api/batch {
lua_need_request_body on;
content_by_lua '
local res, err = client:batch_request({
-- 您可以根据请求更改端点
path = function(self, ctx, req)
return "/api/method/" .. req.method
end,
request = ngx.var.request_body,
});
if err then
ngx.log(ngx.CRIT, err);
ngx.exit(500);
end
ngx.say(res);
';
}
}
}
方法
new
用法: client = jsonrpc_batch:new(options)
options参数是一个Lua表,包含以下键:
max_batch_array_size[Int]
设置批处理请求的json数组大小限制。
当请求的json数组大小超过限制时,request方法返回一个无效的错误json。
默认值为nil(无限制)。
allow_single_request[Bool]
此模块不仅可以接受批处理请求,还可以接受单个请求(非批处理请求)。例如,{"id":1, "jsonrpc": "2.0", "params": {}, "method": "hoge"}是一个单个请求。
如果将allow_single_request设置为false,则单个请求将导致无效的错误json。
默认值为true。
-
before_subrequest[Functionfunction(self, ctx)]指定在发起子请求之前触发的回调函数。
ctx参数是一个上下文对象。例如,您可以设置nginx变量(
ngx.var)来记录子请求,并可以动态操作请求参数。 -
after_subrequest[Functionfunction(self, ctx)]指定在发起子请求之后触发的回调函数。
ctx参数是一个上下文对象。例如,我们可以设置nginx变量(
ngx.var)来记录子请求结果,并可以动态操作子请求响应。
request
用法:
res, err = client:request({
path = "/api",
request = ###jsonrpc请求json###,
})
解码请求json并分离它,并对指定的path并行发起子请求。
它返回由所有子请求的响应json生成的响应json(res)。当lua脚本发生错误时,err设置错误信息。
它可以接受以下参数。
-
request[String](必需)请求JSON。
-
path[String或Functionfunction(self, ctx, req)](必需)子请求路径,如
"/api"。类型可以是函数,根据每个子请求动态决定路径。
ctx参数是一个上下文对象。req参数是包含在批处理请求json数组中的单个请求json,例如{"id":1, "jsonrpc": "2.0", "params": {"user_id": 1}, "method": "getUser"}。举个例子,我们可以使用此函数通过JSON-RPC方法分离api端点,并将原始请求路径信息传递给子请求。
以下配置示例有两个端点,并根据jsonrpc方法将批处理请求分发到端点。此外,端点具有自己的API版本作为路径前缀。
location ~ ^/(\d+\.\d+)/getUser$ {
# jsonrpc端点1
}
location ~ ^/(\d+\.\d+)/updateUser$ {
# jsonrpc端点2
}
location ~ ^/(\d+\.\d+)/batch$ {
set $version $1;
lua_need_request_body on;
content_by_lua {
local res, err = client:batch_request({
path = function(self, ctx, req)
return "/" .. ngx.var.version .. "/" .. req.method
end,
request = ngx.var.request_body,
});
if err then
ngx.log(ngx.CRIT, err);
ngx.exit(500);
return;
end
};
}
-
method(字符串)可选指定子请求使用的HTTP方法。 默认值为
ngx.HTTP_POST。
对象
上下文
before_subrequest、after_subrequest和path回调函数在参数中具有上下文对象。
上下文对象包含请求和子请求响应的信息,因此它所具有的值在请求处理过程中会发生变化。
上下文对象是一个lua表,具有以下键。
path[String或Function]
由request方法指定的path。
method[String]
由request方法指定的method。
raw_request[String]
由request方法指定的请求json。
request[Table]
通过解码raw_request json生成的lua表。
is_batch[Bool]
请求json是单个请求还是批处理请求。
- subreq_reqs [Table]
子请求参数的数组。
这是ngx.location.capture_multi的参数。
- subreq_resps [Table]
子请求响应的数组。
这是ngx.location.capture_multi的响应。
GitHub
您可以在nginx-module-jsonrpc-batch的GitHub仓库中找到此模块的其他配置提示和文档。