Load balancing using HAProxy for MQTT broker


# Overview

![MQTT PIPEline.png](https://qiita-image-store.s3.amazonaws.com/0/6410/7aec612b-66fe-bfe5-e0e9-ababbd76a347.png "MQTT PIPEline.png")


# Install HAProxy

```
apt-get install haproxy
```


# HAProxy config

```
# Listen to all MQTT requests (port 1883)
listen mqtt
  # MQTT binding to port 1883
  bind *:1883
  # communication mode (MQTT works on top of TCP)
  mode tcp
  option tcplog
  # balance mode (to choose which MQTT server to use)
  balance leastconn
  # MQTT broker 1
  server broker_1 10.255.4.101:1883 check
  # MQTT broker 2
  server broker_2 10.255.4.102:1883 check
```
ref:
https://medium.com/@lelylan/how-to-build-an-high-availability-mqtt-cluster-for-the-internet-of-things-8011a06bd000


>leastconn   The server with the lowest number of connections receives the
              connection. Round-robin is performed within groups of servers
              of the same load to ensure that all servers will be used. Use
              of this algorithm is recommended where very long sessions are
              expected, such as LDAP, SQL, TSE, etc... but is not very well
              suited for protocols using short sessions such as HTTP. This
              algorithm is dynamic, which means that server weights may be
              adjusted on the fly for slow starts for instance.

I will take a shot for leastconn at the beginning.

HAProxy balance:
https://cbonte.github.io/haproxy-dconv/configuration-1.5.html#balance


check means: check availabitly of server

> This option enables health checks on the server. By default, a server is
always considered available. If "check" is set, the server is available when
accepting periodic TCP connections, to ensure that it is really able to serve
requests. The default address and port to send the tests to are those of the
server, and the default source is the same as the one defined in the
backend. It is possible to change the address using the "addr" parameter, the
port using the "port" parameter, the source address using the "source"
address, and the interval and timers using the "inter", "rise" and "fall"
parameters. The request method is define in the backend using the "httpchk",
"smtpchk", "mysql-check", "pgsql-check" and "ssl-hello-chk" options. Please
refer to those options and parameters for more information.

> Supported in default-server: No

ref: https://cbonte.github.io/haproxy-dconv/configuration-1.5.html#5.2-check



# Hot reload

```
haproxy -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid -sf $(cat /var/run/haproxy.pid)
```
refs:
http://www.forouzani.com/reload-haproxy-cfg-without-restarting.html


Yelp did a great job for zero packet droping for HAProxy restart. Their approach is that let SYN packet delaed using tc during restart. We should try later.
 
http://engineeringblog.yelp.com/2015/04/true-zero-downtime-haproxy-reloads.html


# HAProxy stats

add this to config file

```
listen stats :1936
    mode http
    stats enable
    stats hide-version
    stats realm Haproxy\ Statistics
    stats uri /
```

Then go http://HAPRoxyHOST:1936
You will see something like this.

![Screenshot 2015-10-02 12.41.34.png](https://qiita-image-store.s3.amazonaws.com/0/6410/0a8cce8c-2471-ec3d-36a9-deec39645397.png "Screenshot 2015-10-02 12.41.34.png")


If you have security concern, you magiht add this conf to the block.

```
    stats realm Strictly\ Private
    stats auth A_Username:YourPassword
    stats auth Another_User:passwd
```

# Weighting policy

More research on this later.

# Dynamic configuration

More research on this later.

# Supervisor tools

More research on this later.
- monit
- demontool
- supervisord