[ EMQX ] EMQX 클러스터 with HAProxy

2025. 6. 30. 22:19EMQX

반응형

시스템 실행 환경

OS Ubuntu 24.04.02
실행 환경 Virtual Box
Docker 28.1.1
EMQX 5.4.1
HAProxy 2.4.24

 

 

HAProxy를 이용한 EMQX 클러스터 로드 밸런싱

HAProxy는 클라이언트의 네트워크 연결 요청을 여러 백엔드 서버로 효율적으로 분산시켜 주는

고성능 오픈 소스 로드 밸런서입니다.

EMQX 클러스터 환경에서는 HAProxy를 통해 클라이언트 접속을 안정적으로 분산시킴으로써
부하를 균형 있게 처리하고 가용성을 높일 수 있습니다😄

 

 

특징 및 장점

  1. 백엔드 노드 정보를 외부에 노출하지 않고, 리버스 프록시를 통해 통합된 접속 주소만 제공함으로써
    시스템의 유지보수성과 확장성을 높일 수 있습니다.
  2. HAProxy는 TLS 연결을 종료할 수 있어 EMQX가 수행해야 할 SSL 암호화 연산 부하를 줄이고,
    인증서의 배포 및 관리가 간편해집니다.
  3. MQTT 프로토콜을 기본적으로 지원하므로, MQTT 메시지를 파싱하여 세션 고정 및 지능형 로드밸런
    구현할 수 있습니다.
    ➡️ 비정상 연결을 식별하고, 보안을 강화할 수 있습니다.
  4. Primary/Stnadby 구조의 고가용성 메커니즘과 백엔드 헬스 체크 기능을 통해 수 밀리초 단위의 장애 전환이
    가능하며, 서비스의 연속적인 가용성을 보장합니다.

출처: https://docs.emqx.com/en/emqx/latest/deploy/cluster/lb-haproxy.html

 

 

빠른 시작

EMQX 공식 문서에서 안내하는 Docker Compose 구성과 예시입니다.

 

1. EMQX 예제 저장소를 클론 할 디렉터리를 생성합니다.

mkdir -p /app/docker/emqx

 

2. EMQX 예제 저장소를 클론 합니다.

# 폴더 이동
cd /app/docker/emqx

# git 클론
git clone https://github.com/emqx/emqx-usage-example

 

3. Docker Compose를 사용하여 컨테이너를 실행합니다.

# 폴더 이동
cd emqx-usage-example/mqtt-lb-haproxy

# Docker Compose 데몬 실행
docker compose up -d

 

4. VM에서 사용할 포트를 포트 포워딩 규칙에 추가합니다.

 

5. MQTTX를 이용하여 EMQX 클라이언트 연결을 테스트합니다.

  • Name: Dauuni
    원하는 이름으로 설정하면 됩니다☺️☺️
  • Host: mqtt://localhost
  • Port: 11883

 

6. HAProxy 연결 모니터링과 EMQX 클라이언트 연결 분포를 확인합니다.

🌐 HAProxy 통계 모니터링 페이지: http://localhost:18888/stats

MQTT 연결 전
MQTT 연결

 

7. 명령어를 사용하여 각 EMQX 노드의 클라이언트 연결 상태를 확인합니다.

docker exec -it emqx1 emqx ctl broker stats | grep connections.count
docker exec -it emqx2 emqx ctl broker stats | grep connections.count
docker exec -it emqx3 emqx ctl broker stats | grep connections.count

MQTTX에 의해 연결된 클라이언트가 emqx1 노드와 연결된 것을 확인할 수 있습니다.

 

 

HAProxy 설정 파일

위 예제에서 제공하는 HAProxy 설정 파일에 대한 설명입니다.

🗒️ HAProxy 설정 파일:  haproxy.cfg 

 

 

기본 구성

HAProxy 서버를 시작하는 데 필요한 기본 구성입니다.

haproxy.cfg 파일에 다음 두 항목이 포함되어 있는지 확인합니다.

global
  log 127.0.0.1 local3 info  # 로그 설정
  daemon                     # HAProxy 백그라운드에서 데몬으로 실행
  maxconn 10240              # 전체 HAProxy가 처리할 수 있는 최대 동시 연결 수

defaults
  log global                 # global 섹션에 정의한 로그 설정 사용
  mode tcp                   # TCP 모드로 작동
  option tcplog              # TCP 연결에 대한 자세한 로그 기록
  timeout connect 10000      # 백엔드 서버와의 timeout(10초)
  timeout client 240s        # 클라이언트 연결의 비활성 상태 최대 지속 시간(4분)
  timeout server 240s        # 서버 연결의 비활성 상태 최대 지속 시간(4분)
  maxconn 20000              # 각 프록시에서 동시에 처리 가능한 최대 연결 수

 

 

MQTT 역방향 프록시 구성

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

  server emqx1 emqx1-cluster.emqx.io:1883
  server emqx2 emqx2-cluster.emqx.io:1883
  server emqx3 emqx3-cluster.emqx.io:1883

frontend mqtt_servers
  bind *:1883
  mode tcp
  tcp-request inspect-delay 10s
  tcp-request content reject unless { req.payload(0,0),mqtt_is_valid }
  default_backend mqtt_backend

 

🔹 backend mqtt_backend

mode tcp

MQTT는 TCP 기반 프로토콜이므로 HAProxy의 처리 모드를 TCP로 설정합니다.

 

stick-table type string len 32 size 1000k expire 30m

세션 고정을 위한 stick-table을 정의합니다.

길이 32까지의 문자열을 키로 사용하며, 최대 100만 개 까지 저장할 수 있고, 각 항목은 30분 후 자동으로 만료됩니다.

 

stick on req.payload(0,0),mqtt_field_value(connect,client_identifier)

MQTT 클라이언트가 서버에 처음 연결할 때 보내는 메시지 중에서 클라이언트 ID 값을 꺼내서
그 값을 기준으로 항상 같은 서버로 연결되게 하겠다는 의미입니다. ➡️ 세션 고정

 

server emqx1 emqx1-cluster.emqx.io:1883
server emqx2 emqx2-cluster.emqx.io:1883
server emqx3 emqx3-cluster.emqx.io:1883

실제 MQTT 요청을 처리할 EMQX 노드를 정의합니다.

각 emqx1, emqx2, emqx3이라는 이름을 가지고 있고, 포트 1883을 통해 처리합니다.

 

 

🔹 frontend mqtt_servers

bind *:1883

외부에서 들어오는 MQTT 요청을 1883 포트에서 수신합니다. ➕ 모든 IP

 

mode tcp

동일하게 TCP 모드를 사용합니다.

 

tcp-request inspect-delay 10s

MQTT 패킷을 분석하여 클라이언트 ID를 추출하기 위한 시간을 확보합니다. 

 

tcp-request content reject unless { req.payload(0,0),mqtt_is_valid }

 

 

들어온 요청이 MQTT 프로토콜이 아니면 거부합니다.

 

default_backend mqtt_backend

위에서 정의한 mqtt_backend로 트래픽을 전달합니다.

 

 

MQTT SSL 역방향 프록시 구성

※ 위에서 겹치는 내용은 생략

다음 구성을 사용하면 HAProxy가 MQTT를 역방향 프록시하고, TLS 연결을 해독하여
클라이언트에서 백엔드 MQTT 서버로 암호화된 MQTT 요청을 전달하여 통신 보안을 보장합니다.

 

기본 TCP 구성에 SSL 및 인증서 관련 매개변수를 추가하면 됩니다.

backend mqtts_backend
  mode tcp
  balance roundrobin

  server emqx1 emqx1-cluster.emqx.io:1883 weight 5
  server emqx2 emqx2-cluster.emqx.io:1883 weight 2
  server emqx3 emqx3-cluster.emqx.io:1883 weight 3

frontend mqtt_tls_frontend
  bind *:8883 ssl crt /etc/haproxy/certs/server.pem

  mode tcp
  default_backend mqtts_backend

 

🔹 backend mqtts_backend

balance roundrobin

서버에 순서대로 번갈아 가며 요청을 분산하는 라운드로빈 방식으로 로드밸런싱 합니다.

 

server emqx1 emqx1-cluster.emqx.io:1883 weight 5
server emqx2 emqx2-cluster.emqx.io:1883 weight 2
server emqx3 emqx3-cluster.emqx.io:1883 weight 3

실제 EMQX 노드를 백엔드 서버로 지정하고, 가중치를 부여합니다.

가중치가 높을수록 분산 시 더 많은 트래픽을 받게 됩니다.

 

🔹 frontend mqtt_tls_frontend

bind *:8883 ssl crt /etc/haproxy/certs/server.pem

클라이언트로부터 TLS 연결을 8883 포트에 수신하며, server.pem 인증서를 사용해 TLS 종료를 수행합니다.

 

 

MQTT WebSocket 역방향 프록시 구성

구성은 MQTT와 동일하며 포트만 다르기 때문에 설정 파일만 작성했습니다.

backend mqtt_ws_backend
  mode tcp
  balance roundrobin
  server emqx1 emqx1-cluster.emqx.io:8083 check
  server emqx2 emqx2-cluster.emqx.io:8083 check
  server emqx3 emqx3-cluster.emqx.io:8083 check

frontend mqtt_ws_frontend
  bind *:8083
  mode tcp
  default_backend mqtt_ws_backend

 

 

MQTT WebSocket SSL 역방향 프록시 구성

다음 구성은 HAProxy를 역방향 프록시로 사용하여 MQTT WebSocket 연결을 설정하고,

TLS 연결을 복호화한 뒤 클라이언트의 암호화된 MQTT 요청을 백엔드 서버로 전달함으로써 통신 보안을 보장합니다.

frontend mqtt_ws_tls_frontend
  bind *:8084 ssl crt /etc/haproxy/certs/server.pem
  mode tcp
  default_backend mqtt_ws_backend

이 경우, TLS 처리 여부만 다를 뿐 실제 서비스 대상은 동일하므로 동일한 백엔드로 연결됩니다.

기본적으로 EMQX는 8083 포트에서 WebSocket 요청을 수신하도록 설정되어 있기 때문에,
HAProxy는 TLS가 적용된 8084 포트의 요청을 복호화한 후 EMQX의 8083 포트로 전달합니다.

 

 

🌐 참고 사이트

https://docs.emqx.com/en/emqx/latest/deploy/cluster/lb-haproxy.html  EMQX 공식 문서

반응형

'EMQX' 카테고리의 다른 글

[ EMQX ] 로드 밸런서  (0) 2025.05.28
[ EMQX ] EMQX 클러스터링  (1) 2025.05.28