通过UDP健康检查排查异常服务器

对于在线游戏、即时通讯等依赖UDP协议的业务,为保证玩家顺畅连接、提升用户体验,您可以使用UDP健康检查功能。该功能通过发送UDP数据包来监测后端服务器的响应情况,能够迅速识别和解决潜在问题,确保快速响应、及时进行故障检测,从而增强服务的可靠性和可用性。

用户场景

某在线游戏公司运营着多台后端服务器,这些服务器通过UDP协议处理玩家的游戏数据。为了确保玩家体验的流畅性,公司希望实时监控每台服务器的健康状态。当某台服务器出现异常时,能够迅速检测并隔离该服务器,此时新的玩家请求不会被发送到异常的服务器上,一旦服务器恢复正常,自动将其重新纳入服务,继续处理玩家请求。

该公司可以使用NLBUDP健康检查功能,定期检查每台后端服务器的状态。当检测到异常服务器时,NLB会自动停止向其转发新的请求,并在服务器恢复后自动重新启用。

image

前提条件

  • 您已在华东1(杭州)地域创建专有网络VPC,并在两个可用区内创建两台交换机VSW1、VSW2。具体操作,请参见创建和管理专有网络

  • 您已分别在VSW1VSW2创建ECS01ECS02实例。

  • 您已在VPC中创建一个处于运行中状态的NLB实例。本文以私网NLB实例为例进行配置说明。具体操作可参考创建和管理NLB实例

注意事项

  • 后端服务器部署UDP业务时,可以通过UDP、TCPHTTP健康检查方式监测其状态。然而,采用TCPHTTP健康检查需要额外开放TCP端口,这可能导致网络配置复杂并增加潜在的安全风险。特别是在CLB迁移到NLB的场景中,为了确保服务能力的一致性,建议您使用UDP健康检查。

  • 请确保后端服务器的安全组已放行用于UDP健康检查的端口。

配置流程

image

操作步骤

步骤一:部署服务

本文以CentOS 7.9为示例,演示使用Python快速部署一个可以响应UDP请求的服务。示例仅供参考,实际使用过程中以您自己开发的程序和服务为准。

ECS01上部署UDP请求服务

  1. 登录ECS01服务后台。

  2. 执行vi udp_server.py,按i键进入编辑模式。

    复制并粘贴如下代码:

    部署测试服务代码参考

    说明
    • 4行中的UDP_IPIP,需要修改为后端服务器ECS01的私网IP。

    • 5行中的UDP_PORT的端口号,需要修改为后端服务器的端口号。

    import socket
    
    # 配置UDP服务器的IP地址和端口号
    UDP_IP = "10.1.*.*"      # 替换为你的后端服务器IP
    UDP_PORT = 161            # 替换为你的后端服务器端口
    
    # 创建一个UDP套接字
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
        # 将套接字绑定到指定的IP地址和端口号
        sock.bind((UDP_IP, UDP_PORT))
        print("UDP server up and listening ")
    
        # 服务器持续运行
        while True:
            # 接收来自客户端的数据(数据缓冲区大小为1024字节)
            data, addr = sock.recvfrom(1024)
            print(f"Received message: {data} from {addr}")
    
            # 检查接收到的数据内容
            if data == b"PING1":
                sock.sendto(b"PONG1", addr)
                print("Sent PONG1")
    
    
  3. Esc键,输入:wq保存修改。

  4. 执行sudo python3 udp_server.py命令,即可运行脚本。

  5. 当收到如下回复信息时,表示UDP后端服务已开启。

    UDP server up and listening 
    

如果出现启动失败,需要排查下端口是否已被占用,或者命令及代码是否复制粘贴错误。

ECS02上部署UDP请求服务

  1. 登录ECS02服务后台。

  2. 执行vi udp_server.py,按i键进入编辑模式。

    复制并粘贴如下代码:

    部署测试服务代码参考

    说明
    • 4行中的UDP_IPIP,需要修改为后端服务器ECS02的私网IP。

    • 5行中的UDP_PORT的端口号,需要修改为后端服务器的端口号。

    import socket
    
    # 配置UDP服务器的IP地址和端口号
    UDP_IP = "10.2.*.*"   # 替换为你的后端服务器IP
    UDP_PORT = 161        # 替换为你的后端服务器端口
    
    # 创建一个UDP套接字
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
        # 将套接字绑定到指定的IP地址和端口号
        sock.bind((UDP_IP, UDP_PORT))
        print("UDP server up and listening ")
    
        # 服务器持续运行
        while True:
            # 接收来自客户端的数据(数据缓冲区大小为1024字节)
            data, addr = sock.recvfrom(1024)
            print(f"Received message: {data} from {addr}")
    
            # 检查接收到的数据内容
            if data == b"PING2":
                sock.sendto(b"PONG2", addr)
                print("Sent PONG2")
    
    
  3. Esc键,输入:wq保存修改。

  4. 执行sudo python3 udp_server.py命令,即可运行脚本。

  5. 当收到如下回复信息时,表示UDP后端服务已开启。

    UDP server up and listening
    

如果出现启动失败,需要排查下端口是否已被占用,或者命令及代码是否复制粘贴错误。

步骤二:创建服务器组并开启健康检查

  1. 登录网络型负载均衡NLB控制台

  2. 在顶部菜单栏,选择NLB实例所属的地域。

  3. 在左侧导航栏,选择网络型负载均衡NLB > 服务器组

  4. 服务器组页面,单击创建服务器组

  5. 创建服务器组对话框,配置以下信息。关键配置信息可参考下表配置,其余配置项保持默认值即可,如需修改可参考创建和管理服务器组

    配置

    说明

    服务器组类型

    选择服务器类型

    选择后端协议

    本文选择UDP协议。

    配置健康检查

    开启健康检查,并在健康检查配置右侧单击编辑

    健康检查协议

    本文选择UDP协议。

    健康检查端口

    本文选择使用后端服务器端口

  6. 服务器组信息配置完成后,单击创建。待服务器组创建成功后,在弹窗中单击添加后端服务器

  7. 添加后端服务器配置面板,选择ECS01ECS02,然后单击下一步

  8. 在配置端口和权重配置向导,输入端口161,权重保持默认值,然后单击确定,完成服务器添加。

步骤三:创建UDP监听

  1. 登录网络型负载均衡NLB控制台

  2. 在顶部菜单栏,选择NLB实例所属的地域。

  3. 实例页面,找到目标NLB实例,然后在操作列单击创建监听

  4. 负载均衡业务配置向导页面,配置以下信息。关键配置信息可参考下表配置,其余配置项保持默认值即可,如需修改可参考添加UDP监听。配置完成后单击提交

    配置监听:

    配置

    说明

    选择监听协议

    本文选择UDP监听。

    监听端口

    本文输入161

    选择服务器组:

    配置

    说明

    选择服务器组

    选择添加了ECS01ECS02的服务器组。

步骤四:测试验证

  1. 检测正常服务器

    1. 以该VPC内的任意一台Linux客户端为例进行测试验证。

      1. 执行vi udp_client.py,按i键进入编辑模式。

        复制并粘贴如下代码:

        部署测试服务代码参考

        说明

        以本文配置为例:

        • 若您需要访问后端服务器ECS01,第9行需要修改为PING1。

        • 若您需要访问后端服务器ECS02,第9行需要修改为PING2。

        import socket
        
        # 创建 UDP 套接字
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        
        server_address = ('10.0.*.*', 161)  # 替换为您NLB实例的VIP和监听端口
        
        # 发送数据
        message = "PING1"     # 访问ECS01替换为PING1,访问ECS02替换为PING2
        client_socket.sendto(message.encode(), server_address)
        
        # 接收响应
        data, address = client_socket.recvfrom(1024)
        print(f"Received data from server: {data.decode()}")
        
        # 关闭套接字
        client_socket.close()
        
      2. Esc键,输入:wq保存修改。

    2. 执行sudo python3 udp_client.py命令,收到如下图示的回复报文PONG1,表示ECS01服务器可以正常接收请求。

      ECS01客户端回复.png

    3. 执行sudo python3 udp_client.py命令,收到如下图示的回复报文PONG2,表示ECS02服务器可以正常接收请求。

      ECS02客户端回复.png

  2. 故障模拟

    修改后端服务器ECS01端口为80

    1. 在左侧导航栏,选择网络型负载均衡 NLB服务器组

    2. 服务器组页面,单击目标服务器组实例ID。

    3. 单击后端服务器页签,修改后端服务器ECS01端口为80

  3. 登录网络型负载均衡NLB控制台查看健康检查异常的原因。

    1. 实例页面,单击目标实例ID。

    2. 单击监听页签,在UDP监听的健康检查状态列查看健康检查状态为异常

    3. 单击异常,可以在弹出的对话框中查看异常的服务器和异常原因。本文异常的服务器和原因如下图所示。

      健康检查异常.png

    4. 在弹出的对话框中,单击实例诊断,在实例健康诊断面板,找到目标监听实例,在诊断结果列单击查看详情

    5. 诊断问题为后端服务器上的监听端口与健康检查端口不一致。

      原因.png

    说明

    您还可以通过以下方式进行健康检查异常排查:

    • 使用网络监控工具(如WiresharkTCPDump)捕获UDP流量并分析异常流量。具体操作,请参见网络异常时如何抓取数据包

    • 通过后端服务器所在主机的系统日志文件(如/var/log/messages)排查。

  4. 修改后端服务器ECS01端口为161,再次刷新NLB实例,健康检查状态显示正常

    健康检查正常.png

    说明

    若您的健康检查异常为其他原因,具体的解决方案,请参见NLB健康检查异常排查方法

关闭健康检查

重要

您可以关闭健康检查功能,但关闭健康检查后,当后端某个ECS出现异常时,NLB还是会把请求转发到该异常的ECS上,造成部分业务不可访问。因此一般情况下建议不要关闭健康检查。

  1. 登录网络型负载均衡NLB控制台

  2. 在顶部菜单栏,选择NLB实例所属的地域。

  3. 在左侧导航栏,选择网络型负载均衡 NLB服务器组

  4. 服务器组页面,找到目标服务器组,在操作列单击编辑健康检查

  5. 编辑健康检查对话框,关闭健康检查,然后单击保存

相关文档

如果您想要了解UDP健康检查的概述和原理,请参见NLB健康检查概述