前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >负载均衡UDP监听器使用自定义健康检查

负载均衡UDP监听器使用自定义健康检查

原创
作者头像
zachz
修改2023-10-30 12:45:52
修改2023-10-30 12:45:52
56500
代码可运行
举报
运行总次数:0
代码可运行

背景

UDP健康检查使用PING,在大并发场景下,由于 Linux 有防 ICMP 攻击保护机制,会限制服务器发送 ICMP 的速度。此时,即使后端服务已经出现异常,但由于无法向 CLB 返回 port XX unreachable,CLB 由于没收到 ICMP 应答进而判定健康检查成功,最终导致后端服务的真实状态与健康检查不一致。

解决方案

在配置 UDP 健康检查时,配置自定义输入和输出,向后端服务器发送您指定的字符串,且 CLB 收到您指定的应答后才判断健康检查成功。此方案依赖后端服务器,后端服务器需处理健康检查输入并返回指定输出。

本文档介绍如何配置和测试自定义健康检查.

步骤

1、由于服务端收到CLB发送的指定字符串的报文后需要向CLB回复指定的应答内容,此处使用一个简单脚本udpHealthCheck.py模拟服务端程序。

代码语言:python
代码运行次数:0
运行
复制
import socket
from sys import argv

#健康检查请求
req = argv[1]

#健康检查返回结果
reply = argv[2]

#服务端口
port = int(argv[3])

# 定义服务器地址和端口
server_address = ('0.0.0.0', port)

# 创建UDP套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(server_address)

print("UDP server listening on", server_address)

while True:
    # 接收数据包
    data, client_address = sock.recvfrom(1024)
    data = data.decode('utf-8')

    print("Received from", client_address, ":", data)

    # 检查数据包是否包含特定内容
    if req in data:
        # 向发送方发送回复
        response = reply.encode('utf-8')
        sock.sendto(response, client_address)
        print("Sent response to", client_address)

sock.close()

2、CLB配置健康检查并绑定RS

可以看到此时后端RS未部署业务程序,未回复udp健康检查请求的情况下,RS的健康状态为异常。

3、服务端运行程序

运行业务程序,可以看到RS收到健康检查报文并回复,RS健康状态变为正常。

代码语言:shell
复制
[root@VM-2-15-centos ~]# python3 udpHealthCheck.py 'health check' 'i am good' 4455
UDP server listening on ('0.0.0.0', 4455)
Received from ('100.126.71.103', 62147) : health check
Sent response to ('100.126.71.103', 62147)
Received from ('100.126.62.45', 36289) : health check
Sent response to ('100.126.62.45', 36289)
Received from ('100.126.35.146', 35193) : health check
Sent response to ('100.126.35.146', 35193)
Received from ('100.126.72.44', 48635) : health check
Sent response to ('100.126.72.44', 48635)
Received from ('100.126.73.71', 55548) : health check
Sent response to ('100.126.73.71', 55548)

4、抓包观察

健康检查请求

健康检查回复

5、16进制和文本转换

UDP自动健康检查可以填写文本和16进制两种形式,此处介绍如何转换。

代码语言:python
代码运行次数:0
运行
复制
字符串转换为16进制(大写)
message = "i am good"
hex_str = ''.join([hex(ord(c))[2:] for c in message]).upper()
print(hex_str) #输出为6920616D20676F6F64

16进制转换为字符串
hex_str = "6920616D20676F6F64"
bytes_data = bytes.fromhex(hex_str)
str_data = bytes_data.decode('ascii')
print(str_data) #输出为i am good

6、健康检查形式

自定义健康检查的情况下,CLB发过来的健康探测只有udp请求,没有PING请求,符合避免 ICMP 攻击保护机制导致健康检查异常的初衷。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 解决方案
  • 步骤
    • 1、由于服务端收到CLB发送的指定字符串的报文后需要向CLB回复指定的应答内容,此处使用一个简单脚本udpHealthCheck.py模拟服务端程序。
    • 2、CLB配置健康检查并绑定RS
    • 3、服务端运行程序
    • 4、抓包观察
    • 5、16进制和文本转换
    • 6、健康检查形式
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档