EMQX集群搭建之(二)、Haproxy部分

基础知识

## Haproxy 相关
    1、Haproxy 2.4 之后的版本支持 配置 MQTT 粘性(Sticky)会话负载均衡
    2、要让后端EMQX 集群获取客户端的原始IP,需要开启 透传代理 send-proxy
    3、haproxy 可以与 Prometheus 集成

准备haproxy 的 docker-compose.yml

## 拉取 haproxy 镜像,并创建指定目录
    docker pull haproxy:2.8
    mkdir -p /opt/devops/haproxy
    cat > /opt/devops/haproxy/docker-compose.yml <<"EOOF"
services:
  haproxy:
    image: haproxy:2.8  # 使用 HAProxy 2.8 版本
    container_name: haproxy
    #ports:
    #  - "8888:8888"
    #  - "1883:1883"
    volumes:
      - ./haproxy.cfg:/etc/haproxy.cfg:ro  # 挂载自定义配置文件
      #- ./certs/:/certs/
    command: ["haproxy", "-f", "/etc/haproxy.cfg"]
    network_mode: host
    restart: always
EOOF

准备haproxy 的配置文件 haproxy.cfg

    cat  /opt/devops/haproxy/haproxy.cfg
# HAProxy 配置文件
global  
  log 127.0.0.1 local3 info
  daemon
  maxconn 1024000

defaults
  log global
  mode tcp
  option tcplog
  #option dontlognull
  timeout connect 10000 
  # timeout > mqtt's keepalive * 1.2
  timeout client 240s
  timeout server 240s

#=============== 启用 haproxy 的 状态检查页面 ==============
frontend stats
  mode http
  bind *:8888
  stats enable
  stats uri /haproxy?stats
  stats refresh 5s

#============== pull 方式与 Prometheus 集成 ==============
userlist prom_users
  user admin insecure-password admin@123

frontend prometheus
  bind *:8889
  mode http
  # 先做 Basic Auth:只要没通过就返回 401
  http-request auth realm "Metrics" if !{ http_auth(prom_users) }
  # 认证通过后,不论请求路径,直接返回 Prometheus 格式的指标
  http-request use-service prometheus-exporter
  # 不记录日志,避免大量拉取请求干扰
  no log

#============== 负载 EMQX 的 Dashboard ===========
frontend emqx_dashboard
    bind *:18083
    option tcplog
    mode tcp
    default_backend emqx_dashboard

backend emqx_dashboard
    balance roundrobin
    server emqx_node1 192.168.60.82:18083 check
    server emqx_node2 192.168.60.83:18083 check

#=============== 支持 ipv4 的 MQTT Over TCP ========
# 配置 MQTT 粘性(Sticky)会话负载均衡(haproxy 2.4引入的特性)
frontend emqx_mqtt_tcp_back
  bind *:1883
  mode tcp
  # 等待缓冲区填满,以便解析 MQTT 报文
  tcp-request inspect-delay 10s
  # 拒绝非 MQTT 连接
  tcp-request content reject unless { req.payload(0,0), mqtt_is_valid }
  default_backend emqx_mqtt_tcp_back

backend emqx_mqtt_tcp_back
  mode tcp
  # balance roundrobin
  # 创建粘性会话表
  stick-table type string len 32 size 100k expire 30m
  # 使用客户端 ID 作为键(注意写法,不能有空格)
  stick on req.payload(0,0),mqtt_field_value(connect,client_identifier)

 # 增加 send-proxy 会把真实带给 EMQX,对应后端监听器需要启用 proxy_protocol
  # server emqx1 emqx1-cluster.emqx.io:1883 check send-proxy-v2-ssl-cn
  server emqx_node1 192.168.60.82:1883 check send-proxy
  server emqx_node2 192.168.60.83:1883 check send-proxy
  # server emqx1 emqx1-cluster.emqx.io:1883 check weight 5

#=============== 支持 ipv6 的 MQTT Over TCP ========
frontend emqx_mqtt_tcp_back_v6
  bind [::]:1883
  mode tcp
  tcp-request inspect-delay 10s
  tcp-request content reject unless { req.payload(0,0), mqtt_is_valid }
  default_backend emqx_mqtt_tcp_back_v6

backend emqx_mqtt_tcp_back_v6
  mode tcp
  stick-table type string len 32 size 100k expire 30m
  stick on req.payload(0,0),mqtt_field_value(connect,client_identifier)

 # 增加 send-proxy 会把真实带给 EMQX,对应后端监听器需要启用 proxy_protocol
  # server emqx1 emqx1-cluster.emqx.io:1883 check send-proxy-v2-ssl-cn
  server emqx_node1 [2408:8362:2482:6ba4:be24:11ff:fe93:7244]:1883 check send-proxy-v2
  server emqx_node2 [2408:8362:2482:6ba4:be24:11ff:fe04:29b5]:1883 check send-proxy-v2

启动haproxy

## 启动 haproxy
    cd /opt/devops/haproxy
    docker compose up -d

附1、开启haproxy 的stats 统计页面

## 在 haproxy.cfg 内添加如下内容
frontend stats
  mode http
  bind *:8888
  stats enable
  stats uri /haproxy?stats
  stats refresh 5s

## 重启haproxy
    cd /opt/devops/haproxy
    docker compose restart
    http://ipaddress:8888/haproxy?stats    # 访问这个页面查看stats信息

附2、haproxy 配置与 Prometheus 集成(2.8版本不需要单独的exporter)

方案A、不带认证的方式

## A1、在haproxy.cfg 内添加如下内容
frontend prometheus
    bind *:8889
    mode http
    # 仅当访问 /metrics 时,才调用 prometheus-exporter 服务
    http-request use-service prometheus-exporter if { path /metrics }
    no log

## A2、prometheus.yml 这样添加 job
  - job_name: 'haproxy'
    metrics_path: /metrics          # 与 HAProxy 上配置的 path 保持一致
    static_configs:
      - targets: ['192.168.60.81:8889']
    params:
      # 可以指定只抓取哪些 scope 的指标,* 表示全部
      scope: ['frontend','backend','server']
      # 如果有维护中 (maintenance) 的 server,使用 no-maint 过滤掉
      no-maint: ['']
    relabel_configs:
      - source_labels: [__address__]
        regex: '(.+):\d+'
        replacement: '${1}'
        target_label: instance

## A3、分别重启haproxy ,重载 Prometheus
    cd /opt/devops/haproxy
    docker compose restart
    http://ipaddress:8889/metrics    # 访问这个页面就能看到指标

方案B、带Basic Auth 认证的方式

### B1、在haproxy.cfg 内添加如下内容
# 1. 定义监控用户admin 和他的密码(Basic Auth)
userlist prom_users
  user admin insecure-password admin@123

# 2. 简化版的 metrics 前端
frontend prometheus
    bind *:8889
    mode http
    # 先做 Basic Auth:只要没通过就返回 401
    http-request auth realm "Metrics" if !{ http_auth(prom_users) }
    # 认证通过后,不论请求路径,直接返回 Prometheus 格式的指标
    http-request use-service prometheus-exporter
    # 不记录日志,避免大量拉取请求干扰
    no log

### B2、prometheus.yml 这样添加 job
  - job_name: 'haproxy_emqx'
    metrics_path: /metrics     # 必须和 HAProxy 上配置的 path 保持一致
    basic_auth:
      username: admin
      password: admin@123
    static_configs:
      - targets: ['192.168.60.81:8889']  # 改成你的 HAProxy 地址或 IP
    params:
      # 可选参数,用来过滤只抓取哪些 scope
      scope: ['frontend','backend','server']
      # no-maint 参数可过滤掉正在 maintenance 的 Server
      no-maint: ['']
    relabel_configs:
      - source_labels: [__address__]
        regex: '(.+):\d+'
        replacement: '${1}'
        target_label: instance

### B3、重启haproxy,重载Prometheus
    cd /opt/devops/haproxy
    docker compose restart
    http://192.168.60.81:8889/metrics    # 访问这个页面就能看到指标(需先认证)

导入 grafana 图表(可用id 12693、2428、367)

声明:本文为原创,作者为 辣条①号,转载时请保留本声明及附带文章链接:https://boke.wsfnk.com/archives/1475.html
谢谢你请我吃辣条谢谢你请我吃辣条

如果文章对你有帮助,欢迎点击上方按钮打赏作者

最后编辑于:2025/5/11作者: 辣条①号

目标:网络规划设计师、系统工程师、ceph存储工程师、云计算工程师。 不负遇见,不谈亏欠!

暂无评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

arrow grin ! ? cool roll eek evil razz mrgreen smile oops lol mad twisted wink idea cry shock neutral sad ???

文章目录