On Tue, 19 Jul 2016 15:28:25 +0530 Sachin Shetty <sshe...@egnyte.com> wrote:
> 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? Hi, The processing of the request by haproxy is pending while the execution of the lua action. The execution of "tcp-request content" directives are done before the execution of "http-request". So HAProxy executes first the capture and them the action which populate the map. Normally, HAProxy display a warning when it start, if it detects a configuration order different than a execution order. Try to replace the "tcp-request" by "http-request". > 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? It seems that you use a good 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. Yes, the usage of core.tcp() require some yields, and haproxu doesn't support yield during the execution of sample-fetches. For bypassing this problem, I use variables. I store the expected result in a variable during the execution of the action, and I use these variable with the use_backend directive. Thierry > 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 > >