I have a simple twisted app that serves “Hello World!” via HTTP protocol. I am trying to run several instances to make use of all processors.
But I mentioned that single twisted app handles much more requests than even 1, 2, or 5 instances of the same app behind the haproxy. I can’t figure out why is this happening.
I run 5000 threads getting / via JMeter. When I run it on 127.0.0.1:9001 it handles each request successfully in 500ms time. When I run it on 127.0.0.1:8080 some of responses are 503 Service Unavailable and some run more than 500ms.
Here is my configuration file:
global
maxconn 500000
user german
defaults
mode http
retries 0
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
balance roundrobin
# if something goes wrong with server, redistribute client to a working server
option redispatch
listen http 127.0.0.1:8080
mode http
option httpchk GET / HTTP/1.1
server prototype-local 127.0.0.1:9001 maxconn 0 weight 1 maxqueue 0 cookie server01 check inter 5000 rise 1 fall 3
balance roundrobin
# to see ip's of clients
option forwardfor
option http-server-close
# disable or enable immediate session resource cleaning(useful for chat)
# option nolinger
# inserts cookie to each client requet to identify a process
cookie SWCOMMET insert indirect nocache
# will be enalbed as soon as main server with process crashed :nice fail resistance
option allbackups
Are you kidding ? If an application as simple as a “hello world” responds in 500ms, for sure there is something broken somewhere.
You should check that your server is not swapping (eg: due to a memory leak), which could explain such a huge response time and why it’s even worse when you add haproxy in the chain since both processes would then be affected.
The fact that you get a 503 from haproxy means that it lost the server which failed to respond to health checks. This is in line with the huge response time BTW.
It is also possible that for any reason the application is eating all the CPU and incurs high scheduling latencies to haproxy if it’s bound to the same CPU. You should monitor CPU usage and see on which CPU each process runs (use “top” for this). Ideally you should force haproxy to a specific core (using taskset) and your application to another core. Avoiding thread migrations across cores is critical to achieve high loads, so each new instance will have to run on a dedicated core.
If the server is eating a lot of memory, you should use haproxy’s server maxconn parameter to serialize the requests (and remove maxqueue).
Among the other things I’m seeing in your haproxy config, the global maxconn is huge and does not make much sense, as you’d need around 9 GB of RAM just for haproxy in order to reach this limit. Also, you need to set a maxconn value in your defaults section, as the default value for a frontend is 2000, which probably is lower than what you’re trying.
You should remove “maxconn 0”, “maxqueue 0” and “weight 1” as they’re default and only complicate understanding of the config.