Closed RaymondMouthaan closed 6 years ago
I will look into this.
Thanks Thomas, if you need assistance, just let me know!
Here is a possible interface for this feature:
services:
emqtt-master:
deploy:
labels:
...
- com.df.reqMode.2=tcp
- com.df.serviceGroup.2=emqtt-group
- com.df.tcpCheckPort.2=1881
- com.df.port.2=1883
- com.df.srcPort.2=1883
emqtt-worker:
deploy:
labels:
...
- com.df.reqMode.1=tcp
- com.df.serviceGroup.1=emqtt-group
- com.df.tcpCheckPort.1=1880
- com.df.port.1=1883
- com.df.srcPort.1=1883
This places both services on the same group for the frontend with the name: emqtt-group
. Setting com.df.tcpCheckPort
will enable tcp checking on that port, i.e. the haproxy config will look something like this:
frontend tcp_emqtt-group_1883:
bind *:1883
mode tcp
default_backend emqtt-group-be1883
backend emqtt-group-be1883:
mode tcp
server emqtt-master emqtt-master:1883 check port 1881
server emqtt-worker emqtt-worker:1883 check port 1880
Setting com.df.port
will set the public port for emqtt-group
, if emqtt-master
and emqtt-worker
have conflicting com.df.port
s then the listening port for the emqtt-group
frontend can be either one. The user would need to know to set these two ports the same.
What do you think of this interface?
I like the idea about grouping the services. I only wonder how that goes when one has replica set to more then 1? (which is not the case in my emqtt set-up btw).
Wouldn't it be more easier to let docker decide the com.df.port so that the exposed ports are not fixed?
Example haproxy.cfg:
server mosca_1 178.62.122.204:1883 check
server mosca_2 178.62.104.172:1883 check
Your proposal:
server emqtt-master emqtt-master:1883 check port 1881
server emqtt-worker emqtt-worker:1883 check port 1880
You explicit have those checks on the public port, but in the example they are left out. Also in the example there are some other settings:
#Use this to avoid the connection loss when client subscribed for a topic and its idle for sometime
option clitcpka # For TCP keep-alive
timeout client 3h #By default TCP keep-alive interval is 2hours in OS kernal, 'cat /proc/sys/net/ipv4/tcp_keepalive_time'
timeout server 3h #By default TCP keep-alive interval is 2hours in OS kernal
option tcplog
balance leastconn
Just to like web applications, a mqtt client connects to mymqtt.server.com on 1883, which is haproxy. haproxy should balance between the master or worker. If one of them is down then the client should be re-directed to the mqtt broker that is still alive.
If a test version of this feature is available then I can test it out in a real life situation.
Thanks for your effort 👍
Maybe it would be better to just have com.df.tcpCheck=true
to enable tcp checking. Please see the example below.
There is a way to configuring DFSL to send the IPs of the services so we can use the IPs for the backend. This would handle the case where replicas >= 1. If this is a desirable feature, I can add this feature into DFP.
For the complete config, I propose this compose file:
services:
emqtt-master:
deploy:
labels:
...
- com.df.reqMode.2=tcp
- com.df.serviceGroup.2=emqtt-group
- com.df.tcpCheck.2=true
- com.df.port.2=1883
- com.df.srcPort.2=1883
- com.df.balance.2=leastconn
- com.df.timeoutServer.2=10800
- com.df.timeoutClient.2=10800
- com.df.clitcpka.2=true
emqtt-worker:
deploy:
labels:
...
- com.df.reqMode.1=tcp
- com.df.serviceGroup.1=emqtt-group
- com.df.tcpCheck.1=true
- com.df.port.1=1883
- com.df.srcPort.1=1883
- com.df.balance.1=leastconn
- com.df.timeoutServer.1=10800
- com.df.timeoutClient.1=10800
- com.df.clitcpka.1=true
which will result in:
frontend tcp_emqtt-group_1883:
bind *:1883
mode tcp
option tcplog
option clitcpka
timeout client 10800s
default_backend emqtt-group-be1883
backend emqtt-group-be1883:
mode tcp
timeout server 10800s
balance leastconn
server emqtt-master emqtt-master:1883 check
server emqtt-worker emqtt-worker:1883 check
This should work for your use case with replicas == 1. Does this work for you?
@thomasjpfan I think your proposal is exactly what i need and possible also solves #6. I can't wait to test if it works.
1. Maybe it would be better to just have com.df.tcpCheck=true to enable tcp checking. Please see the example below.
2. There is a way to configuring DFSL to send the IPs of the services so we can use the IPs for the backend. This would handle the case where replicas >= 1. If this is a desirable feature, I can add this feature into DFP.
3. For the complete config, I propose this compose file:
@thomasjpfan, just curious, are there any update on this? 😄
I made some changes to the original proposal. To use this feature for your use case the stack file would be:
services:
proxy:
image: dockerflow/docker-flow-proxy
environment:
- DEBUG=true
emqtt-master:
deploy:
labels:
...
- com.df.reqMode.2=tcp
- com.df.serviceGroup.2=emqtt-group
- com.df.checkTcp.2=true
- com.df.port.2=1883
- com.df.srcPort.2=1883
- com.df.balanceGroup.2=leastconn
- com.df.timeoutServer.2=10800
- com.df.timeoutClient.2=10800
- com.df.clitcpka.2=true
emqtt-worker:
deploy:
labels:
...
- com.df.reqMode.1=tcp
- com.df.serviceGroup.1=emqtt-group
- com.df.tcpCheck.1=true
- com.df.port.1=1883
- com.df.srcPort.1=1883
- com.df.balanceGroup.1=leastconn
- com.df.timeoutServer.1=10800
- com.df.timeoutClient.1=10800
- com.df.clitcpka.1=true
This would result in this configuration:
listen tcp_emqtt-group_1883:
bind *:1883
mode tcp
option tcplog
log global
option clitcpka
option tcp-check
timeout client 10800s
timeout server 10800s
balance leastconn
server mqtt_emqtt-master_1883_0 *EMQTT-MASTER_IP_REPLICA_1*:1883 check
server mqtt_emqtt-worker_1883_0 *EMQTT-WORKER_IP_REPLICA_1*:1883 check
The DEBUG=true
flag in the environment enables option tcplog
and log global
.
You can test out the TCP groups feature by using dockerflow/docker-flow-proxy:18.05.08-45
or later.
@thomasjpfan, I just tested the above stack file and it works exactly how I hoped it would be! 💯.
I have tested the following scenario:
So basically I works perfectly and I am really happy you implemented this feature into DFP, thank you 🥇 🥇 🥇.
note: I noticed an issue #18 with the docker image tag for linux-arm and I'll investigate whats going wrong and do a PR for it.
Hi @vfarcic & (@thomasjpfan)
In response of our Skype session, I am submitting this issue, possibly related to #6
Please consider the following compose file, which creates two services mqtt_emqtt-master and mqtt_emqtt-worker. Each service deploys 1 container.
The haproxy.cfg looks like this:
Unfortunately as I understood dfp currently doesn't support load balancing between two (or more) services.
In this case all incoming mqtt tcp connections are getting connection with the worker and none with the master. When the worker is shutdown (replica set to zero), all the incoming mqtt tcp connections fail and not redirected to the master.
What I would like is that dfp load balances the incoming mqtt tcp connection over the two (or more) containers.
Find below an haproxy.cfg example which worked for me before i used dfp:
Hope you guys have time to look into this :-)