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

news2024/11/13 22:11:52

目录

  • 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;
			}
#endif

			n++;
		}
	}
以上代码会对于每个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.coloradmin.cn/o/1436965.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Layui 表格组件 头部工具栏 筛选列 加入全选和全不选的功能

Layui 表格组件 头部工具栏 筛选列 加入全选和全不选的功能 问题 前端使用Layui表格组件展示后台数据&#xff0c;因数据中涉及字段较多&#xff0c;因此加入了组件中固有的控制表格列隐藏显示的功能。奈何客户希望再此基础上&#xff0c;加入“全选”和“全不选”的功能&…

Github 2024-02-06 开源项目日报Top9

根据Github Trendings的统计&#xff0c;今日(2024-02-06统计)共有9个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目4TypeScript项目2C项目1Ruby项目1HTML项目1Go项目1Rust项目1C项目1Kotlin项目1 Magic Mask for And…

【golang】24、go get 和 go mod:indrect 与 go mod tidy

文章目录 go get 会执行如下操作&#xff1a; 操作 go.mod 文件&#xff08;add、update、remove&#xff09;下载依赖到 $GOPATH/pkg/mod 中若已安装&#xff0c;则更新该包&#xff0c;到最新版本 试验前置准备&#xff1a;首先删除已下载的依赖&#xff0c;rm -rf $GOPATH…

Linux虚拟文件系统(VFS)

虚拟地址空间通常是与进程密切相关的概念&#xff0c;而不是文件系统。虚拟地址空间是为了提供进程对内存的抽象和隔离而设计的。 文件系统不使用页表&#xff0c;直接使用物理地址。 虚拟文件系统是linux内核的一个核心子系统。、 虚拟文件系统的目的&#xff1a;通过一个抽…

基于CEVA DSP BX2的架构分析(六)-加载和存储单元(二)

6.4 指针修改机制 LS0和LS1都包含指针修改机制。当使用间接或索引寻址模式时&#xff0c;指针的修改可以与地址生成并行执行。在间接寻址模式中&#xff0c;指针包含地址&#xff0c;而在变址寻址模式下&#xff0c;指针包含偏移量&#xff08;有关这些寻址模式的更多详细信息&…

python实现飞书群机器人消息通知

python实现飞书群机器人消息通知&#xff08;消息卡片&#xff09; 直接上代码 """ 飞书群机器人发送通知 """ import time import urllib3 import datetimeurllib3.disable_warnings()class FlybookRobotAlert():def __init__(self):self.web…

数据库管理-第146期 最强Oracle监控EMCC深入使用-03(20240206)

数据库管理145期 2024-02-06 数据库管理-第146期 最强Oracle监控EMCC深入使用-03&#xff08;20240206&#xff09;1 概览2 性能中心3 性能中心-Exadata总结 数据库管理-第146期 最强Oracle监控EMCC深入使用-03&#xff08;20240206&#xff09; 作者&#xff1a;胖头鱼的鱼缸&…

【大数据】Flink on YARN,如何确定 TaskManager 数

Flink on YARN&#xff0c;如何确定 TaskManager 数 1.问题2.并行度&#xff08;Parallelism&#xff09;3.任务槽&#xff08;Task Slot&#xff09;4.确定 TaskManager 数 1.问题 在 Flink 1.5 Release Notes 中&#xff0c;有这样一段话&#xff0c;直接上截图。 这说明从 …

Stable Diffusion 模型下载:majicMIX realistic 麦橘写实 - V7

文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 非常推荐的一个写实模型&#xff0c;由国人“Merjic”发布&#xff0c;下载量颇高。这款大模型带来非常高的写实度以及光影感&#xff0c;特别是光线在画面中生成的…

【JS逆向一】逆向某站的 加密参数算法--仅供学习参考

逆向日期&#xff1a;2024.02.06 使用工具&#xff1a;Node.js 文章全程已做去敏处理&#xff01;&#xff01;&#xff01; 【需要做的可联系我】 可使用AES进行解密处理&#xff08;直接解密即可&#xff09;&#xff1a;在线AES加解密工具 1、打开某某网站(请使用文章开头的…

模拟串口LV2,解决硬件串口资源不足问题!!!!

模拟串口通信 2.0 版本&#xff01;&#xff01; 我在前面的文章里面有写了 虚拟串口通信&#xff0c;虽然说能用&#xff0c;但是用过的小伙伴都说 “好!” 优缺点: 先说一点&#xff0c;2.0版本并不适用于同硬件串口的所有场合&#xff0c;仅仅针对自己开发的电子垃圾的主…

用HTML5 + JavaScript实现下雪效果

用HTML5 JavaScript实现下雪效果 <canvas>是一个可以使用脚本 (通常为JavaScript) 来绘制图形的 HTML 元素。 <canvas> 标签/元素只是图形容器&#xff0c;必须使用脚本来绘制图形。 HTML5 canvas 图形标签基础https://blog.csdn.net/cnds123/article/details/…

架构(十三)动态本地锁

一、引言 加锁大家都知道&#xff0c;但是目前提供动态锁的基本都是分布式锁&#xff0c;根据订单或者某个收费款项进行加锁。比如这个1订单要收刷卡费用&#xff0c;那就OREDER_1做为key丢到redis进行分布式加锁。这也是当下分布式锁最流行的方式。 但是对于平台项目或者一些并…

飞天使-k8s知识点14-kubernetes散装知识点3-Service与Ingress服务发现控制器

文章目录 Service与Ingress服务发现控制器存储、配置与角色 Service与Ingress服务发现控制器 在 Kubernetes 中&#xff0c;Service 和 Ingress 是两种不同的资源类型&#xff0c;它们都用于处理网络流量&#xff0c;但用途和工作方式有所不同。Service 是 Kubernetes 中的一个…

redis:七、集群方案(主从复制、哨兵模式、分片集群)和面试模板

redis集群方案 在Redis中提供的集群方案总共有三种&#xff08;一般一个redis节点不超过10G内存&#xff09; 主从复制哨兵模式分片集群 主从复制&#xff08;主从数据同步&#xff09; replid和offset Replication Id&#xff1a;简称replid&#xff0c;是数据集的标记&a…

回归预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多变量回归预测

回归预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多变量回归预测 目录 回归预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现POA-BP鹈鹕算法优化BP神经网络多变量回归预测&#xff08;完整源码…

Java LinkedList 实现栈和队列

Java LinkedList 实现栈和队列 package com.zhong.collection;import java.util.LinkedList;public class LinkedListDemo {public static void main(String[] args) {// LinkedList 创建一个队列LinkedList<String> queue new LinkedList<>();// 进队System.out…

大华 DSS 数字监控系统 attachment_getAttList.action SQL 注入漏洞复现

0x01 产品简介 大华 DSS 数字监控系统是大华开发的一款安防视频监控系统,拥有实时监视、云台操作、录像回放、报警处理、设备管理等功能。 0x02 漏洞概述 大华 DSS存在SQL注入漏洞,攻击者 /portal/attachment_getAttList.action 路由发送特殊构造的数据包,利用报错注入获…

git合入的parents和child

最近在管理代码&#xff0c;有2的权限&#xff0c;看到一些以前1看不到的东西。 有时候会遇到多个人基于同一节点提交代码&#xff0c;那就要选择先合入和后合入&#xff0c;如果这多人修改到同一个文件同一个地方&#xff0c;就可能产生冲突&#xff0c;一般要避免这种情况出…

NLP_神经概率语言模型(NPLM)

文章目录 NPLM的起源NPLM的实现1.构建实验语料库2.生成NPLM训练数据3.定义NPLM4.实例化NPLM5.训练NPLM6.用NPLM预测新词 NPLM小结 NPLM的起源 在NPLM之前&#xff0c;传统的语言模型主要依赖于最基本的N-Gram技术&#xff0c;通过统计词汇的共现频率来计算词汇组合的概率。然而…