Hi,

We always had a unique requirement of picking a backend based on response
from a external http service.  In the past we have got this working by
routing requests via a modified apache and caching the headers in maps for
further request, but now I am trying to simplify our topology and trying to
get this done using just haproxy and lua.

I am running in to some problems:

Lua method:

function choose_backend(txn)

        local host = txn.http:req_get_headers()["host"][0]

        core.Alert("Getting Info:" .. host)

        local sock = core.tcp()

        sock:connect("127.0.0.1", 6280)

        sock:send("GET /eos/rest/private/gds/l1/1.0/domain/" .. host ..
"\r\n")

        result = sock:receive("*a")

        sock:close()

        core.Alert("Received Response:" .. result .. "<")

        core.set_map("/tmp/proxy_webui.map", host, result)

        core.Alert("Map Set:" .. host .. "-->" .. result .. "<")

end



core.register_action("choose_backend", { "http-req" }, choose_backend)


Haprpxy Conf:

frontend luatest

        mode http

        maxconn 10000

        bind *:9000



        use_backend %[hdr(host),lower,map(/tmp/proxy_webui.map)] if FALSE #
To declare the map


        http-request lua.choose_backend


        tcp-request content capture hdr(host),map(/tmp/proxy_webui.map) len
80

        acl is_ez_pod capture.req.hdr(0) http://127.0.0.1:6280

        use_backend ez_pod if is_ez_pod





backend ez_pod

        server ez_pod 192.168.56.101:6280 maxconn 2





There are some issues:
1. I do see Map Set called correctly in the logs, but the haproxy capture
does not find the key in the map for the first request. Is this related to
async execution of luna routine?
2. I expected subsequent requests to see the value atleast, but even that is
not consistent, some request see the value in the map and some donĀ¹t
Is there a better way to do this? I already found that I cannot invoke the
luna routine with use_backend because yield is not allowed in a sample fetch
context. 

What would be the best way to achieve this, our requirement is similar to
what can be done with redis+nginx here:
http://openresty.org/en/dynamic-routing-based-on-redis.html except for we
have an http service that decides the backend instead of a redis service.

Thanks
Sachin


Reply via email to