# Load Balancing

During development, we usually use compressed packages to start services in the form of a single node. However, production operation requires a more robust way of deployment. This page focuses on deploying your EMQX service using best practices for production deployment.

TIP

If the EMQX cluster is deployed behind HAProxy or Nginx, and you need to get the real source IP address and port of the clients, you need to turn on the Proxy Protocol configuration with the following configuration item: EMQX listener proxy_protocol

Proxy Protcol Reference: https://www.haproxy.com/blog/haproxy/proxy-protocol (opens new window). Nginx uses Proxy Prorcol Reference: https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/ (opens new window)

# Deployment Architecture

EMQX cluster can be deployed as an IoT access service (IoT Hub). Currently, EMQ provides free software images out of the box on cloud service providers such as QingCloud, Aliyun, and AWS. For special hardware platforms and system versions such as Raspberry Pi and Linux ARM, source code compilation and installation can be used.

Typical deployment architecture:

image

# Load Balancer (LB)

The Load Balancer (LB) distributes MQTT connections and traffic from devices across the EMQX clusters. LB enhances the HA of the clusters, balances the loads among the cluster nodes, and makes dynamic expansion possible.

It is recommended that SSL connections are terminated by an LB. The links between devices and the LB are secured by SSL, while the links between the LB and EMQX cluster nodes are plain TCP connections. With this setup, a single EMQX cluster can serve a million devices.

LB products of public cloud providers:

Cloud providerSSL TerminationLB Product DOC/URL
QingCloud (opens new window)Yeshttps://docs.qingcloud.com/product/network/loadbalancer/ (opens new window)
AWS (opens new window)Yeshttps://aws.amazon.com/cn/elasticloadbalancing/ (opens new window)
Aliyun (opens new window)Nohttps://www.aliyun.com/product/slb (opens new window)
UCloud (opens new window)Unknownhttps://ucloud.cn/site/product/ulb.html (opens new window)
QCloud (opens new window)Unknownhttps://www.qcloud.com/product/clb (opens new window)

LBs for Private Cloud:

Open-Source LBSSL TerminationDOC/URL
HAProxy (opens new window)Yeshttps://www.haproxy.com/solutions/load-balancing.html (opens new window)
NGINX (opens new window)Yeshttps://www.nginx.com/solutions/load-balancing/ (opens new window)

TIP

QingCloud(EMQX partner) is recommended for domestic public cloud deployments, AWS for foreign deployments, and HAProxy for private deployments.

# EMQX Ports

EMQX cluster nodes are deployed behind LB. It is suggested that the nodes be deployed on VPCs or private networks. Cloud providers, such as AWS, Azure, or QingCloud, usually provide a VPC network.

EMQX provides the MQTT service on the following TCP ports by default:

PortDescription
1883MQTT
8883MQTT/SSL
8083MQTT/WebSocket
8084MQTT/WebSocket/SSL
8081Management API
18083Dashboard/Management API

Firewalls should make the relevant ports accessible for the public according to the MQTT access method.

TCP ports used by EMQX node cluster:

PortDescription
4370Cluster node distribution port
5370Cluster RPC

If a firewall is deployed for the security of inter-cluster communication, it should be configured that the above ports are accessible between the nodes.

# Deploying on QingCloud

  1. Create a VPC network.
  2. Create a ‘private network’ for the EMQX cluster inside the VPC network, e.g. 192.168.0.0/24
  3. Create 2 EMQX hosts inside the private network, like:
NodeIP address
emqx1192.168.0.2
emqx2192.168.0.3
  1. Install and cluster EMQX on these two hosts. Please refer to the sections of cluster installation for details.
  2. Create LB and assign the public IP address.
  3. Create an MQTT TCP listener:

image

Or create an SSL listener and terminate the SSL connections on LB:

image

  1. Connect the MQTT clients to the LB using the public IP address and test the deployment.

# Deploying on AWS

  1. Create a VPC network.
  2. Create a ‘private network’ for the EMQX cluster inside the VPC network, e.g., 192.168.0.0/24
  3. Create 2 hosts inside the private network, like:
NodeIP address
emqx1192.168.0.2
emqx2192.168.0.3
  1. Open the TCP ports for MQTT services (e.g., 1883,8883) on the security group.
  2. Install and cluster EMQX on these two hosts. Please refer to the sections on cluster installation for details.
  3. Create ELB (Classic Load Balancer), assign the VPC network, and assign the public IP address.
  4. Create an MQTT TCP listener on the ELB:

image

Or create an SSL listener and terminate the SSL connections on the ELB:

image

  1. Connect the MQTT clients to the ELB using the public IP address and test the deployment.

# Deploying on a Private Network

# Direct Connection to an EMQX Cluster

EMQX cluster should be DNS-resolvable, and the clients access the cluster via domain name or IP list:

  1. Deploy EMQX cluster. Please refer to the sections ‘Installation’ and ‘EMQX nodes clustering’ for details.
  2. Enable access to the MQTT ports on the firewall (e.g., 1883, 8883).
  3. Client devices access the EMQX cluster via domain name or IP list.

TIP

This kind of deployment is NOT recommended.

# HAProxy LB

HAProxy serves as an LB for the EMQX cluster and terminates the SSL connections:

  1. Create EMQX Cluster nodes like the following:
nodeIP
emqx1192.168.0.2
emqx2192.168.0.3
  1. Configure /etc/haproxy/haproxy.cfg:
listen mqtt-ssl
  bind *:8883 ssl crt /etc/ssl/emqx/emq.pem no-sslv3
  mode tcp
  maxconn 50000
  timeout client 600s
  default_backend emqx_cluster

backend emqx_cluster
  mode tcp
  balance source
  timeout server 50s
  timeout check 5000
  server emqx1 192.168.0.2:1883 check inter 10000 fall 2 rise 5 weight 1
  server emqx2 192.168.0.3:1883 check inter 10000 fall 2 rise 5 weight 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# Nginx LB

NGINX Plus serves as an LB for the EMQX cluster and terminates the SSL connections.

  1. Create EMQX cluster nodes like the following:
NodeIP
emqx1192.168.0.2
emqx2192.168.0.3
  1. Configure /etc/nginx/nginx.conf:
stream {
  upstream stream_backend {
      zone tcp_servers 64k;
      hash $remote_addr;
      server 192.168.0.2:1883 max_fails=2 fail_timeout=30s;
      server 192.168.0.3:1883 max_fails=2 fail_timeout=30s;
  }

  server {
      listen 8883 ssl;
      status_zone tcp_server;
      proxy_pass stream_backend;
      proxy_buffer_size 4k;
      ssl_handshake_timeout 15s;
      ssl_certificate     /etc/emqx/certs/cert.pem;
      ssl_certificate_key /etc/emqx/certs/key.pem;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18