diff --git a/tutorial/README.adoc b/tutorial/README.adoc index bf2c5ec..8536bdb 100644 --- a/tutorial/README.adoc +++ b/tutorial/README.adoc @@ -139,17 +139,170 @@ image::./imgs/debug-nginx.png[调试nginx] == 三. 网关原理 -参考: +网关可以执行多种功能,包括路由、负载均衡、认证、授权、限流、监控和安全等。负载均衡是网关最基本的功能之一。负载均衡器中的主动探测和被动探测是两种不同的健康检查机制,用于确定后端服务器或服务实例是否能够正常处理请求。以下是它们的主要区别: -1. 负载均衡解释:link:https://www.nginx.org.cn/article/detail/440[] -2. 高可用配置示例:link:https://blog.csdn.net/IT_10/article/details/89365436[] -3. nginx开发参考1:link:https://tengine.taobao.org/book/[] -4. nginx开发参考2:link:https://www.nginx.org.cn/article/detail/443[] -5. nginx中文配置手册:link:https://wizardforcel.gitbooks.io/nginx-doc/content/index.html[] -6. nginx开发参考3:link:https://www.kancloud.cn/kancloud/master-nginx-develop/51798[] +[%autowidth] +|=== +| |主动探测(Active Probing) | 被动探测(Passive Probing) + +|定义| 负载均衡器定期向后端服务器发送探测请求(如HTTP请求、TCP连接或ICMP消息),以检查它们是否健康|负载均衡器通过监控经过它的实际用户请求来检测后端服务器的健康状况 +| 依赖| 不依赖于用户请求 | 依赖于用户请求的响应来评估后端服务器的状态,不会主动发送额外的探测请求 +|类型|可以是简单的TCP连接尝试,或者更复杂的应用层探测,如发送HTTP HEAD请求并检查HTTP状态码|取决于用户请求 +|频率|根据需要设置探测的时间间隔|取决于用户请求频率 +|响应|如果后端服务器在指定的时间内响应了探测请求并且返回了健康的响应,那么它被认为是健康的|如果用户请求得到了成功的响应(如HTTP 200 OK),则认为后端服务器是健康的;如果响应表明错误(如HTTP 5xx错误),则认为服务器可能不健康 +|优点|及时发现不健康的服务器,在用户请求到达之前将其从负载均衡池中移除|仅依赖于实际的用户请求,不会给后端服务器带来额外的负载 +|缺点|频繁的探测请求可能给后端服务器带来额外的负载|只有在用户请求到达不健康的服务器时才会被检测到,可能无法及时发现不健康的服务器 +|=== + +本文档以link:https://github.com/yaoweibin/nginx_upstream_check_module[nginx_upstream_check_module]为例,深入理解nginx的主动探测原理。 + +=== 3.1 源码解读 + +==== 3.1.1 配置与编译 + +ngx_http_upstream_check_module模块的 `config` 文件内容如下: + +[source,shell,numbered] +---- +ngx_feature="ngx_http_upstream_check_module" +ngx_feature_name= +ngx_feature_run=no +ngx_feature_incs= +ngx_feature_libs="" +ngx_feature_path="$ngx_addon_dir" +ngx_feature_deps="$ngx_addon_dir/ngx_http_upstream_check_module.h" +ngx_check_src="$ngx_addon_dir/ngx_http_upstream_check_module.c" +ngx_feature_test="int a;" +. auto/feature + +if [ $ngx_found = yes ]; then + have=NGX_HTTP_UPSTREAM_CHECK . auto/have + CORE_INCS="$CORE_INCS $ngx_feature_path" + ngx_addon_name=ngx_http_upstream_check_module + HTTP_MODULES="$HTTP_MODULES ngx_http_upstream_check_module" + NGX_ADDON_DEPS="$NGX_ADDON_DEPS $ngx_feature_deps" + NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_check_src" +else + cat << END + $0: error: the ngx_http_upstream_check_module addon error. +END + exit 1 +fi +---- + +**解读如下**: + +`auto/feature` 是 Nginx 源码树中的一个脚本文件,位于 auto 目录下。这个脚本的作用是自动检测当前编译环境是否支持某些特定的系统特性(features),并据此设置编译配置。这对于确保 Nginx 能够在不同操作系统和硬件平台上以最优方式运行至关重要。该脚本主要功能是: + +. **检测特性**: 检查编译环境中是否存在 Nginx 所需的系统调用、库函数或编译器特性。 +. **设置宏定义**: 如果检测到特性存在,则在 Nginx 的配置头文件中定义相应的宏,以便编译时启用相关的特性代码。 +. **生成配置**: 根据检测结果,生成或更新配置文件,如 `nginx.conf` 和 `ngx_auto_config.h`(低版本Nginx该文件名为 `auto_config.h`)。 + +`auto/feature` 脚本通过命令行参数指定要检测的特性。以下是一些常见的参数: + +* `ngx_feature`: 特性的名称,用于日志输出。 +* `ngx_feature_name`: 这个参数预期是一个宏名称字符串,它用于在 Nginx 的配置头文件(通常是 `ngx_auto_config.h`)中定义一个宏,以指示编译器和运行时环境该特性是可用的。 +* `ngx_feature_run`: 这个参数的值通常为 `yes` 或者不设置(空)。如果设置为 `yes`,则表示编译后的测试程序需要被执行,以确保不仅编译通过了,而且程序在运行时也能正确工作。如果不设置或者留空,编译后的程序将不会被执行,仅仅编译成功即认为特性支持。。 +* `ngx_feature_incs`: 这个参数预期是一个或多个头文件的列表,这些头文件对于编译测试程序来说是必需的,它们通常用于声明用于检测特定系统特性的函数、结构或宏。 +* `ngx_feature_path`: 头文件的搜索路径。 +* `ngx_feature_libs`: 编译测试程序时需要链接的库。 +* `ngx_feature_test`: 这个参数是一个字符串,包含了用于检测特性的 C 语言代码片段。这段代码通常包括函数调用、结构体定义、宏检查或其他编译时的检查,旨在验证系统是否提供了所需的功能。 + +注意,`ngx_check_src` 和 `ngx_feature_deps` 并不是feature脚本内置参数,而是用户自定义参数。 + +`auto/feature` 脚本的工作流程: + +. **生成测试代码**: 根据参数 `ngx_feature_test` 提供的参数,脚本生成一个 C 语言的测试程序。 +. **编译测试程序**: 使用参数 `ngx_feature_incs` 和 `ngx_feature_libs` 指定的编译器选项、头文件路径和库链接选项编译测试程序。 +. **运行测试**: 如果 `ngx_feature_run` 设置为 `yes` ,则执行编译后的测试程序。 +. **分析结果**: 根据测试程序的编译和运行结果,确定特性是否存在。 +. **更新配置**: 如果特性存在,更新配置文件和头文件,使用 `ngx_feature_name` 指定的名称定义相应的宏。 + +其他变量: + +* `NGX_ADDON_DEPS` : 主要用于指定第三方模块(被编译为 addon 模块)所依赖的其他模块或文件。这个变量在 Nginx 的 `auto/modules` 脚本中被处理,负责设置模块依赖. +* `CORE_INCS` : 是一个变量,用于定义 Nginx 编译所需的头文件的搜索路径。在编译过程中,`CORE_INCS` 变量的值会被用作编译器的 `-I` 参数,这是指定头文件搜索目录的标准编译器选项。在 Nginx 的 `auto/configure` 脚本或 `auto/modules` 脚本中,`CORE_INCS` 会根据检测到的模块和特性动态地设置和更新。 +* `ngx_addon_name`` :指定第三方模块的名称,是必须定义的变量, `ngx_addon_name` 被添加到模块列表中,这样在构建过程中,构建脚本就知道需要编译哪些模块 +* `HTTP_MODULES` : 定义了所有编译进 Nginx 的 HTTP 模块的列表,包括 Nginx 核心 HTTP 功能以及任何第三方 HTTP 模块。 +* `NGX_ADDON_DEPS` : 指定第三方模块(也称为 addon 模块)在编译时所依赖的其他文件或模块,在 Nginx 的构建脚本 auto/modules 中被使用。 +* `NGX_ADDON_SRCS` : 指定构成第三方模块的所有源代码文件,在 Nginx 的构建脚本 auto/modules 中被使用。 + +[小技巧]: 使用kimi对config文件解读如下: + +---- +这段 Nginx 第三方模块的 `config` 文件是一个脚本,用于配置和检测模块 `ngx_http_upstream_check_module`。下面是对脚本中每行的详细解释: + +1. `ngx_feature="ngx_http_upstream_check_module"` + 定义了正在配置的 Nginx 模块的名称。 + +2. `ngx_feature_name=` + 通常用于定义一个宏名称,但这里留空,表示可能不需要定义特定的宏。 + +3. `ngx_feature_run=no` + 表示不需要执行编译后的测试程序来验证特性。这可能是因为模块的存在与否不依赖于运行时检测。 + +4. `ngx_feature_incs=` + 留空,表示没有特定的头文件需要包含。 + +5. `ngx_feature_libs=""` + 留空,表示没有特定的库需要链接。 + +6. `ngx_feature_path="$ngx_addon_dir"` + 设置模块的路径为 `ngx_addon_dir` 变量的值,这通常是模块的安装目录。 + +7. `ngx_feature_deps="$ngx_addon_dir/ngx_http_upstream_check_module.h"` + 定义模块的依赖头文件,这里是模块的头文件。 + +8. `ngx_check_src="$ngx_addon_dir/ngx_http_upstream_check_module.c"` + 指定模块的源文件路径。 + +9. `ngx_feature_test="int a;"` + 提供一个非常简单的测试代码,这里仅仅声明了一个整型变量,实际上这个测试可能不会对模块的检测产生实际作用。 + +10. `. auto/feature` + 执行 Nginx 的 `auto/feature` 脚本来处理配置。 + +11. `if [ $ngx_found = yes ]; then` + 如果 `auto/feature` 脚本执行后 `ngx_found` 变量被设置为 `yes`,则继续执行以下命令。 + +12. `have=NGX_HTTP_UPSTREAM_CHECK . auto/have` + 使用 `auto/have` 脚本定义一个宏,表示检测到 `ngx_http_upstream_check_module`。 + +13. `CORE_INCS="$CORE_INCS $ngx_feature_path"` + 将模块的路径添加到 Nginx 核心的头文件搜索路径中。 + +14. `ngx_addon_name=ngx_http_upstream_check_module` + 设置第三方模块的名称。 + +15. `HTTP_MODULES="$HTTP_MODULES ngx_http_upstream_check_module"` + 将模块名称添加到 HTTP 模块列表中。 + +16. `NGX_ADDON_DEPS="$NGX_ADDON_DEPS $ngx_feature_deps"` + 将模块的依赖项添加到第三方模块的依赖列表中。 + +17. `NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_check_src"` + 将模块的源文件添加到第三方模块的源文件列表中。 + +18. `else` + 如果 `ngx_found` 不是 `yes`,执行错误处理。 + +19. `cat << END ... END` + 输出错误信息,指出 `ngx_http_upstream_check_module` 模块的添加出现错误。 + +20. `exit 1` + 退出脚本并返回状态码 1,表示配置过程中出现错误。 + +整体来看,这个 `config` 文件的作用是检测 `ngx_http_upstream_check_module` 是否可以被添加到 Nginx 中,并根据检测结果更新 Nginx 的配置,以便在编译时包含这个模块。如果检测失败,则输出错误信息并退出配置过程。 +---- == 四. 开发流程 == 五. 其他 -== 六. 参考资料 \ No newline at end of file +== 六. 参考资料 +1. 负载均衡解释:link:https://www.nginx.org.cn/article/detail/440[] +2. nginx中文配置手册:link:https://wizardforcel.gitbooks.io/nginx-doc/content/index.html[] +3. 高可用配置示例:link:https://blog.csdn.net/IT_10/article/details/89365436[] +4. nginx开发参考1:link:https://tengine.taobao.org/book/[] +5. nginx开发参考2:link:https://www.nginx.org.cn/article/detail/443[] +6. nginx开发参考3:link:https://www.kancloud.cn/kancloud/master-nginx-develop/51798[] \ No newline at end of file