In haproxy, I implemented a simple way to delay clients sending too many requests too fast:
In haproxy.cfg:
acl conn_rate_high sc1_conn_rate(ipsticktable) gt 20
http-request lua.delay_request if conn_rate_high
In the lua file:
function delay_request(txn)
core.msleep(1000)
end
core.register_action("delay_request", { "http-req" }, delay_request);
This works okay, but what if I want to delay more if there are even more requests? I can have multiple delay functions with different delays, and multiple acls and conditions, but this gets clunky really fast.
The sensible thing would be to calculate the delay inside the lua function from the connection rate. My problem is, that I cannot pass the connection rate value to the lua function.
Here is what I tried and does not work:
In haproxy.cfg:
http-request set-var(txn.sc1_conn_rate) sc1_conn_rate(ipsticktable)
In the lua script:
function delay_request(txn)
local cr = tostring(txn:get_var("sc1_conn_rate"))
txn:Alert("conn_rate: ")
txn:Alert(cr)
txn:Alert("\n")
core.msleep(tonumber(cr) * 500)
end
The output in the log is:
Nov 18 14:41:06 haproxy[10988]: conn_rate:
Nov 18 14:41:06 haproxy[10988]: conn_rate:
Nov 18 14:41:06 haproxy[10988]: nil
Nov 18 14:41:06 haproxy[10988]: nil
Nov 18 14:41:06 haproxy[10988]: conn_rate:
Nov 18 14:41:06 haproxy[10988]: conn_rate:
Nov 18 14:41:06 haproxy[10988]: nil
Nov 18 14:41:06 haproxy[10988]: nil
Nov 18 14:41:06 haproxy[10988]: .
Nov 18 14:41:06 haproxy[10988]: .
Nov 18 14:41:06 haproxy[10988]: Lua function 'delay_request': runtime error: /etc/haproxy/delay.lua:6: attempt to perform arithmetic on a nil value from /etc/haproxy/delay.lua:6 C function line 1.
Nov 18 14:41:06 haproxy[10988]: Lua function 'delay_request': runtime error: /etc/haproxy/delay.lua:6: attempt to perform arithmetic on a nil value from /etc/haproxy/delay.lua:6 C function line 1.
So, as far as I understand, get_var
got nil
for some reason. :(
My main question is: How do I pass the value of sc1_conn_rate(ipsticktable) to the lua function?
Bonus question: Why are all alerts printed twice?