<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Michael Goffin &#187; haproxy</title>
	<atom:link href="http://www.mgoff.in/tag/haproxy/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mgoff.in</link>
	<description>geek</description>
	<lastBuildDate>Tue, 16 Aug 2011 18:27:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>HAProxy: Gathering Stats Using `socat`</title>
		<link>http://www.mgoff.in/2010/07/14/haproxy-gathering-stats-using-socat/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=haproxy-gathering-stats-using-socat</link>
		<comments>http://www.mgoff.in/2010/07/14/haproxy-gathering-stats-using-socat/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 17:36:11 +0000</pubDate>
		<dc:creator>Michael Goffin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[haproxy]]></category>
		<category><![CDATA[socat]]></category>

		<guid isPermaLink="false">http://www.mgoff.in/?p=114</guid>
		<description><![CDATA[We use Zabbix to monitor our systems at work. It&#8217;s a great open source alternative. One of things I&#8217;ve been working on recently is auditing our monitoring system for defunct monitoring points, unmonitored services, and proper triggers and alerts based on our SLA requirements. HAProxy was one of those items. There are standard monitoring points [...]]]></description>
			<content:encoded><![CDATA[<p>
We use <a href="http://www.zabbix.com/">Zabbix</a> to monitor our systems at work. It&#8217;s a great open source alternative. One of things I&#8217;ve been working on recently is auditing our monitoring system for defunct monitoring points, unmonitored services, and proper triggers and alerts based on our SLA requirements. <a href="http://haproxy.1wt.eu/">HAProxy</a> was one of those items.
</p>
<p>
There are standard monitoring points like PID changes, web interface availability, CPU/Memory usage, etc. But what about monitoring things like MAXCONN and CURCONNS? Turns out there&#8217;s a way to get this data from HAProxy using what they call a &#8220;stats socket.&#8221; This information isn&#8217;t found in the <b>haproxy-en.txt</b> file, but in the <b>configuration.txt</b> file. In my installation, it isn&#8217;t in <b>/usr/share/doc/haproxy</b> like everything else. I actually found this on the official <a href="http://haproxy.1wt.eu/download/1.4/doc/configuration.txt">website</a>. Here&#8217;s the interesting bit:</p>
<blockquote><p>
stats socket
<path> [{uid | user} <uid>] [{gid | group} <gid>] [mode <mode>]<br />
  [level <level>]</p>
<p>  Creates a UNIX socket in stream mode at location
<path>. Any previously<br />
  existing socket will be backed up then replaced. Connections to this socket<br />
  will return various statistics outputs and even allow some commands to be<br />
  issued. Please consult section 9.2 &#8220;Unix Socket commands&#8221; for more details.</p>
<p>  An optional &#8220;level&#8221; parameter can be specified to restrict the nature of<br />
  the commands that can be issued on the socket :<br />
    &#8211; &#8220;user&#8221; is the least privileged level ; only non-sensitive stats can be<br />
      read, and no change is allowed. It would make sense on systems where it<br />
      is not easy to restrict access to the socket.</p>
<p>    &#8211; &#8220;operator&#8221; is the default level and fits most common uses. All data can<br />
      be read, and only non-sensible changes are permitted (eg: clear max<br />
      counters).</p>
<p>    &#8211; &#8220;admin&#8221; should be used with care, as everything is permitted (eg: clear<br />
      all counters).</p>
<p>  On platforms which support it, it is possible to restrict access to this<br />
  socket by specifying numerical IDs after &#8220;uid&#8221; and &#8220;gid&#8221;, or valid user and<br />
  group names after the &#8220;user&#8221; and &#8220;group&#8221; keywords. It is also possible to<br />
  restrict permissions on the socket by passing an octal value after the &#8220;mode&#8221;<br />
  keyword (same syntax as chmod). Depending on the platform, the permissions on<br />
  the socket will be inherited from the directory which hosts it, or from the<br />
  user the process is started with.
</p></blockquote>
<p>Simple enough. Edit your <b>haproxy.cfg</b> and add this into your &#8220;global&#8221; section:</p>
<pre>
global
        daemon
        maxconn 100
        quiet
        user haproxy
        group haproxy
        stats socket    /tmp/haproxy
</pre>
<p><a href="http://www.mgoff.in/2010/04/18/haproxy-reloading-your-config-with-minimal-service-impact/">Reload your HAProxy config</a> and you should now see a socket setup in <b>/tmp</b> (note in the <a href="http://www.freebsd.org/cgi/man.cgi?query=ls">ls</a> output that the &#8220;s&#8221; at the beginning of the permission set denotes the file type as a socket):</p>
<pre>
# ls -lah /tmp/haproxy
srwxr-xr-x 1 root root 0 2010-07-14 12:53 /tmp/haproxy
#
</pre>
<p>Now we can query HAProxy using this socket for some stats. A great way to do this is using <a href="http://www.dest-unreach.org/socat/">socat</a>. If you don&#8217;t have it installed, you can compile from <a href="http://www.dest-unreach.org/socat/download/">source</a>, or use the package management system for your OS (ex: &#8220;apt-get install socat&#8221; for Ubuntu).
</p>
<p>
To query for some stats, you can try the following commands:</p>
<pre>
# echo “show info” | socat unix-connect:/tmp/haproxy stdio
# echo “show stat” | socat unix-connect:/tmp/haproxy stdio
# echo “show errors” | socat unix-connect:/tmp/haproxy stdio
# echo “show sess” | socat unix-connect:/tmp/haproxy stdio
</pre>
<p>More information on interacting with HAProxy through the stats socket can be found in section <b>&#8220;9.2. Unix Socket commands&#8221;</b> of the configuration.txt file I linked to above (it&#8217;s the last section in the file).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mgoff.in/2010/07/14/haproxy-gathering-stats-using-socat/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>HAProxy: Reloading Your Config With Minimal Service Impact</title>
		<link>http://www.mgoff.in/2010/04/18/haproxy-reloading-your-config-with-minimal-service-impact/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=haproxy-reloading-your-config-with-minimal-service-impact</link>
		<comments>http://www.mgoff.in/2010/04/18/haproxy-reloading-your-config-with-minimal-service-impact/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 03:34:10 +0000</pubDate>
		<dc:creator>Michael Goffin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[haproxy]]></category>

		<guid isPermaLink="false">http://www.mgoff.in/?p=77</guid>
		<description><![CDATA[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&#8217;ve been making a lot of load balancer changes at work to accommodate new systems and services. Even though [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://haproxy.1wt.eu/">HAProxy</a> 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.
</p>
<p>
Lately we&#8217;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 <a href="http://www.keepalived.org/">keepalived</a> 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 &#8220;common&#8221; way to get the changes to take effect is to run <b>/etc/init.d/haproxy restart</b>. This is bad for a couple major reasons:</p>
<ol>
<li>You are temporarily shutting your load balancer down</li>
<li>You are severing any current connections going through the load balancer</li>
</ol>
<p>You might say, &#8220;if you have two load balancers with keepalived, restarting the service should be fine since keepalived will handle the failover.&#8221; This, however, isn&#8217;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 <b>(256 &#8211; priority) / 256</b>. As defined in the RFC, the backup must receive an advertisement from the master every <b>(3 * advert_int) + skew_time</b> seconds. If it doesn&#8217;t hear anything from the master, it takes over.
</p>
<p>
Let&#8217;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:</p>
<pre>
# time /etc/init.d/haproxy restart
 * Restarting haproxy haproxy
   ...done.

real    0m0.022s
user    0m0.000s
sys     0m0.016s
</pre>
<p>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&#8217;ll be causing a lot of connection issues. So we cannot rely on keepalived to solve the first problem, and it definitely doesn&#8217;t solve the second problem.
</p>
<p>
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:</p>
<pre>
    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 $(&lt;/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 $(&lt;/var/run/haproxy-private.pid) -st $(&lt;/var/run/haproxy-private.pid)
</pre>
<p>That last command is the one of interest. The -p asks the process to write down each of its children&#8217;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:</p>
<pre>
    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)
</pre>
<p>The end-result is a reload of the configuration file which is not visible by the customer. It also solves the second problem! Let&#8217;s look at an example of the command and look at the time compared to our above example:</p>
<pre>
# 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
</pre>
<p>I&#8217;ve specified the config file I want to use and the pid file haproxy is currently using. The <b>$(cat /var/run/haproxy.pid)</b> takes the output of <b>cat /var/run/haproxy.pid</b> 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&#8217;t matter because we&#8217;ve been able to reload the haproxy configuration without dropping any connections and without causing any customer-facing issues.
</p>
<p>
<b>UPDATE:</b> There is a reload in some of the init.d scripts (I haven&#8217;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 <b>$(cat /path/to/pidfile)</b> whereas this haproxy_reload() function uses <b>$(<$PIDFILE)</b>. Either should work, but really, way to lead by example&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mgoff.in/2010/04/18/haproxy-reloading-your-config-with-minimal-service-impact/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>

