HAProxy 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 we’ve 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 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, isn’t 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 doesn’t hear anything from the master, it takes over.

Let’s 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, you’ll be causing a lot of connection issues. So we cannot rely on keepalived to solve the first problem, and it definitely doesn’t 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 children’s 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! Let’s 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

I’ve 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 doesn’t matter because we’ve 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 haven’t 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…

[笔记]HAproxy reload config file with uninterrupt session的更多相关文章

  1. peomethues 参数设置 监控网站 /usr/local/prometheus-2.13.0.linux-amd64/prometheus --config.file=/usr/local/prometheus-2.13.0.linux-amd64/prometheus.yml --web.listen-address=:9999 --web.enable-lifecycle

    probe_http_status_code{instance="xxxx",job="web_status"} probe_http_status_code{ ...

  2. Example config file /etc/vsftpd.conf

    # Example config file /etc/vsftpd.conf # # The default compiled in settings are fairly paranoid. Thi ...

  3. error in config file "/etc/rabbitmq/rabbitmq.config"

    记录一次RabbitMQ配置文件配置错误 error信息: dill@ubuntu-vm:/usr/share/doc/rabbitmq-server$ sudo /usr/lib/rabbitmq/ ...

  4. .NET错误The 'targetFramework' attribute in the <compilation> element of the Web.config file is used only to target version 4.0 and later of the .NET Framework

    错误描述: The 'targetFramework' attribute in the <compilation> element of the Web.config file is u ...

  5. No connection string named '***' could be found in the application config file

    Code-First时更新数据库遇到妖孽问题“No connection string named '***' could be found in the application config fil ...

  6. Camel routes in Spring config file

    The normal spring bean definition configuration file, the xsi:schemaLocation only has two: beans and ...

  7. The document has been modified outside of Code Composer. Would you like to reload the file

    2013-06-20 10:03:32 烧写过程是合众达给出的文档 problem: I'm new to using Code Composer Studio 3.3 and am having a ...

  8. 为 vsftpd 启动 vsftpd:500 OOPS: bad bool value in config file for: pasv_enable

    每行的值都不要有空格,否则启动时会出现错误,举个例子,假如我在listen=YES后多了个空格,那我启动时就出现.. 为 vsftpd 启动 vsftpd:500 OOPS: bad bool val ...

  9. Warning: World-writable config file '/etc/my.cnf' is ignored

    1. 问题描述: 重启mysql服务时出现以下信息: Warning: World-writable config file '/etc/my.cnf' is ignored 出现这种情况的原因是:m ...

随机推荐

  1. .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类

    .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件功能比较简单,有的则比较复杂,并且依赖其它组件.除 ...

  2. SQL Server-聚焦使用视图若干限制/建议、视图查询性能问题,你懵逼了?(二十五)

    前言 上一节我们简单讲述了表表达式的4种类型,这一系列我们来讲讲使用视图的限制,简短的内容,深入的理解,Always to review the basics. 避免在视图中使用ORDER BY 上一 ...

  3. XML技术之DOM4J解析器

    由于DOM技术的解析,存在很多缺陷,比如内存溢出,解析速度慢等问题,所以就出现了DOM4J解析技术,DOM4J技术的出现大大改进了DOM解析技术的缺陷. 使用DOM4J技术解析XML文件的步骤? pu ...

  4. 算法与数据结构(十五) 归并排序(Swift 3.0版)

    上篇博客我们主要聊了堆排序的相关内容,本篇博客,我们就来聊一下归并排序的相关内容.归并排序主要用了分治法的思想,在归并排序中,将我们需要排序的数组进行拆分,将其拆分的足够小.当拆分的数组中只有一个元素 ...

  5. MyBatis基础入门--知识点总结

    对原生态jdbc程序的问题总结 下面是一个传统的jdbc连接oracle数据库的标准代码: public static void main(String[] args) throws Exceptio ...

  6. CentOS7使用firewalld打开关闭防火墙与端口(转载)

    1.firewalld的基本使用 启动: systemctl start firewalld 查看状态: systemctl status firewalld 停止: systemctl disabl ...

  7. MongoDB集群配置

    本文演示:(一个主服务器,一个备份服务器,三个仲裁服务器) 官方推荐副本集的成员数量为奇数,最多12个副本集节点,最多7个节点参与选举. 本文演示基于本机,用端口区分服务(每个服务器下新建db文件夹用 ...

  8. 1.Hibernate简介

    1.框架简介: 定义:基于java语言开发的一套ORM框架: 优点:a.方便开发;           b.大大减少代码量;           c.性能稍高(不能与数据库高手相比,较一般数据库使用者 ...

  9. TCP的数据传输小结

    TCP的交互数据流 交互式输入 通常每一个交互按键都会产生一个数据分组,也就是说,每次从客户传到服务器的是一个字节的按键(而不是每次一行) 经受时延的确认 通常TCP在接受到数据时并不立即发送ACK: ...

  10. Hibernatel框架基础使用

    Hibernatel框架基础使用 1.简介 1.1.Hibernate框架由来 Struts:基于MVC模式的应用层框架技术 Hibernate:基于持久层的框架(数据访问层使用)! Spring:创 ...