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

news/2024/5/18 14:26:52 标签: nginx, http, udp, 健康检测, upstream, tengine, 源码实现
http://www.w3.org/2000/svg" style="display: none;">

目录

本篇对ngx_http_upstream_check_module的源码进行扩展,来实现udp健康检查功能。

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

7. 实现一个UDP健康检测功能

7.1 功能定义

  • 支持后端UDP请求定义
  • 支持通过nginx配置发送一个用户自定义的请求包
  • 支持通过nginx配置希望从上游服务器响应的报文内容,通过比对实际响应内容和希望的响应内容来判断上游服务器是否正常
  • 允许配置的希望响应报文内容部分匹配就认为OK
  • 允许用text字符串或者16进制编码的方式来设置请求报文内容和响应报文内容

7.2 定义一个新的健康检测类型

static ngx_check_conf_t  ngx_check_types[] = {
   
......
    {
    NGX_HTTP_CHECK_UDP,
      ngx_string("udp"),
      ngx_null_string,
      0,
      ngx_http_upstream_check_send_handler,
      ngx_http_upstream_check_recv_handler,
      ngx_http_upstream_check_udp_init,
      ngx_http_upstream_check_udp_parse,
      ngx_http_upstream_check_udp_reinit,
      1,
      0 },
......
      
这里定义了名称为udp的新的健康检测类型,其中ngx_http_upstream_check_send_handler和ngx_http_upstream_check_recv_handler两个回调函数是复用原先的实现的,而ngx_http_upstream_check_udp_init、ngx_http_upstream_check_udp_parse和ngx_http_upstream_check_udp_reinit是需要后面重新来实现的。这几个函数的实现留待后面来阐述。

其中NGX_HTTP_CHECK_UDP定义为:
	#define NGX_HTTP_CHECK_UDP                   0X0020

udp_45">7.3 增加udp特定的健康检测需要的配置指令

static ngx_command_t  ngx_http_upstream_check_commands[] = {
   
......
    {
    ngx_string("check_udp_send"),
      NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1,
      ngx_http_upstream_check_udp_send,
      0,
      0,
      NULL },
    {
    ngx_string("check_udp_expect"),
        NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
        ngx_http_upstream_check_udp_expect,
        0,
        0,
        NULL },
......
}

http_upstream_check_srv_conf_s_66">7.3.1 ngx_http_upstream_check_srv_conf_s结构体的扩展

为了保存解析到的配置信息,需要对ngx_http_upstream_check_srv_conf_s结构体进行扩展,增加4个字段,定义如下:

struct ngx_http_upstream_check_srv_conf_s {
   
    ngx_uint_t                 port;
    ngx_uint_t                 fall_count;
    ngx_uint_t                 rise_count;
    ngx_msec_t                 check_interval;
    ngx_msec_t                 check_timeout;
    ngx_uint_t                 check_keepalive_requests;

    ngx_check_conf_t          *check_type_conf;
    ngx_str_t                  send;

    union {
   
        ngx_uint_t             return_code;
        ngx_uint_t             status_alive;
    } code;

    ngx_array_t               *fastcgi_params;

    ngx_uint_t                default_down;
    ngx_uint_t                unique;
    ngx_uint_t                udp : 1;       /* 是否udp socket */
    ngx_int_t                 match_part : 1; /* 是否只要部分匹配就可以了 */
    ngx_int_t                 match_offset; /* udp响应期望的内容从哪个字节开始匹配 */
    ngx_str_t                 expect;   /* udp响应的期望内容 */
};

udp_send_100">7.3.2 check_udp_send的实现

check_udp_send配置指令用来读取准备发送到上游服务器的报文内容,格式如下:
   check_udp_send [raw:|text:]packet   
如果指定了raw格式,那么packet中的内容就是用16进制编码的报文,如果用text格式,那么packet内容就是一个普通的字符串,如果没有指定raw或者text,那么默认是text格式。

下面来实现check_udp_send配置指令的解析函数ngx_http_upstream_check_udp_send函数:

static char *ngx_http_upstream_check_udp_send(ngx_conf_t *cf,
    ngx_command_t *cmd, void *conf)
{
   
    ngx_str_t                           *value;
    ngx_http_upstream_check_srv_conf_t  *ucscf;
    ngx_str_t                            tmp;
    ngx_str_t                            content;
    ngx_int_t                            r;

    value = cf->args->elts;

    ucscf = ngx_http_conf_get_module_srv_conf(cf,
                                              ngx_http_upstream_check_module);

	/* 如果是text格式,直接取text:后的字符内容即可 */
    if (value[1].len > 5 && ngx_strncmp(value[1].data, "text:", 5) == 0) {
   
        ucscf->send.data = value[1].data + 5;
        ucscf->send.len  = value[1].len - 5;

    } /* 如果是raw格式,则需要进行16进制的解码 */
    else if(value[1].len > 4 && ngx_strncmp(value[1].data, "raw:", 4) == 0) {
   

http://www.niftyadmin.cn/n/5368151.html

相关文章

IDEA生成可执行jar包

1. 进入需要打包的项目,选择 最上方菜单栏的 File → Project Structure 2. 选择 左侧菜单栏 Artifacts → 加号 → JAR → from modules with dependencies 3. 选择入口类 Main Class(点击文件夹图标可以快速选择),点击 OK&#…

python实现飞书群机器人消息通知(消息卡片)

python实现飞书群机器人消息通知 直接上代码 """ 飞书群机器人发送通知 """ import time import urllib3 import datetimeurllib3.disable_warnings()class FlybookRobotAlert():def __init__(self):self.webhook webhook_urlself.headers {…

Android编程权威指南(第四版)-第 2 章 Android与MVC设计模式

文章目录 代码MainActivityQuestionactivity_main.xmlstring.xml效果知识点代码 大体是一样的,修改了一些 MainActivity package com.example.geoquizimport androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.Gravity import andro…

Java中List有哪些实现类

什么是List接口?它有哪些实现类? List接口是Java集合框架(Java Collections Framework)中的一个核心接口,它定义了一个有序的集合(也称为序列)。List集合中的元素是以线性方式存储的&#xff0…

泛型、Trait 和生命周期(上)

目录 1、提取函数来减少重复 2、在函数定义中使用泛型 3、结构体定义中的泛型 4、枚举定义中的泛型 5、方法定义中的泛型 6、泛型代码的性能 每一门编程语言都有高效处理重复概念的工具。在 Rust 中其工具之一就是 泛型(generics)。泛型是具体类型…

Qt 常见容器类用法(二)

目录 QList类 QLinkedList类 QList类 对于不同的数据类型&#xff0c;QList<T>采取不同的存储策略&#xff0c;存储策略如下&#xff1a; 如果T是一个指针类型或指针大小的基本数据类型(该基本类型占有的字节数和指针类型占有的字节数相同)&#xff0c;QList<T>…

解决Pygame精灵会跳但不会走的问题

根据我从事几年游戏开发的经验&#xff0c;我们知道在Pygame中&#xff0c;精灵&#xff08;Sprite&#xff09;是游戏中的基本元素&#xff0c;通常代表游戏中的角色、物体或动画。精灵可以执行各种动作&#xff0c;包括移动、跳跃、碰撞检测等。但是如果我们遇到Pygame精灵能…

SD-WAN:轻松穿越网络壁垒的利器

在当今信息时代&#xff0c;企业面临着越来越复杂的网络环境和日益增长的数据需求。随着企业的规模扩大和业务范围拓展&#xff0c;传统的网络架构已经无法满足其灵活性、性能和安全性的要求。SD-WAN作为一种新兴的网络技术&#xff0c;正成为企业解决这些问题的利器。 1、拓展…