Saltar a contenido

lua-upstream: API de Lua para el control de upstream en NGINX

Instalación

Puedes instalar este módulo en cualquier distribución basada en RHEL, incluyendo, pero no limitado a:

  • RedHat Enterprise Linux 7, 8, 9 y 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 y Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-lua-upstream
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 nginx-module-lua-upstream

Habilita el módulo añadiendo lo siguiente en la parte superior de /etc/nginx/nginx.conf:

load_module modules/ngx_http_lua_upstream_module.so;

Este documento describe nginx-module-lua-upstream v0.7 lanzado el 15 de mayo de 2017.


http {
    upstream foo.com {
        server 127.0.0.1 fail_timeout=53 weight=4 max_fails=100;
        server agentzh.org:81;
    }

    upstream bar {
        server 127.0.0.2;
    }

    server {
        listen 8080;

        # salida de muestra para la siguiente interfaz /upstream:
        # upstream foo.com:
        #     addr = 127.0.0.1:80, weight = 4, fail_timeout = 53, max_fails = 100
        #     addr = 106.184.1.99:81, weight = 1, fail_timeout = 10, max_fails = 1
        # upstream bar:
        #     addr = 127.0.0.2:80, weight = 1, fail_timeout = 10, max_fails = 1

        location = /upstreams {
            default_type text/plain;
            content_by_lua_block {
                local concat = table.concat
                local upstream = require "ngx.upstream"
                local get_servers = upstream.get_servers
                local get_upstreams = upstream.get_upstreams

                local us = get_upstreams()
                for _, u in ipairs(us) do
                    ngx.say("upstream ", u, ":")
                    local srvs, err = get_servers(u)
                    if not srvs then
                        ngx.say("falló al obtener servidores en upstream ", u)
                    else
                        for _, srv in ipairs(srvs) do
                            local first = true
                            for k, v in pairs(srv) do
                                if first then
                                    first = false
                                    ngx.print("    ")
                                else
                                    ngx.print(", ")
                                end
                                if type(v) == "table" then
                                    ngx.print(k, " = {", concat(v, ", "), "}")
                                else
                                    ngx.print(k, " = ", v)
                                end
                            end
                            ngx.print("\n")
                        end
                    end
                end
            }
        }
    }
}

Funciones

get_upstreams

syntax: names = upstream.get_upstreams()

Obtiene una lista de los nombres de todos los grupos de upstream nombrados (es decir, bloques upstream {} explícitos).

Ten en cuenta que los grupos de upstream implícitos creados por proxy_pass, etc. están excluidos.

get_servers

syntax: servers = upstream.get_servers(upstream_name)

Obtiene configuraciones para todos los servidores en el grupo de upstream especificado. Ten en cuenta que un servidor puede tener múltiples direcciones cuando su nombre de servidor puede resolverse a múltiples direcciones.

El valor de retorno es una tabla de Lua similar a un array. Cada entrada de la tabla es una tabla de Lua similar a un hash que toma las siguientes claves:

  • addr

    dirección(es) de socket. puede ser una cadena de Lua o una tabla de Lua similar a un array de cadenas de Lua. * backup * fail_timeout * max_fails * name * weight

get_primary_peers

syntax: peers = upstream.get_primary_peers(upstream_name)

Obtiene configuraciones para todos los pares primarios (no de respaldo) en el grupo de upstream especificado.

El valor de retorno es una tabla de Lua similar a un array para todos los pares primarios. Cada entrada de la tabla es una tabla de Lua similar a un hash (anidada) que toma las siguientes claves:

  • current_weight
  • effective_weight
  • fail_timeout
  • fails
  • id

    Identificador (ID) para el par. Este ID puede ser utilizado para referenciar un par en un grupo en la API de modificación de pares. * max_fails * name

    Dirección de socket para el par actual * weight * accessed

    Marca de tiempo para el último acceso (en segundos desde la Época) * checked

    Marca de tiempo para la última verificación (en segundos desde la Época) * down

    Mantiene verdadero si el par ha sido marcado como "down", de lo contrario esta clave no está presente * conns

    Número de conexiones activas al par (esto requiere NGINX 1.9.0 o superior).

get_backup_peers

syntax: peers = upstream.get_backup_peers(upstream_name)

Obtiene configuraciones para todos los pares de respaldo en el grupo de upstream especificado.

El valor de retorno tiene la misma estructura que la función get_primary_peers.

set_peer_down

syntax: ok, err = upstream.set_peer_down(upstream_name, is_backup, peer_id, down_value)

Establece el atributo "down" (booleano) del par especificado.

Para especificar de manera única un par, necesitas especificar el nombre del upstream, si es o no un par de respaldo, y el id del par (comenzando desde 0).

Ten en cuenta que este método solo cambia la configuración del par en el proceso de trabajo actual de Nginx. Necesitas sincronizar los cambios entre todos los trabajadores de Nginx tú mismo si deseas un cambio a nivel de servidor (por ejemplo, mediante ngx_lua's ngx.shared.DICT).

A continuación se muestra un ejemplo. Considera que tenemos un bloque de upstream "bar" en nginx.conf:

upstream bar {
    server 127.0.0.2;
    server 127.0.0.3 backup;
    server 127.0.0.4 fail_timeout=23 weight=7 max_fails=200 backup;
}

entonces

upstream.set_peer_down("bar", false, 0, true)

desactivará el par primario correspondiente a server 127.0.0.2.

De manera similar,

upstream.set_peer_down("bar", true, 1, true)

desactivará el par de respaldo correspondiente a server 127.0.0.4 ....

Puedes volver a activar un par proporcionando un valor false como el cuarto argumento.

current_upstream_name

syntax: name = upstream.current_upstream_name()

Devuelve el nombre del upstream proxied para la solicitud actual. Si no hay upstream para esta solicitud (sin llamada a proxy_pass), o esta función se llama en una fase anterior a la fase de contenido, entonces el valor de retorno será nil. Si un puerto se incluye explícitamente en la definición de upstream o en la directiva proxy_pass, se incluirá en el valor de retorno de esta función.

Ejemplo:

-- upstream my_upstream { ... }
-- proxy_pass http://my_upstream;
upstream.current_upstream_name() --> my_upstream

-- proxy_pass http://example.com:1234;
upstream.current_upstream_name() --> example.com:1234

Ten en cuenta que los upstreams implícitos creados por proxy_pass están incluidos, a diferencia de la salida de upstream.get_upstreams().

asumiendo que tu luajit está instalado en /opt/luajit:

export LUAJIT_LIB=/opt/luajit/lib

asumiendo que estás usando LuaJIT v2.1:

export LUAJIT_INC=/opt/luajit/include/luajit-2.1

Aquí asumimos que instalarías tu nginx en /opt/nginx/.

./configure --prefix=/opt/nginx \ --with-ld-opt="-Wl,-rpath,$LUAJIT_LIB" \ --add-module=/path/to/lua-nginx-module \ --add-module=/path/to/lua-upstream-nginx-module

make -j2 make install

A partir de NGINX 1.9.11, también puedes compilar este módulo como un módulo dinámico, utilizando la opción `--add-dynamic-module=PATH` en lugar de `--add-module=PATH` en la línea de comando de `./configure` anterior. Y luego puedes cargar explícitamente el módulo en tu `nginx.conf` a través de la directiva [load_module](http://nginx.org/en/docs/ngx_core_module.html#load_module), por ejemplo,

```nginx
load_module /path/to/modules/ngx_http_lua_upstream_module.so;

Ver También

GitHub

Puedes encontrar consejos de configuración adicionales y documentación para este módulo en el repositorio de GitHub para nginx-module-lua-upstream.