Hello, Thanks for all your help. Any rough estimate on when the patch for doing DNS resolutions during runtime with asynchronous methods might be out? -Mrunmayi
On Saturday, May 30, 2015 2:47 AM, Thierry FOURNIER <tfourn...@haproxy.com> wrote: On Sat, 30 May 2015 00:25:59 +0000 (UTC) Mrunmayi Dhume <mrunmayi.dh...@yahoo.com> wrote: > Hello Thierry, > This seems to be what we are looking for, however it doesn't seem to work as > expected. When we use your example as is, it seems to fail with a 500 error. > When we switch to using a IP address, it works, so it seems like DNS > resolution is a problem? Yes, haproxy can not execute DNS résolutions while is running. It does DNS resolution only during the configuration parsing. Its because the standard DNS resolution are a synchronous process, and the HAProxy architecture does not accept synchronous processes. Note that a patch is currently in development for doing DNS resolutions during the runtime with asynchronous methods. As per this doc - http://cbonte.github.io/haproxy-dconv/configuration-1.6.html#4-option%20http_proxy http-proxy mode does not accept hostname, instead it only accepts IP. > The below example works: > core.register_fetches("choose_backend", function(txn) if >txn.sf.req_fhdr(Host) == 'example.test.com' and txn.sf.req_path == >'/test' then return "1.1.1.1" else if [...] end return >"default_backend" end); > In the haproxy configuration file, you must load the lua file, and usethe new > declared fetch in your frontend: > global [...] lua-load your-lua-file.lua [...] > listen your_frt [...] option http_proxy http-request set-uri >http://%[lua.choose_backend]%[url] > We don’t want to have to specify the IP as that means that we will have to > perform some sort of dns resolution in lua. Can you suggest an alternative? Actually, you can use maps to do this. A map is a file containing a name and his correspondance. You can put a hostname and the associated ip. This map can be updated throught the HAProxy's socket (without restarting HAProxy). This is not a real DNS Resolution, you must kown the full list of your domains. Thierry > Thanks! > -Mrunmayi > > > On Wednesday, May 27, 2015 1:50 AM, Thierry FOURNIER ><tfourn...@haproxy.com> wrote: > > > On Tue, 26 May 2015 21:39:23 +0000 (UTC) > Mrunmayi Dhume <mrunmayi.dh...@yahoo.com> wrote: > > > Thanks for your detailed reply Thierry. While this approach would solve the > > aspect of choosing the backend dynamically we still need to explicitly > > define each backend server separately in the haproxy config file. Our > > use-case involves having 100+ backends and we would prefer not to > > complicate the config file by defining each backend server as it is not > > easy to maintain. We prefer to set it based on incoming http request > > information like path or host header and keep haproxy config file simple > > with just listen and FE directives and of course single default backend > > server > > > Hi, > > HAProxy does not permit to choose the destination IP and PORT. > > But, maybe I have an ugly solution to your problem. > > You can try to deal with the option "option http_proxy". This option > understand the base proxy requests. > > You create a "listen" section which use Lua for rewriting the path of > the HTTP request like this: > > core.register_fetches("choose_backend", function(txn) > if txn.sf.req_fhdr(Host) == 'example.test.com' and > txn.sf.req_path == '/test' then > return "test1. example.com:8081" > else if > [...] > end > return "default_backend" > end); > > In the haproxy configuration file, you must load the lua file, and use > the new declared fetch inyour frontend: > > global > [...] > lua-load your-lua-file.lua > [...] > > listen your_frt > [...] > option http_proxy > http-request set-uri http://%[lua.choose_backend]%[url] > [...] > > Thierry > > > > if (Host == aaa.example.com’ and path == ‘/test’) thenbackend server == > > test1. example.com:8081 (Origin port changed) elsif (Host == > > aaa.example.com’ and path == ‘/test2’) backend server == test2. > > example.com:8080 (Origin port changed) elsif (Host == aaa.example.com’ and > > path == ‘/test3’) backend server == xxx.example.com:9999 ((Origin host and > > port changed) > > > > looking for something like the Traffic server lua api - > > https://docs.trafficserver.apache.org/en/latest/reference/plugins/ts_lua.en.html#ts-client-request-set-url-host > > > > Thanks, > > Mrunmayi > > > > > > > > On Tuesday, May 26, 2015 3:15 AM, Thierry FOURNIER > ><tfourn...@haproxy.com> wrote: > > > > > > On Fri, 22 May 2015 19:06:59 +0000 (UTC) > > Mrunmayi Dhume <mrunmayi.dh...@yahoo.com> wrote: > > > > > Hello, > > > I am using haproxy-1.6 with Lua. I have a use-case where I want to set > > > the destination (backend server) very dynamically, based on certain layer > > > 7 information (I am trying to avoid updating haproxy configuration and > > > make it complicated with a ~100 domain names and their corresponding > > > backend server name and do a map lookup, I want lua to do it ) > > > eg: from lua, based on certain layer 7 information I want to change the > > > backend server (set destination) it should connect to.. > > > if Host is ‘example.test.com’; then backend is test1.server.com elsif > > >Host is ‘example2.test.com; then backend is test2.server.com I want to > > >keep the haproxy config simple and have only the Listen directive listed > > >and take more control of the request flow from the LUA code. > > > The ATS traffic server does provide such functionality through the LUA > > > API hook to override backend server dynamically from Lua end > > > if ts.client_request.header[Host] == 'example.test.com' then > > >ts.client_request.set_url_host( > > >test1.server.comts.client_request.set_url_port(80)elsif > > >ts.client_request.header[Host] == 'example2.test.com' then > > >ts.client_request.set_url_host( test2.server.com ) > > >ts.client_request.set_url_port(80)end > > > Is it possible to do the same using Haproxy and Lua? > > > > > > Hi, > > > > Yes, you can, but the way is a little bit different. > > > > You must create a new sample fetch in Lua. This fetch executes the > > analysis of your HTTP resuest and returns the backend name. The > > following code (untested) must set in a lua file: > > > > core.register_fetches("choose_backend", function(txn) > > if txn.sf.req_fhdr(Host) == 'example.test.com' then > > return "backend1" > > else if txn.sf.req_fhdr(Host) == 'other.domain.com' then > > return "backend2" > > [...] > > end > > return "default_backend" > > end); > > > > In the haproxy configuration file, you must load the lua file, and use > > the new declared fetch inyour frontend: > > > > global > > [...] > > lua-load your-lua-file.lua > > [...] > > > > frontend your_frt > > [...] > > use_backend %[lua.choose_backend] > > [...] > > > > Note that your example code seem to choose a backend regarding only the > > header "host". In this case, the lua is useless, you can use the "maps" > > to choose your backend. The configuration looks like this: > > > > frontend yur_frt > > [...] > > use_backend %[req.fhdr(host),tolower,map(host_to_bck.map,default)] > > [...] > > > > The "default" argument is the name of the default backend. And the file > > "host_to_bck.map" contains a mapping between the hostnames (in lower > > case) and the backend names: > > > > example.test.com backend1 > > other.domain.com backend2 > > > > etc... > > > > Thierry > > > > > > > > > > Thank you, > > > Mrunmayi > > > > > > > >