跳转至

upstream-jdomain: NGINX 上游的异步域名解析模块

安装

您可以在任何基于 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-upstream-jdomain
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-upstream-jdomain

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

load_module modules/ngx_http_upstream_jdomain_module.so;

本文档描述了 nginx-module-upstream-jdomain v1.5.2,于 2024 年 12 月 09 日发布。


这是一个用于 nginx 上游的异步域名解析模块。

该模块允许您在上游块中使用域名,并期望该域名能够动态解析,以便您的上游能够适应 DNS 条目的更新。

该模块不会在某个间隔内自动执行 DNS 解析。相反,DNS 解析需要通过对给定上游的请求来触发。如果 nginx 服务于一个指向 jdomain 上游的连接,并且配置的 interval 已经过期,则该模块将执行 DNS 查找。

该模块与其他 upstream 范围指令兼容。这意味着您可以用多个 jdomain 指令、多个 server 指令、keepalive、负载均衡指令等填充一个 upstream 块。请注意,除非在 upstream 块中指定了其他负载均衡方法,否则该模块将使用 nginx 核心内置的默认轮询负载均衡算法。

重要提示:如果指定了其他负载均衡算法,它必须在上游块中的 jdomain 指令 之前 如果不遵循这一点,nginx 在运行时崩溃!这是因为许多其他负载均衡模块显式扩展了内置的轮询,因此最终会覆盖 jdomain 初始化处理程序,因为 jdomain 在技术上也是一个负载均衡模块。虽然并非所有负载均衡模块都存在这种情况,但最好还是保持安全,将 jdomain 放在后面。

重要提示:由于该模块的非阻塞特性以及其 DNS 解析是由传入请求触发的,因此触发查找的请求实际上仍会被转发到在 DNS 查找发生之前已解析和缓存的上游。根据场景的不同,这可能导致在更改上游状态时出现一次性故障。牢记这一点对于确保上游的平滑过渡非常重要。

该存储库是 一个存储库 的分支,最初由 wdaike 创建。由于该项目不再维护,因此该存储库旨在成为其继任者,并且现在已经有了几个新特性。

用法

resolver 8.8.8.8; # 您的本地 DNS 服务器

## 基本上游使用默认端口 80 的域名。
upstream backend_01 {
    jdomain example.com;
}

## 指定不同端口的基本上游。
upstream backend_02 {
    jdomain example.com port=8080;
}

## 上游具有备份服务器,以便在找不到主机或 DNS 解析格式错误时使用。
upstream backend_03 {
    server 127.0.0.2 backup;
    jdomain example.com;
}

## 上游将在任何和所有 DNS 解析错误时使用备份。
upstream backend_04 {
    server 127.0.0.2 backup;
    jdomain example.com strict;
}

server {
    listen 127.0.0.2:80;
    return 502 '发生错误。';
}

概述

语法: jdomain <domain-name> [port=80] [max_ips=4] [interval=1] [strict]
上下文: upstream
属性:
    port:       后端的监听端口。                                      (默认: 80)
    max_ips:    IP 缓冲区大小。最大解析 IP 数量以进行缓存。       (默认: 4)
    interval:   解析域名的秒数。                       (默认: 1)
    ipver:      如果定义,仅使用 IPv4 或 IPv6 的地址。  (默认: 0)
    strict:     要求 DNS 解析成功并返回地址,
                否则将基础服务器和对等体标记为不可用,并
                强制使用上游块中的其他服务器(如果存在)。
                解析失败可能是超时、DNS
                服务器故障、连接拒绝、响应没有
                地址等。

有关详细信息,请参见 https://www.nginx.com/resources/wiki/modules/domain_resolve/

开发

先决条件

为了方便本地开发并使您能够构建和测试该模块,您需要一些工具。

  • Docker:提供一个环境,以便轻松重现构建和测试的理想条件。
  • act:模拟在本地执行 GitHub Actions 工作流,避免您推送提交只是为了查看 CI 失败。
  • rustcargo-make 的依赖项。
  • cargo-make:用于运行常见开发任务,如构建、测试和格式化代码。

任务运行器

cargo-make 是一个高级任务运行器,可以让您轻松执行常见的开发操作,如格式化代码、构建模块、运行测试套件和运行代码分析。您可以在文件 Makefile.toml 中查看任务定义。安装 cargo-make 将生成一个名为 makers 的独立可执行文件,以及一个可以通过 cargo make 执行的 cargo 扩展。由于该项目不是一个 rust crate,建议直接使用 makers

还要注意,为了简单起见,任务运行器使用 docker 来运行所有任务。这意味着构建的二进制文件并不针对您的主机平台。

默认任务

为了增加价值,默认任务(即仅运行 makers)将开始一个交互式 bash 会话,位于用于该项目的 docker 容器内。

这应该有助于调试和一般工作流程。

格式化

格式不正确的代码将导致 GitHub Actions 的 linting 作业失败。为避免这种情况,您可以在推送新更改之前运行格式化任务,如下所示:

makers format

此格式化是通过一个名为 clang-format 的工具执行的。您可以在文件 ./.clang-format 中找到定义的配置选项。

静态代码分析

您可以通过分析任务运行代码的静态分析:

makers analyse

此分析是通过一个名为 clang-tidy 的工具执行的。您可以在文件 ./.clang-tidy 中找到定义的配置选项。

测试

您可以使用测试任务运行测试套件,如下所示:

makers test

调试

我们可以在容器内使用 valgrindgdb 调试 nginx。

首先通过以下命令在容器中打开一个交互式 shell:

$ makers

我们将使用该会话运行 valgrind

$ valgrind --vgdb=full --vgdb-error=0 /github/workspace/bin/static/nginx -p/github/workspace/t/servroot -cconf/nginx.conf
==15== Memcheck, a memory error detector
==15== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==15== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==15== Command: /github/workspace/bin/static/nginx -p/github/workspace/t/servroot -cconf/nginx.conf
==15==
==15== (action at startup) vgdb me ...
==15==
==15== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==15==   /path/to/gdb /github/workspace/bin/static/nginx
==15== and then give GDB the following command
==15==   target remote | /usr/lib64/valgrind/../../bin/vgdb --pid=15
==15== --pid is optional if only one valgrind process is running
==15==

接下来,找到容器标识符,以便我们可以在其中打开另一个会话:

$ docker ps
CONTAINER ID        IMAGE                                     COMMAND             CREATED             STATUS              PORTS                    NAMES
55fab1e069ba        act-github-actions-nginx-module-toolbox   "bash"              4 seconds ago       Up 3 seconds        0.0.0.0:1984->1984/tcp   serene_newton

使用名称或 ID 执行 bash 会话:

$ docker exec -it serene_newton bash

我们将使用此会话启动 gdb 并针对我们在另一个会话中启动的 valgrind gdb 服务器:

$ gdb /github/workspace/bin/static/nginx
GNU gdb (GDB) Red Hat Enterprise Linux 8.0.1-30.amzn2.0.3
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /github/workspace/bin/static/nginx...done.
(gdb)

在 gdb 提示符下,针对 valgrind 进程并开始调试:

(gdb) target remote | /usr/lib64/valgrind/../../bin/vgdb --pid=15
Remote debugging using | /usr/lib64/valgrind/../../bin/vgdb --pid=15
relaying data between gdb and process 15
warning: remote target does not support file transfer, attempting to access files from local filesystem.
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
0x0000000004000ef0 in _start () from /lib64/ld-linux-x86-64.so.2
Missing separate debuginfos, use: debuginfo-install glibc-2.26-35.amzn2.x86_64
(gdb)

运行 GitHub Actions

使用 act,您可以模拟在推送更改后将在 GitHub 服务器上运行的工作流。

主工作流中有多个作业,因此在运行 act 时需要指定测试作业。例如,您可以使用以下命令运行代码格式验证:

act -vj lint

请注意,lint 作业不会格式化您的代码,它只检查格式是否符合预期。

还要注意,-v 用于启用详细模式,以便更清楚地了解 act 正在做什么。

您可以(并且应该)在本地运行的作业包括 lintbuildanalysetesttest 作业依赖于 build 作业的输出。为了保留构建作业的输出,您可以将 -b 标志添加到 act,或者您可以简单地使用任务运行器进行构建。

已知问题

目前没有! 🎉

如果您发现错误或有问题,请 打开一个问题

原作者

wdaike wdaike@163.com (https://github.com/wdaike),百度公司。

GitHub

您可以在 nginx-module-upstream-jdomain 的 GitHub 存储库 中找到该模块的其他配置提示和文档。