Define custom load balancing algorithm
Asked Answered
M

1

11

Here is the situation:

I have a number of web servers, say 10. I need to use a (software) load balancer which can be implemented using a reverse proxy server, like HAProxy or Varnish. Now, All the traffic that we serve is over https and not http, so Varnish is out of the question.

Now, I want to divide the users' request into a few categories, which depend on one of the input (POST) parameters of the request. Depending on that parameter, I need to divide the request among the servers, as based on that, (even if all other input (POST) parameters are same) different servers would serve differently.

So, I need to define a custom load balancing algorithm, such that, for a particular value of that parameter, I divide the load to specific 3 (say), for some other value, divide the request to specific 2 and for other value(s), to remaining 5.

Since I cannot use varnish, as it cannot be use to terminate ssl (defining custom algorithm would have been easy in VCL), I am thinking of using HA-Proxy.

So, here is the question:

Can anyone help me with how to define a custom load balancing function using HA-Proxy?

I've researched a lot and I could not find any such document with which we can. So, if it is not possible with HA-Proxy, can you refer me to some other reverse-proxy service, that can be used as a load balancer too, such that it meets both the above criteria? (ssl termination and ability to define a custom load balancing).

EDIT:

This question is in succession with one of my previous questions. Varnish to be used for https

Managerial answered 3/12, 2015 at 15:40 Comment(3)
Would Hitch → PROXY protocol → Varnish 4.1 be an option for you?Poleax
@CarlosAbalde, I saw that. It is not what I'm looking for. See the link: #33475654. This is also a question that I asked...which is related.Managerial
HAProxy 1.6 - req.body_param + ACL to define the route to your backends - cbonte.github.io/haproxy-dconv/…Jacklyn
K
5

I'm not sure what your goal is, but I'd suggest NOT doing custom routing based on the HTTP request body at all. This will perform very poorly, and likely outweigh any benefit you are trying to achieve.

Anything that has to parse values beyond typical HTTP headers at your load balancer will slow things down. Cookies by themselves are generally a bad idea if you can avoid it.

If you can control the path/route values that is likely a much better idea than to parse every POST for certain values.


You can probably achieve what you want via NGINX with lua scripts (the Kong platform is based on them), but I can't say how hard that would be for you...

https://github.com/openresty/lua-nginx-module#readme

Here's an article with a specific example of setting different upstreams based on lua input.

http://sosedoff.com/2012/06/11/dynamic-nginx-upstreams-with-lua-and-redis.html

server {
  ...BASE CONFIG HERE...

  port_in_redirect off;

  location /somepath {
    lua_need_request_body on;

    set $upstream "default.server.hostname";

    rewrite_by_lua '
      ngx.req.read_body()  -- explicitly read the req body
      local data = ngx.req.get_body_data()
      if data then
        -- use data: see
        -- https://github.com/openresty/lua-nginx-module#ngxreqget_body_data
        ngx.var.upstream = some_deterministic_value
      end
    '

    ...OTHER PARAMS...
    proxy_pass http://$upstream
  }
}
Kentish answered 15/12, 2015 at 6:28 Comment(8)
Hi @Tracker...thanks for the reply. There are a few things I want to test for the UEx. So, I want to serve the "same" request differently to different users based on a single parameter. (Its like A-B testing on server level)Managerial
can you use other parameters besides post? you can't change the path based on your A/B params? Or a composite hash based on IP and useragent? A cookie?Kentish
IP and user agent would not work...Actually, my A/B param (specifically) is that POST param itself and I'm not very sure if we store that that data in cookies (in a session) and if we don't, changing that part of the codebase would also be a headache.Managerial
assuming are you posting url-form-encoded? as I said, you could do it with nginx/lua ... but that's not one of the proxies you mentioned. wiki.nginx.org/HttpLuaModule#ngx.req.get_post_argsKentish
Also... github.com/openresty/lua-nginx-module ... which has some examples on reading data and adjusting the url.. not sure about changing/using the proxypass directive from lua based on input/variables...Kentish
@Managerial I added some more details on using nginx for your task to my answer... you can also use an external file, for reuse.Kentish
I'm not really sure if this will actually solve my problem...I have awarded the bounty on the thought that if this actually solves my problem, bounty will be lost...I hoped you had given the answer a day or two earlier though :) I'll accept the answer in the future if it solves...Managerial
Let us continue this discussion in chat.Kentish

© 2022 - 2024 — McMap. All rights reserved.