Stick url to backend server testing with etherpad

I am testing a bit with etherpad. You can create a simple collaboration notepad, by generating a unique string at the end of the url, like this:

group1 is using Riseup Pad
group2 is using Riseup Pad

How would I create a haproxy cfg that would redirect users to a specific backend based on a previously used url?

Say I have one server running and thus all urls are going to be on that server. When the load increases I scale this task to 2 servers.

Now haproxy needs to remember what urls where on the first server and keep users there. But if there is a new request for a url that is on the first server, the first server should still receive it.
If there is a new url the new url should be send to the 2nd server.

Thus in this scenario, you need to scale to 2nd server at 80% load or so, so you can still facilitate new users on this first server.

I thought about using maps but maybe that is not the best choice “This lookup is done by a linear search and can be expensive with large lists!”

Currently I have this:

 http-request set-map(/etc/haproxy/maps/etherpad.map) %[url] %[str(value)] if { path_beg /p/ }
  use_backend %[req.hdr(host),lower,word(1,:),map(/etc/haproxy/maps/etherpad.map,etherpad)]

But I do not see an option somewhere to select a server. So I guess maybe stick-tables?

Currently I am trying with:

stick-table type string len 15 size 1000 nopurge store server_id
stick store-request url if { path_beg /p/ }
stick match url if { path_beg /p/ }

I am not sure, but I do not think there is a necessity to have an empty map file in order to be able to use it in the configuration.

It looks like the haproxy does not reload the config, if the map file is not there.

Looking at maps, weird is that
v2/services/haproxy/storage/maps/test.map
this returns map entries
and this
v2/services/haproxy/runtime/maps/test.map
returns:
{“description”:“pattern loaded from file ‘/etc/haproxy/maps/test.map’ used by map at file ‘/etc/haproxy/haproxy.cfg’ line 399”,“file”:"/etc/haproxy/maps/test.map",“id”:“45”}

Should that not be at least having the entries from storage?

I would strongly recommend not doing it this way. You are using maps in a way that it is absolutely not designed for. Even if you would periodically write the maps contents to a file, you would still loose data when you loose the process (application crash, power failure, kernel crash, host failure).

If you loose the association and clients get the wrong server, they wouldn’t be able to access their previously stored data.

stick-tables and other run-time data is designed for session identifiers, which means that when you loose them, you have to login again. Not completely loose access to your previous work.

You can probably achieve something like this with LUA and a redis backend, but it will require you put in some work.

Haproxy will probably never write to the filesystem during run-time, because that is a terrible thing for a reverse proxy to do.

I also think it’s unlikely that new features or behavior changes will be implemented, based on this use-case.

If you want to report bugs, you need to fill out the complete issue template. If you can’t spend a few minutes to do this, why would a developer spend half a day working on your bug?

I totally agree.

However, the idea of the template is to make sure that necessary information is available so someone can act on it.
The goal of the template is not the template itself.

I think the information I supplied is enough for a developer to understand and judge if something needs to be done. It is just a minor thing. You can leave it and update the manual for this, or change it.

Wouldn’t using the proper balancing strategy work?

Check this post: Hash-based load balancing

Just read it, did not know about it. I think you are right, probably better.