狂自私

导航

端口复用-使用haproxy代理端口的http协议、mqtt协议的流量

现在有一个新的需求,21883端口需要同时代理mqtt协议和http协议的流量,所以需要实现端口复用,我先后尝试了nginx和haproxy,nginx那边我没有成功,使用haproxy成功了,记录一下。

haproxy,我使用过2.4.22-f8e3218和3.0.5-8e879a5版本,都可以通过以下配置实现需求:

global
    log stdout local0 info
    maxconn 20000
    daemon
    stats timeout 30s

defaults
    log     global  # 继承global的debug日志级别和输出方式
    mode    tcp
    option  tcplog
    option  dontlognull  # 不记录空请求,减少冗余
    option  logasap  # 尽早输出日志,避免连接断开后日志丢失
    option  redispatch
    retries 3
    timeout http-request 5s
    timeout queue 30s
    timeout connect 5s
    timeout client 30s
    timeout server 30s
    timeout tunnel 1h  # 适配MQTT长连接

frontend main_frontend
    bind :21883  # 业务端口
    mode tcp

    # 性能优化:300ms检测延迟,捕获首包
    tcp-request inspect-delay 300ms
    # 强制等待首包有数据(payload长度>0)后再分流,不允许提前转发
    tcp-request content accept if { req.len  gt 0 }
    # 若超过300ms仍无首包,默认拒绝(避免空连接占用资源,可选)
    tcp-request content reject if { req.len  eq 0 }
#
# | 消息类型               | 功能描述                                  | 高4位取值(二进制) | 首字节范围(十六进制) | 典型首字节示例 |
# |------------------------|-------------------------------------------|---------------------|------------------------|----------------|
# | CONNECT                | 客户端连接到服务器                        | 0001                | 10 ~ 1F                | 10(标志位全0)|
# | CONNACK                | 服务器响应客户端连接请求                  | 0010                | 20 ~ 2F                | 20(标志位固定0)|
# | PUBLISH                | 客户端/服务器发送消息(最核心类型)       | 0011                | 30 ~ 3F                | 30(QoS 0)、31(QoS 1)|
# | PUBACK                 | 响应 PUBLISH(QoS 1)                     | 0100                | 40 ~ 4F                | 40(标志位固定0)|
# | PUBREC                 | 响应 PUBLISH(QoS 2 第一步)              | 0101                | 50 ~ 5F                | 50(标志位固定0)|
# | PUBREL                 | 响应 PUBREC(QoS 2 第二步)               | 0110                | 60 ~ 6F                | 62(标志位固定2)|
# | PUBCOMP                | 响应 PUBREL(QoS 2 第三步)               | 0111                | 70 ~ 7F                | 70(标志位固定0)|
# | SUBSCRIBE              | 客户端订阅主题                            | 1000                | 80 ~ 8F                | 82(标志位固定2)|
# | SUBACK                 | 服务器响应订阅请求                        | 1001                | 90 ~ 9F                | 90(标志位固定0)|
# | UNSUBSCRIBE            | 客户端取消订阅                            | 1010                | A0 ~ AF                | A2(标志位固定2)|
# | UNSUBACK               | 服务器响应取消订阅                        | 1011                | B0 ~ BF                | B0(标志位固定0)|
# | PINGREQ                | 客户端发送心跳请求                        | 1100                | C0 ~ CF                | C0(标志位固定0)|
# | PINGRESP               | 服务器响应心跳请求                        | 1101                | D0 ~ DF                | D0(标志位固定0)|
# | DISCONNECT             | 客户端/服务器断开连接                     | 1110                | E0 ~ EF                | E0(标志位固定0)|

    # # 简化MQTT检测
    acl is_mqtt_10 req.payload(0,1) -m bin 10    # 客户端连接到服务器
    # acl is_mqtt_20 req.payload(0,1) -m bin 20    # 服务器响应客户端连接请求
    acl is_mqtt_30 req.payload(0,1) -m bin 30    # 客户端/服务器发送消息
    acl is_mqtt_31 req.payload(0,1) -m bin 31    # 客户端/服务器发送消息
    acl is_mqtt_32 req.payload(0,1) -m bin 32    # 客户端/服务器发送消息
    acl is_mqtt_82 req.payload(0,1) -m bin 82    # 客户端订阅主题
    # acl is_mqtt_90 req.payload(0,1) -m bin 90    # 服务器响应订阅请求
    acl is_mqtt_A2 req.payload(0,1) -m bin a2    # 客户端取消订阅
    acl is_mqtt_B0 req.payload(0,1) -m bin b0    # 服务器响应取消订阅
    acl is_mqtt_D0 req.payload(0,1) -m bin d0    # 服务器响应心跳请求
    acl is_mqtt_E0 req.payload(0,1) -m bin e0    # 客户端/服务器断开连接

    # 分流规则:MQTT优先,默认走HTTP
    # use_backend mqtt_servers if is_mqtt_10 or is_mqtt_20 or is_mqtt_30 or is_mqtt_31 or is_mqtt_32 or is_mqtt_82 or is_mqtt_90 or is_mqtt_A2 or is_mqtt_B0 or is_mqtt_D0 or is_mqtt_E0
    use_backend mqtt_servers if is_mqtt_10 or is_mqtt_30 or is_mqtt_31 or is_mqtt_32 or is_mqtt_82 or is_mqtt_A2 or is_mqtt_B0 or is_mqtt_D0 or is_mqtt_E0
    default_backend http_servers

backend http_servers
    mode http
    balance roundrobin
    option httpchk  # HTTP健康检查
    http-check send meth OPTIONS uri / ver HTTP/1.1 hdr Host localhost
#    server http_server1 192.168.50.22:10008 check maxconn 1000  # 后端健康检查
    server http_server1 192.168.50.22:10008

backend mqtt_servers
    mode tcp
    balance source  # 源IP哈希,MQTT重连不换后端
#    server mqtt_server1 xx.xx.x.xx:1883 check maxconn 5000  # MQTT后端
    server mqtt_server1 xx.xx.xx.xx:1883

2.4.22版本是在主机上部署的,所以关于日志的部分应该要更改下。

3.0.5版本我是容器化部署的,日志的那部分可以不用改;

部分日志输出:

[NOTICE]   (1) : haproxy version is 3.0.5-8e879a5
[NOTICE]   (1) : path to executable is /usr/local/sbin/haproxy
[WARNING]  (1) : Exiting Master process...
[WARNING]  (8) : Proxy main_frontend stopped (cumulated conns: FE: 25, BE: 0).
[WARNING]  (8) : Proxy http_servers stopped (cumulated conns: FE: 0, BE: 27).
[WARNING]  (8) : Proxy mqtt_servers stopped (cumulated conns: FE: 0, BE: 1).
<132>Sep 10 05:18:15 haproxy[8]: Proxy main_frontend stopped (cumulated conns: FE: 25, BE: 0).
<132>Sep 10 05:18:15 haproxy[8]: Proxy http_servers stopped (cumulated conns: FE: 0, BE: 27).
<132>Sep 10 05:18:15 haproxy[8]: Proxy mqtt_servers stopped (cumulated conns: FE: 0, BE: 1).
[WARNING]  (1) : Current worker (8) exited with code 0 (Exit)
[WARNING]  (1) : All workers exited. Exiting... (0)
[NOTICE]   (1) : New worker (9) forked
[NOTICE]   (1) : Loading success.
<134>Sep 10 05:18:31 haproxy[9]: 192.168.50.25:2674 [10/Sep/2025:05:18:31.939] main_frontend mqtt_servers/mqtt_server1 8/6/+13 +0 -- 1/1/1/1/0 0/0
<134>Sep 10 06:09:58 haproxy[9]: 192.168.50.25:3817 [10/Sep/2025:06:09:58.609] main_frontend mqtt_servers/mqtt_server1 7/6/+12 +0 -- 1/1/1/1/0 0/0
<134>Sep 10 06:10:10 haproxy[9]: 192.168.50.194:46212 [10/Sep/2025:06:10:10.570] main_frontend http_servers/http_server1 0/0/+1 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:11 haproxy[9]: 192.168.50.194:46226 [10/Sep/2025:06:10:11.588] main_frontend http_servers/http_server1 0/0/+2 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:12 haproxy[9]: 192.168.50.194:46230 [10/Sep/2025:06:10:12.607] main_frontend http_servers/http_server1 0/0/+1 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:13 haproxy[9]: 192.168.50.194:46232 [10/Sep/2025:06:10:13.626] main_frontend http_servers/http_server1 0/0/+1 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:14 haproxy[9]: 192.168.50.194:46242 [10/Sep/2025:06:10:14.645] main_frontend http_servers/http_server1 0/0/+0 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:15 haproxy[9]: 192.168.50.194:46250 [10/Sep/2025:06:10:15.659] main_frontend http_servers/http_server1 0/0/+1 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:16 haproxy[9]: 192.168.50.194:46256 [10/Sep/2025:06:10:16.677] main_frontend http_servers/http_server1 0/0/+0 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:17 haproxy[9]: 192.168.50.194:46260 [10/Sep/2025:06:10:17.690] main_frontend http_servers/http_server1 0/0/+0 +202 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:18 haproxy[9]: 192.168.50.194:46272 [10/Sep/2025:06:10:18.705] main_frontend http_servers/http_server1 0/0/+1 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:19 haproxy[9]: 192.168.50.194:46280 [10/Sep/2025:06:10:19.726] main_frontend http_servers/http_server1 0/0/+1 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:20 haproxy[9]: 192.168.50.194:36492 [10/Sep/2025:06:10:20.745] main_frontend http_servers/http_server1 0/0/+0 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:21 haproxy[9]: 192.168.50.194:36502 [10/Sep/2025:06:10:21.756] main_frontend http_servers/http_server1 0/0/+1 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:22 haproxy[9]: 192.168.50.194:36514 [10/Sep/2025:06:10:22.769] main_frontend http_servers/http_server1 0/0/+1 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:23 haproxy[9]: 192.168.50.194:36528 [10/Sep/2025:06:10:23.787] main_frontend http_servers/http_server1 0/0/+1 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:24 haproxy[9]: 192.168.50.194:36542 [10/Sep/2025:06:10:24.807] main_frontend http_servers/http_server1 0/0/+1 +202 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:25 haproxy[9]: 192.168.50.194:36556 [10/Sep/2025:06:10:25.826] main_frontend http_servers/http_server1 0/0/+0 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:26 haproxy[9]: 192.168.50.194:36568 [10/Sep/2025:06:10:26.838] main_frontend http_servers/http_server1 0/0/+0 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:10:27 haproxy[9]: 192.168.50.194:36578 [10/Sep/2025:06:10:27.850] main_frontend http_servers/http_server1 0/0/+1 +2349 -- 2/2/1/1/0 0/0
<134>Sep 10 06:25:37 haproxy[9]: 192.168.50.25:10005 [10/Sep/2025:06:25:37.169] main_frontend mqtt_servers/mqtt_server1 8/6/+13 +0 -- 1/1/1/1/0 0/0

 

posted on 2025-09-10 15:00  狂自私  阅读(19)  评论(0)    收藏  举报