Instantly share code, notes, and snippets.

What would you like to do?
-- This service checks all the servers in the named backend (see the
-- backend_name var). If _any_ of them are up, it returns 200 OK. If
-- they are all down it returns a 500 FAILED.
-- This is intended to be used as a HTTP health check from an upstream
-- load balancer, without this check the most intelligent health check
-- that could be performed is a simple TCP check on the HAProxy frontend.
-- This would not fail in the event that HAProxy cannot see *any* of its
-- downstream servers
core.register_service("tcp_healthcheck", "http", function (applet)
-- Harcoded backend here, if anybody knows how to pass vars into Lua
-- from the haproxy.cfg please shout!
local backend_name = "aws-ldap"
local r = ""
backend = core.proxies[backend_name]
servers = backend["servers"]
local any_up = false
for k, v in pairs(servers) do
status = v.get_stats(v)["status"]
-- If _any_ of the servers are up, we will return OK
if (status == "UP") then
any_up = true
if ( any_up ) then
core.log(core.debug, "Found some servers up")
r = "OK"
core.log(core.debug, "Found NO servers up")
r = "FAILED"

This comment has been minimized.

Copy link

rk295 commented Oct 8, 2018

This script is handy if you have HAProxy behind an upstream load balancer, working in TCP mode. In such a scenario, all the upstream load balancer can do is TCP health check HAProxy on its frontend listening port. This type of health check is prone to cause issues if the HAProxy instance cannot see any of its downstream servers because although they would be marked down to HAProxy, the dumb TCP health check to the listen port will still succeed. With this lua script in place, we define a HTTP health check which reports OK if any downstream are up and FAILED if all downstreams are down. Sample HAProxy config below:

# Health check frontend, runs the Lua.
frontend status-lua
    bind  *:8000
    mode http
    http-request use-service lua.tcp_healthcheck

# Normal TCP traffic frontend
frontend tcp-fe
    bind  *:389
    option socket-stats
    option tcpka
    timeout client 5s
    default_backend aws-ldap

# Pair of TCP backends for the ldap_front frontend above
backend aws-ldap
    balance roundrobin
    server directory1 check port 8081
    server directory2 check port 8081
    option tcp-check

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment