nginx upstream server主动健康检测模块ngx_http_upstream_check_module 使用和源码分析(中)

目录

  • 6. 源码分析
    • 6.1 解析指令分析
    • 6.2 待检查的服务器的添加和状态查询
    • 6.3 本模块的进程初始化函数
    • 6.4 准备执行健康检测任务
    • 6.5 执行健康检测任务

本篇对ngx_http_upstream_check_module的源码实现进行详细分析。

关于配置和使用部分可以查看上篇:nginx upstream server主动健康检测模块ngx_http_upstream_check_module 使用和源码分析(上)

6. 源码分析

本模块虽然代码量比较大,洋洋洒洒近5000行代码,但是执行逻辑还是非常清晰明了的。大致如下图:

在这里插入图片描述

程序的运行逻辑是靠nginx内核框架中的定时器定时驱动的,每一个定时间隔会对upstream中的peer(即后端服务)执行配置中定义好的健康检查。

6.1 解析指令分析

配置指令中最重要的就是check指令了,这个配置指令的格式如2.1节所述,nginx解析到这个指定的时候,就会开启对当前所在upstream块中的服务器的健康检测工作。其定义如下:
static ngx_command_t  ngx_http_upstream_check_commands[] = {{ ngx_string("check"),NGX_HTTP_UPS_CONF|NGX_CONF_1MORE,ngx_http_upstream_check,0,0,NULL },......
};
从以上指令的定义可以知道,指令的解析函数是ngx_http_upstream_check,源码如下:
	static char *
ngx_http_upstream_check(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{ngx_str_t                           *value, s;ngx_uint_t                           i, port, rise, fall, default_down, unique;ngx_msec_t                           interval, timeout;ngx_check_conf_t                    *check;ngx_http_upstream_check_srv_conf_t  *ucscf;/* default values */port = 0;rise = 2;fall = 5;interval = 30000;timeout = 1000;default_down = 1;unique = 0;value = cf->args->elts;ucscf = ngx_http_conf_get_module_srv_conf(cf,ngx_http_upstream_check_module);if (ucscf == NULL) {return NGX_CONF_ERROR;}/* 循环解析check指令的各个参数 */for (i = 1; i < cf->args->nelts; i++) {if (ngx_strncmp(value[i].data, "type=", 5) == 0) {s.len = value[i].len - 5;s.data = value[i].data + 5;ucscf->check_type_conf = ngx_http_get_check_type_conf(&s);if (ucscf->check_type_conf == NULL) {goto invalid_check_parameter;}continue;}....../* 这里省略了部分的配置项的解析 */goto invalid_check_parameter;}/* 将解析出来的配置项设置到ucscf中 */ucscf->port = port;ucscf->check_interval = interval;ucscf->check_timeout = timeout;ucscf->fall_count = fall;ucscf->rise_count = rise;ucscf->default_down = default_down;ucscf->unique = unique;if (ucscf->check_type_conf == NGX_CONF_UNSET_PTR) {ngx_str_set(&s, "tcp");ucscf->check_type_conf = ngx_http_get_check_type_conf(&s);}check = ucscf->check_type_conf;if (ucscf->send.len == 0) {ucscf->send.data = check->default_send.data;ucscf->send.len = check->default_send.len;}if (ucscf->code.status_alive == 0) {ucscf->code.status_alive = check->default_status_alive;}return NGX_CONF_OK;invalid_check_parameter:ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"invalid parameter \"%V\"", &value[i]);return NGX_CONF_ERROR;
}
check配置指令解析过程非常清晰,没有什么难度,无非就是把解析到的选项存放到本模块的server级别的配置中。
本模块的其他配置指令的解析也非常简单,不再赘述。

6.2 待检查的服务器的添加和状态查询

众所周知,在nginx的配置文件中的upstream块可以添加一个或者多个server,而这个server的配置指令其实并不是由ngx_http_upstream_check模块来处理的,它是由nginx的内核模块ngx_http_upstream来处理的。那本模块是如何感知到当前的upstream块有哪些需要健康检查的server呢?
为了解决这个问题,本模块向负载均衡模块开放了接口函数,列举如下:

/* 向本模块添加服务器 */
ngx_uint_t ngx_http_upstream_check_add_peer(ngx_conf_t *cf,ngx_http_upstream_srv_conf_t *us, ngx_addr_t *peer);/* 检查服务器是否已经故障 */*
ngx_uint_t ngx_http_upstream_check_peer_down(ngx_uint_t index);
在负载均衡模块初始化的时候,就调用ngx_http_upstream_check_add_peer向本模块添加需要监控的服务器。另外,在nginx的负载均衡模块需要判断server是否可用的时候,就调用ngx_http_upstream_check_peer_down来判断服务器的可用状态。
由于这个耦合性的存在,因此本模块是不能直接由官方原生nginx来使用的,tengine在各个负载均衡模块修改了部分代码来调用ngx_http_upstream_check_add_peer和ngx_http_upstream_check_peer_down。以round robin负载均衡模块为例,在ngx_http_upstream_init_round_robin函数中:
	for (i = 0; i < us->servers->nelts; i++) {if (!server[i].backup) {continue;}for (j = 0; j < server[i].naddrs; j++) {......
#if (NGX_HTTP_UPSTREAM_CHECK)if (!server[i].down) {peer[n].check_index =ngx_http_upstream_check_add_peer(cf, us,&server[i].addrs[j]);} else {peer[n].check_index = (ngx_uint_t) NGX_ERROR;}
#endifn++;}}
以上代码会对于每个upstream中的server的每个地址(如果以域名方式配置的话可能解析出多个地址),负载均衡模块向本模块添加一条检测记录。
**我突然发现,如果采用域名方式添加的server,本模块在后续应该是不能在通过域名解析动态得到上游服务器的地址进行检测的。**这或许是一个不足之处吧。同样以round robin负载均衡模块为例,在ngx_http_upstream_get_round_robin_peer函数中调用了ngx_http_upstream_check_peer_down,如下:
ngx_int_t
ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
{

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/456773.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

table列折行

这里折叠后少了合同名称,风险进展,预判无法达成金额 通过按钮的状态,来控制某一列的显示与隐藏, <el-tablev-loading"loading"v-if"tableStatus"border:data"tableData":key"tableKey"id"table"class"table-self is…

【MATLAB】使用梯度提升树在回归预测任务中进行特征选择(深度学习的数据集处理)

1.梯度提升树在神经网络的应用 使用梯度提升树进行特征选择的好处在于可以得到特征的重要性分数&#xff0c;从而识别出对目标变量预测最具影响力的特征。这有助于简化模型并提高其泛化能力&#xff0c;减少过拟合的风险&#xff0c;并且可以加快模型训练和推理速度。此外&…

C#,河豚算法(Blowfish Algorithm)的加密、解密源代码

Bruce Schneier 1 河豚算法&#xff08;Blowfish Algorithm&#xff09; 河豚算法&#xff08;Blowfish Algorithm&#xff09;是1993年11月由Bruce Schneier设计的一个完全开源的算法。 Blowfish算法是一个分组长度为64位、密钥长度可变的对称分组密码算法。 Blowfish算法具…

docker复习笔记01(小滴课堂)安装+部署mysql

查看内核版本。 关闭防火墙&#xff1a; 查看docker版本&#xff1a; 下载阿里yum源&#xff1a; 再看一下yum版本都有哪些&#xff1a; 我们可以看的docker-ce了。 安装它&#xff1a; 设置docker服务开机启动&#xff1a; 更新日志文件&#xff1a; 启动docker&#xff1a; …

【云原生之kubernetes系列】--HPA自动伸缩

HPA自动伸缩 HorizontalPodAutoscaler&#xff08;简称 HPA &#xff09;自动更新工作负载资源&#xff08;例如Deployment或者Statefulset)&#xff0c;目的是让pod可以自动扩缩工作负载以满足业务需求。 水平扩缩意味着对增加的负载的响应是部署更多的Pod。这与“垂直&…

【零基础入门TypeScript】Union

目录 语法&#xff1a;Union文字 示例&#xff1a;Union类型变量 示例&#xff1a;Union 类型和函数参数 Union类型和数组 示例&#xff1a;Union类型和数组 TypeScript 1.4 使程序能够组合一种或两种类型。Union类型是表达可以是多种类型之一的值的强大方法。使用管道符号…

某公司遭遇AI换脸诈骗,被骗走两个亿!

大家好我是二狗。 这年头&#xff0c;AI换脸不是个新鲜事了。 但是你敢信香港一公司因此被骗了两亿港元&#xff1f; 事情究竟是怎么一回事呢&#xff1f; 据香港文区报2月4日报道&#xff0c;香港警方披露首宗多人换脸AI诈骗案&#xff0c;一家总部在英国的跨国公司的香港…

(五)elasticsearch 源码之查询流程分析

https://www.cnblogs.com/darcy-yuan/p/17039526.html 1.概述 上文我们讨论了es&#xff08;elasticsearch&#xff0c;下同&#xff09;索引流程&#xff0c;本文讨论es查询流程&#xff0c;以下是基本流程图 2.查询流程 为了方便调试代码&#xff0c;笔者在电脑上启动了了…

单片机学习笔记---串口通信(1)

目录 通信的基本概念 通信的方式 1.按照数据传送的方式&#xff0c;可分为串行通信和并行通信。 1.1串行通信 1.2并行通信 2.按照通信的数据同步方式&#xff0c;又可以分为异步通信和同步通信。 2.1 异步通信 2.2同步通信 3.按照数据的传输方向&#xff0c;又可以分为…

DBNet详解及训练ICDAR2015数据集

论文地址&#xff1a;https://arxiv.org/pdf/1911.08947.pdf 开源代码pytorch版本&#xff1a;GitHub - WenmuZhou/DBNet.pytorch: A pytorch re-implementation of Real-time Scene Text Detection with Differentiable Binarization 前言 在这篇论文之前&#xff0c;文字检…

PKI - 01 散列(Hash)函数

文章目录 PKI概述散列日产生活中的指纹的工作原理散列函数的工作原理散列函数的四大特点使用散列函数验证数据的完整性 PKI概述 PKI&#xff08;Public Key Infrastructure&#xff0c;公钥基础设施&#xff09;证书系统是一种用于保护网络通信安全的技术。它基于非对称加密算法…

【Unity优化(一)】音频优化

整理资教程&#xff1a;https://learn.u3d.cn/tutorial/unity-optimization-metaverse 1.音频优化 音频一般不会成为性能瓶颈&#xff0c;是为了节省内存和优化包体大小。 1.0 文件格式和压缩格式 原始音频资源尽量采用WAV格式。 移动平台音频尽量采用Vorbis压缩格式&#x…