1
votes

I am using HAProxy for load balancing my HTTP requests. I would like to know if there is any way to customize the selection of backend server based on the responses returned by each server. I have a servlet which can return the responses (number of clients connected to it). I would like to use this information and route the request to the backend server which has the lowest number.

My HAProxy configuration looks like:

listen http_front xx.xx.xx.xx:8080
  mode http
  option httpchk GET /servlet/GetClientCountServlet
  server app1 xx.xx.xx.xx:8080 check port 8080
  server app2 xx.xx.xx.xx:8080 check port 8080
  server app3 xx.xx.xx.xx:8080 check port 8080
2

2 Answers

0
votes

Would not leastconn balance mode work for your use case? Otherwise I you can use Lua scripts to customize the way load balancing is done using HAProxy

0
votes

As I am searching for a solution in the same direction, maye this helps as a base:

Loadbalancing via custom lua script

Create a file called least_sessions.lua and add the following code:

local function backend_with_least_sessions(txn)
    -- Get the frontend that was used
    local fe_name = txn.f:fe_name()

    local least_sessions_backend = ""
    local least_sessions = 99999999999

    -- Loop through all the backends. You could change this
    -- so that the backend names are passed into the function too.
    for _, backend in pairs(core.backends) do


        -- Look at only backends that have names that start with
        -- the name of the frontend, e.g. "www_" prefix for "www" frontend.
        if backend and backend.name:sub(1, #fe_name + 1) == fe_name .. '_' then
            local total_sessions = 0

            -- Using the backend, loop through each of its servers
            for _, server in pairs(backend.servers) do

                -- Get server's stats
                local stats = server:get_stats()

                -- Get the backend's total number of current sessions
                if stats['status'] == 'UP' then
                    total_sessions = total_sessions + stats['scur']
                    core.Debug(backend.name .. ": " .. total_sessions)
                end
            end

            if least_sessions > total_sessions then
                least_sessions = total_sessions
                least_sessions_backend = backend.name
            end
        end
    end

    -- Return the name of the backend that has the fewest sessions
    core.Debug("Returning: " .. least_sessions_backend)
    return least_sessions_backend
end

core.register_fetches('leastsess_backend', backend_with_least_sessions)

This code will loop through all of the backends that start with the same letters as the current frontend, for example finding the backends www_dc1 and www_dc2 for the frontend www. It will then find the backend that currently has the fewest sessions and return its name.

Use a lua-load directive to load the file into HAProxy. Then, add a use_backend line to your frontend to route traffic to the backend that has the fewest, active sessions.

global
    lua-load /path/to/least_sessions.lua

frontend www
    bind :80
    use_backend %[lua.leastsess_backend]

backend www_dc1
    balance roundrobin
    server server1 192.168.10.5:8080 check maxconn 30

backend www_dc2
    balance roundrobin
    server server1 192.168.11.5:8080 check maxconn 30

More details: https://www.haproxy.com/de/blog/5-ways-to-extend-haproxy-with-lua/