Tengine 的xquic,如何适配四层负载的udp健康检查?

news/2024/5/18 15:29:29 标签: udp, 网络协议, 网络

udp_0">为什么要适配udp健康检查?

Tengine通过xquic实现HTTP3协议,不同于HTTP2和HTTP1.1以及之前的HTTP协议,HTTP3最大的不同就是其传输层协议由TCP改成了基于UDP实现的QUIC协议。QUIC 协议实现在用户态,建立在内核态的 UDP 的基础之上,集成了 TCP 的可靠传输特性,集成了 TLS1.3 协议,保证了用户数据传输的安全。不过HTTP3具体的特性不是本文的重点,我们在适配HTTP3的过程中遇到了许多问题,本文主要介绍关于UDP健康检查的部分。

Tengine作为Nginx的一个重要分支,在应用中常作为7层负载均衡使用。但在实际的生产中,7层负载均衡服务之前往往还有lvs这种4层负载均衡服务。为了保证高可用,就少不了在lvs 和 Tengine之前需要做健康检查探测。

常见的健康检查模式

TCP协议的健康检查一般通过TCP三次握手来检查,握手成功即代表服务可用。但是UDP的协议没有连接状态,默认不会回复任何内容,所以它的健康检查要麻烦一些。

目前比较常见的UDP健康检查主要有两种。

方法一

通过UDP报文加ICMP协议进行UDP端口探测,比如nmap命令

sudo nmap -sU 127.0.0.1 -p 123

返回

PORT     STATE         SERVICE
123/udp open|filtered powerclientcsf

它的检查逻辑大致是向目标端口发送一个UDP报文,并且对对端IP进行一次ping探测,如果主机可达且未收到ICMP的port unreachable报错(端口未监听,类似于TCP协议会回复rst)则认为是服务正常,否则则为服务异常。

但这个探测逻辑有个缺陷,如果服务器能ping通,但是假死;或者有防火墙策略,drop了指定端口的UDP报文,这些情况下能通过健康检查探测,但服务其实是不可用的。

方法二

另一种就是偏应用层探测。向服务发送特定的UDP报文,服务需要在指定时间内回复相应的UDP报文,才会认为服务健康。但是这种健康检查需要服务测适配。

udp_28">Tengine的 udp健康检查适配

Tengine是通过xquic实现的quic协议。xquic模块是可以通过方法2来实现被健康检查探测。在xquic的ngx_xquic_recv.h中,定义了3个宏:

#define NGX_XQUIC_HEALTH_CHECK  "Healthcheck"
#define NGX_XQUIC_HEALTH_CHECK_REQ  "UDPSTATUS"
#define NGX_XQUIC_HEALTH_CHECK_RSP  "UDPOK"

这三个宏的作用是,如果UDP 报文的payload中以NGX_XQUIC_HEALTH_CHECK 定义的字符串开头,则会认为是健康检查探测包,跳过后续流程。

如果UDP 报文的payload 为 NGX_XQUIC_HEALTH_CHECK_REQ 定义的字符串,则会返回payload为 NGX_XQUIC_HEALTH_CHECK_RSP 定义的字符串。通过这个配置即可自定义实现上面方法二的探测。

但是这个种方式定义的字符串有特定条件才能适配。因为xquic模块在进行健康检查报文检测之前会先做一个 quic头检测

    /* check QUIC magic bit */
    if (!NGX_XQUIC_CHECK_MAGIC_BIT(packet->buf)) {
        ngx_log_error(NGX_LOG_WARN, c->log, 0,
                      "|xquic|invalid packet head|");
        return;
    }


#define NGX_XQUIC_CHECK_MAGIC_BIT(pos) (((*(pos)) & 0x40) == 0x40)

这个校验逻辑很简单,检查UDPpayload里第一个字节第二位是否为1。但是这导致健康检查字符串的第一个字符也必须符合这个特点。比如a-zA-Z可以通过,但是数字不可以。具体可以查下ascii表。

如果已经约定好了UDP健康检查的字符串,通过修改 NGX_XQUIC_HEALTH_CHECK_REQ和NGX_XQUIC_HEALTH_CHECK_RSP “UDPOK” 重新编译一下就可以适配了。


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

相关文章

阿里云数据库怎么使用?从购买到数据库连接教程

阿里云数据库怎么使用?阿里云服务器网aliyunfuwuqi.com整理阿里云数据库从购买到使用全流程,阿里云支持MySQL、SQL Server、PostgreSQL和MariaDB等数据库引擎,阿里云数据库具有高可用、高容灾特性,阿里云提供数据库备份、恢复、迁…

C语言指针与数组(不适合初学者版):一篇文章带你深入了解指针与数组!

🎈个人主页:JAMES别扣了 💕在校大学生一枚。对IT有着极其浓厚的兴趣 ✨系列专栏目前为C语言初阶、后续会更新c语言的学习方法以及c题目分享. 😍希望我的文章对大家有着不一样的帮助,欢迎大家关注我,我也会回…

ArcGIS学习(十六)基于交通网络的城市情景分析

ArcGIS学习(十六)基于交通网络的城市情景分析 本任务给大家带来一个非常重要的内容一一基于交通网络的城市情景分析。基于交通网络模拟交通出行并进行相关分析是ArcGIS里面一种常用的分析方法,大家一定要掌握!本任务包括三个关卡: 交通网络模型构建基于交通网络模型的基本…

嵌入式学习日记 27

TCP包头: 1.序号:发送端发送数据包的编号 2.确认号:已经确认接收到的数据的编号(只有当ACK为1时,确认号才有用) TCP为什么安全可靠: 1.在通信前建立三次握手连接 SYN SYNACK ACK 2.在通信过程中通过序列号和确认号保障数据传输的完整性 本次发送序列号:上次…

Cloudways搭建WordPress外贸独立站完整教程

现在做个网站不比从前了,搭建网站非常的简单,主要是由于开源的CMS建站系统的崛起,就算不懂编程写代码的人也能搭建一个自己的网站,这些CMS系统提供了丰富的主题模板和插件,使用户可以通过简单的拖放和配置操作来建立自…

XSS_lab(level11-level18)

level11: 还是url这里,输入:<script>alert(1)</script> 与上一题相似 构建:?t_link1&t_history2&t_sort3&t_ref4 我们发现t_sort是可用的 构建:?t_sort1" type"button" οnclickalert(1) // 把双引号过滤了 这里无法使用实体编码…

论文阅读——VSA

VSA: Learning Varied-Size Window Attention in Vision Transformers 方法&#xff1a; 给定输入特征X&#xff0c;VSA首先按照基线方法的例程&#xff0c;将这些标记划分为几个窗口Xw&#xff0c;窗口大小为预定义的w。我们将这些窗口称为默认窗口&#xff0c;并从默认窗口中…

【Git】error: bad signature 0xb86f1e1 和 bfatal: index file corrupt

一、问题 之前都好好的&#xff0c;今天执行 git add .的时候突然报错 报错原因翻译成中文&#xff1a;索引文件损坏 二、解决方法 方法1&#xff1a; 删除.git隐藏文件夹中的index文件 然后执行 git reset 重新生成index文件 git reset 方法2&#xff1a; 重新从远程克隆…