跳转至

lua-upstream: NGINX 上游控制的 Lua API

安装

您可以在任何基于 RHEL 的发行版中安装此模块,包括但不限于:

  • RedHat Enterprise Linux 7、8、9 和 10
  • CentOS 7、8、9
  • AlmaLinux 8、9
  • Rocky Linux 8、9
  • Amazon Linux 2 和 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

通过在 /etc/nginx/nginx.conf 顶部添加以下内容来启用该模块:

load_module modules/ngx_http_lua_upstream_module.so;

本文档描述了 nginx-module-lua-upstream v0.7,于 2017 年 5 月 15 日发布。


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;

        # 以下 /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("failed to get servers in 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
            }
        }
    }
}

函数

get_upstreams

syntax: names = upstream.get_upstreams()

获取所有命名上游组的名称列表(即显式的 upstream {} 块)。

请注意,由 proxy_pass 等创建的隐式上游组被排除在外。

get_servers

syntax: servers = upstream.get_servers(upstream_name)

获取指定上游组中所有服务器的配置。请注意,一个服务器可能会在其服务器名称可以解析为多个地址时使用多个地址。

返回值是一个类数组的 Lua 表。每个表条目是一个类哈希的 Lua 表,包含以下键:

  • addr

    套接字地址。可以是 Lua 字符串或类数组的 Lua 字符串表。 * backup * fail_timeout * max_fails * name * weight

get_primary_peers

syntax: peers = upstream.get_primary_peers(upstream_name)

获取指定上游组中所有主(非备份)对等体的配置。

返回值是一个类数组的 Lua 表,包含所有主对等体。每个表条目是一个(嵌套的)类哈希的 Lua 表,包含以下键:

  • current_weight
  • effective_weight
  • fail_timeout
  • fails
  • id

    对等体的标识符(ID)。该 ID 可用于在对等体修改 API 中引用组中的对等体。 * max_fails * name

    当前对等体的套接字地址 * weight * accessed

    最后访问的时间戳(自纪元以来的秒数) * checked

    最后检查的时间戳(自纪元以来的秒数) * down

    如果对等体已被标记为“下线”,则为真,否则该键不存在 * conns

    到对等体的活动连接数(这需要 NGINX 1.9.0 或更高版本)。

get_backup_peers

syntax: peers = upstream.get_backup_peers(upstream_name)

获取指定上游组中所有备份对等体的配置。

返回值的结构与 get_primary_peers 函数相同。

set_peer_down

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

设置指定对等体的“下线”(布尔值)属性。

要唯一指定一个对等体,您需要指定上游名称、它是否是备份对等体,以及对等体 ID(从 0 开始)。

请注意,此方法仅在当前 Nginx 工作进程中更改对等体设置。如果您希望进行全服务器的更改,您需要自己在所有 Nginx 工作进程之间同步更改(例如,通过 ngx_luangx.shared.DICT)。

以下是一个示例。假设我们在 nginx.conf 中有一个“bar”上游块:

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;
}

那么

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

将使对应于 server 127.0.0.2 的主对等体下线。

类似地,

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

将使对应于 server 127.0.0.4 ... 的备份对等体下线。

您可以通过提供 false 值作为第四个参数再次启用对等体。

current_upstream_name

syntax: name = upstream.current_upstream_name()

返回当前请求的代理上游名称。 如果此请求没有上游(没有 proxy_pass 调用),或者此函数在内容阶段之前的阶段被调用,则返回值将为 nil。如果在上游定义或 proxy_pass 指令中明确包含了端口,则该端口将包含在此函数的返回值中。

示例:

-- 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

请注意,由 proxy_pass 创建的隐式上游被包含在内,这与 upstream.get_upstreams() 的输出相反。

假设您的 luajit 安装在 /opt/luajit:

export LUAJIT_LIB=/opt/luajit/lib

假设您使用的是 LuaJIT v2.1:

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

在此假设您将 nginx 安装在 /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

从 NGINX 1.9.11 开始,您还可以通过在上述 `./configure` 命令行中使用 `--add-dynamic-module=PATH` 选项来编译此模块为动态模块,而不是使用 `--add-module=PATH`。然后,您可以通过 [load_module](http://nginx.org/en/docs/ngx_core_module.html#load_module) 指令在您的 `nginx.conf` 中显式加载该模块,例如,

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

另见

GitHub

您可以在 nginx-module-lua-upstream 的 GitHub 仓库中找到此模块的其他配置提示和文档。