跳转至

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 [Function function(self, ctx)]

    指定在发起子请求之前触发的回调函数。ctx参数是一个上下文对象。

    例如,您可以设置nginx变量(ngx.var)来记录子请求,并可以动态操作请求参数。

  • after_subrequest [Function function(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或Function function(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_subrequestafter_subrequestpath回调函数在参数中具有上下文对象。 上下文对象包含请求和子请求响应的信息,因此它所具有的值在请求处理过程中会发生变化。

上下文对象是一个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仓库中找到此模块的其他配置提示和文档。