Aller au contenu

jsonrpc-batch: Module de protocole batch JSONRPC pour nginx-module-lua

Installation

Si vous n'avez pas encore configuré l'abonnement au dépôt RPM, inscrivez-vous. Ensuite, vous pouvez procéder avec les étapes suivantes.

CentOS/RHEL 7 ou 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

Pour utiliser cette bibliothèque Lua avec NGINX, assurez-vous que nginx-module-lua est installé.

Ce document décrit lua-resty-jsonrpc-batch v0.0.1 publié le 15 juillet 2015.


L'implémentation Lua-Openresty de JSON-RPC 2.0 Batch Request (http://www.jsonrpc.org/specification#batch).

La requête batch est non-bloquante et se déroule en parallèle car ce module utilise location.capture_multi de ngx_lua. Ainsi, la performance est élevée tandis que l'implémentation est simple.

Ce module analyse une requête batch, la valide et effectue plusieurs sous-requêtes vers des serveurs en amont. Notez que vous devez avoir un serveur JSON-RPC en amont comme vous le souhaitez, mais les serveurs en amont n'ont pas besoin de s'appliquer à la requête batch JSON-RPC.

Synopsis

Utilisation de base

server {
    location /api {
        # point de terminaison 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)
        ';
    }
}

Utilisation avancée

http {

    init_by_lua '
        local jsonrpc_batch = require "resty.jsonrpc.batch"
        client = jsonrpc_batch.new({
            -- limiter la taille du tableau de requêtes batch
            max_batch_array_size = 10,
            -- pour enregistrer le temps de réponse en amont
            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/.* {
            # point de terminaison jsonrpc
        }

        location /api/batch {
            lua_need_request_body on;

            content_by_lua '
                local res, err = client:batch_request({
                    -- vous pouvez changer le point de terminaison par requête
                    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);
            ';
        }
    }
}

Méthodes

new

usage:client = jsonrpc_batch:new(options)

L'argument options est une table Lua contenant les clés suivantes :

  • max_batch_array_size [Int]

Définir une limitation à la taille du tableau json de la requête batch.
Lorsqu'une requête dont la taille du tableau json dépasse la limite arrive, la méthode request renvoie une erreur json invalide.

La valeur par défaut est nil (pas de limite).

  • allow_single_request [Bool]

Ce module peut accepter non seulement des requêtes batch, mais aussi des requêtes simples (pas de requêtes batch). Par exemple, {"id":1, "jsonrpc": "2.0", "params": {}, "method": "hoge"} est une requête simple.

Si allow_single_request est défini sur false, une requête simple entraîne une erreur json invalide.

La valeur par défaut est true.

  • before_subrequest [Function function(self, ctx)]

    Spécifiez la fonction de rappel déclenchée juste avant d'envoyer des sous-requêtes. L'argument ctx est un objet Context.

    Par exemple, vous pouvez définir une variable nginx (ngx.var) pour enregistrer les sous-requêtes, et vous pouvez manipuler dynamiquement les paramètres de la requête.

  • after_subrequest [Function function(self, ctx)]

    Spécifiez la fonction de rappel déclenchée juste après l'envoi des sous-requêtes. L'argument ctx est un objet Context.

    Par exemple, nous pouvons définir une variable nginx (ngx.var) pour enregistrer les résultats des sous-requêtes, et nous pouvons manipuler dynamiquement les réponses des sous-requêtes.

request

usage:
res, err = client:request({
    path = "/api",
    request = ###jsonrpc request json###,
})

Décode la requête json et la sépare, et effectue des sous-requêtes en parallèle vers le path spécifié. Cela renvoie le json de réponse (res) qui est généré par toutes les réponses des sous-requêtes. err est défini comme message d'erreur lorsque le script lua rencontre une erreur.

Il peut accepter les paramètres suivants.

  • request [String] (obligatoire)

    Un JSON de requête.

  • path [String ou Function function(self, ctx, req)] (obligatoire)

    Chemin de sous-requête comme "/api".

    Le type peut être une fonction qui décide dynamiquement le chemin pour chaque sous-requête.

    L'argument ctx est un objet Context.

    L'argument req est un json de requête unique inclus dans le tableau json de la requête batch. comme {"id":1, "jsonrpc": "2.0", "params": {"user_id": 1}, "method": "getUser"}.

    Pour donner un exemple, nous pouvons utiliser cette fonction pour séparer les points de terminaison API par méthode JSON-RPC, et nous pouvons transmettre les informations de chemin de requête d'origine à la sous-requête.

    L'exemple de configuration suivant montre qu'il y a deux points de terminaison, et dispatch les requêtes batch vers les points de terminaison par méthode jsonrpc. De plus, les points de terminaison ont leur propre version API comme préfixe de chemin.

    location ~ ^/(\d+\.\d+)/getUser$ {
        # point de terminaison jsonrpc 1
    }

    location ~ ^/(\d+\.\d+)/updateUser$ {
        # point de terminaison 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 (string) optionnel

    Spécifiez la méthode HTTP utilisée par les sous-requêtes. La valeur par défaut est ngx.HTTP_POST.

Objet

Context

Les fonctions de rappel before_subrequest, after_subrequest, et path ont un objet Context dans les arguments. L'objet Context contient des informations sur les requêtes et les réponses des sous-requêtes, donc les valeurs qu'il possède ou non changent en fonction du processus de requête.

L'objet Context est une table lua, et a les clés suivantes.

  • path [String ou Function]

Spécifié par la méthode request comme path.

  • method [String]

Spécifié par la méthode request comme method.

  • raw_request [String]

json de requête spécifié par la méthode request comme request.

  • request [Table]

table lua générée en décodant le json raw_request.

  • is_batch [Bool]

Le json de requête est une requête unique ou une requête batch.

  • subreq_reqs [Table]

Le tableau des paramètres de sous-requêtes. Ce sont les arguments de ngx.location.capture_multi.

  • subreq_resps [Table]

Le tableau des réponses des sous-requêtes. Ce sont les réponses de ngx.location.capture_multi.

GitHub

Vous pouvez trouver des conseils de configuration supplémentaires et de la documentation pour ce module dans le dépôt GitHub pour nginx-module-jsonrpc-batch.