1
0
mirror of /repos/dotTiddlywiki.git synced 2025-12-30 07:31:33 +01:00
dotTiddlywiki/mywiki/tiddlers/HAProxy_ Reloading Your Config With Minimal Service Impact.tid
Aiko Mastboom c8270d6eb6 update
2015-12-07 22:16:06 +01:00

79 lines
5.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

created: 20151204110112790
creator: user
modified: 20151204113747216
modifier: user
tags:
title: HAProxy: Reloading Your Config With Minimal Service Impact
type: text/vnd.tiddlywiki
docker image: https://hub.docker.com/r/million12/haproxy/~/dockerfile/
source: https://web.archive.org/web/20150219063018/http://www.mgoff.in/2010/04/18/haproxy-reloading-your-config-with-minimal-service-impact
posted by: Michael Goffin
[[HAProxy| http://haproxy.org ]] is a high performance load balancer. It is very light-weight, and free, making it a great option if you are in the market for a load balancer and need to keep your costs down.
Lately weve been making a lot of load balancer changes at work to accommodate new systems and services. Even though we have two load balancers running with [[keepalived| http://www.keepalived.org/ ]] taking care of any failover situations, I was thinking about how we go about reloading our configuration files. In the event of a change, the “common” way to get the changes to take effect is to run ''/etc/init.d/haproxy restart''. This is bad for a couple major reasons:
# You are temporarily shutting your load balancer down
# You are severing any current connections going through the load balancer
You might say, “if you have two load balancers with keepalived, restarting the service should be fine since keepalived will handle the failover.” This, however, isnt always true. Keepalived uses advertisements to determine when to fail over. The default advertisement interval is 1 second (configurable in keepalived.conf). The skew time helps to keep everyone from trying to transition at once. It is a number between 0 and 1, based on the formula ''(256 priority) / 256''. As defined in the RFC, the backup must receive an advertisement from the master every ''(3 * advert_int) + skew_time'' seconds. If it doesnt hear anything from the master, it takes over.
Lets assume you are using the default interval of 1 second. On my test machine, this is the duration of time it takes to restart haproxy:
```
# time /etc/init.d/haproxy restart
* Restarting haproxy haproxy
...done.
real 0m0.022s
user 0m0.000s
sys 0m0.016s
```
In this situation, haproxy would restart much faster than your 1 second interval. You could get lucky and happen to restart it just before the check, but luck is not consistent enough to be useful. Also, in very high-traffic situations, youll be causing a lot of connection issues. So we cannot rely on keepalived to solve the first problem, and it definitely doesnt solve the second problem.
After sifting through haproxy documentation (the text-based documentation, not the man page) (/usr/share/doc/haproxy/haproxy-en.txt.gz on Ubuntu), I came across this:
```
313
314 global
315 daemon
316 quiet
317 nbproc 2
318 pidfile /var/run/haproxy-private.pid
319
320 # to stop only those processes among others :
321 # kill $(</var/run/haproxy-private.pid)
322
323 # to reload a new configuration with minimal service impact and without
324 # breaking existing sessions :
325 # haproxy -f haproxy.cfg -p $(</var/run/haproxy-private.pid) -st $(</var/run/haproxy-private.pid)
```
That last command is the one of interest. The -p asks the process to write down each of its childrens pids to the specified pid file, and the -st specifies a list of pids to send a SIGTERM to after startup. But it does this in an interesting way:
```
609 The '-st' and '-sf' command line options are used to inform previously running
610 processes that a configuration is being reloaded. They will receive the SIGTTOU
611 signal to ask them to temporarily stop listening to the ports so that the new
612 process can grab them. If anything wrong happens, the new process will send
613 them a SIGTTIN to tell them to re-listen to the ports and continue their normal
614 work. Otherwise, it will either ask them to finish (-sf) their work then softly
615 exit, or immediately terminate (-st), breaking existing sessions. A typical use
616 of this allows a configuration reload without service interruption :
617
618 # haproxy -p /var/run/haproxy.pid -sf $(cat /var/run/haproxy.pid)
```
The end-result is a reload of the configuration file which is not visible by the customer. It also solves the second problem! Lets look at an example of the command and look at the time compared to our above example:
```
# time haproxy -f /etc/haproxy.cfg -p /var/run/haproxy.pid -sf $(cat /var/run/haproxy.pid)
real 0m0.018s
user 0m0.000s
sys 0m0.004s
```
Ive specified the config file I want to use and the pid file haproxy is currently using. The ''$(cat /var/run/haproxy.pid)'' takes the output of ''cat /var/run/haproxy.pid'' and passes it in to the -sf parameter as a list, which is what it is expecting. You will notice that the time is actually faster too (.012s sys, and .004s real). It may not seem like much, but if you are dealing with very high volumes of traffic, this can be pretty important. Luckily for us it doesnt matter because weve been able to reload the haproxy configuration without dropping any connections and without causing any customer-facing issues.
''UPDATE:'' There is a reload in some of the init.d scripts (I havent checked every OS, so this can vary), but it uses the -st option which will break existing sessions, as opposed to using -sf to do a graceful hand-off. You can modify the haproxy_reload() function to use the -sf if you want. I also find it a bit confusing that the documentation uses ''$(cat /path/to/pidfile)'' whereas this haproxy_reload() function uses ''$(<$PIDFILE)''. Either should work, but really, way to lead by example…