Stick table - store strings to lookup strings

Hello,
I’m trying to achieve a certain functionality in HAProxy. It might be possible, it might not.

Our customers can use their own (whitelisted) domains.

What I want to achieve
When our main url becomes unresponsive or inaccessible we have a backup url which our customers can use(only) if the main url is down. When the main url is back up, you will get automatically redirected to the main url.

I’d like that redirect, to redirect them back to their original url. That information is unfortunately not currently available. But what we do have is the path they are using and the first part of the path is decisive for where I want to send them.

/env1 https://customurl
/env2 https://anothercustomurl

What I suspect might work

I figure I could do this by storing this data in a sticktable with no expiry. I figured using the path as the key and then store the url. But I could not find a way to do this.

If this is not possible, perhaps I can do something similar with a dynamic map. We only have a few thousand environments so performance wise it might still work.

Hoping someone can give me an insight as to how I can achieve this.

using stick tables you can store strings or arbitrary data by setting the table type to either “string” or “bin” on the table definition line.

It is documented there:

https://docs.haproxy.org/dev/configuration.html#11.1

Example:

# store URLs of max 256 chars, up to 1k entries, no expiry
stick-table type string len 256 size 1k

Since there is no way to remove an entry from a stick-table (aside from expiring), I suggest to use a general purpose counter (gpc) that is either set to 1 to indicate the URL is not accessible, or 0 to indicate the opposite (as if the entry was missing)

Hi Adarragon,
Thanks for your reply. That part I figured, I had also mentioned in my opening post. So the ‘key’ is not the problem, the issue is for every key I want to store a string, which I do not believe to be possible. As far as I can tell I can only store counters and integers.

I’d very much like my table to be similar to a map where I can lookup a key(environment) and return a url. But perhaps I’d need to see if I can do something like that with a map.

Somehow I don’t think maps are the way to go as inherently there would be a check and possible write for the map contents on every http request.

I might have a workaround to the limitation, and I’m just putting it here so it clarifies my situation, and what it is that I want to achieve.

I could collect the path and the url as separate variables. Then I could track the path as a key in a stick table. And then write that information to a separate custom log. The stick table is then essentially used for deduplication only.

I could then have a script checking this log, creating a map from this data, and send it to HAProxy API so it gets loaded into memory. That is a bit of a hassle though.

It would probably work, however I would very much prefer a more native HAProxy solution.

Oh sorry I misread that part of your message!

Yeah you’re right you cannot store generic string values inside sticktables, only numeric values

I don’t know of a straightforward/native solution to do this. Maps may be a solution indeed, but you need find a way to only write once in a while or group updates in batches, not for every request (like you suggested with a sidecar task). The more you perform writes on a map while it is accessed in parallel, the more contention there will be.

Another solution could be to leverage Lua with a custom sample fetch to perform the link between the path and the url. But again, if the script is mono-threaded and requires to share variables between threads (loaded using lua-load and not lua-load-per-thread) it will become a bottleneck. You could also manage the map through Lua (ie: lua fetch/converter as entry point) to add an abstraction layer and group updates to reduce contention.