HAProxy如何传递sc1_conn_rate值到Lua函数?及日志重复疑问
HAProxy动态延迟:如何将连接速率值传递到Lua函数?
我在HAProxy中实现了一个针对高频请求客户端的简单延迟方案:
HAProxy配置(haproxy.cfg):
acl conn_rate_high sc1_conn_rate(ipsticktable) gt 20 http-request lua.delay_request if conn_rate_high
Lua脚本:
function delay_request(txn) core.msleep(1000) end core.register_action("delay_request", { "http-req" }, delay_request);
这个方案能正常运行,但我希望根据客户端的连接速率动态调整延迟时长,而非固定延迟1秒。如果创建多个对应不同延迟的Lua函数和ACL会过于繁琐,因此想在Lua函数内直接根据连接速率计算延迟,但目前无法将sc1_conn_rate(ipsticktable)的值传递到Lua函数中。
尝试过的失败方法
我尝试通过设置事务变量传递值,但未成功:
修改后的HAProxy配置:
http-request set-var(txn.sc1_conn_rate) sc1_conn_rate(ipsticktable) acl conn_rate_high sc1_conn_rate(ipsticktable) gt 20 http-request lua.delay_request if conn_rate_high
修改后的Lua脚本:
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 core.register_action("delay_request", { "http-req" }, delay_request);
错误日志输出
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.
可见txn:get_var("sc1_conn_rate")返回了nil,导致Lua脚本运行报错。
核心问题
如何将sc1_conn_rate(ipsticktable)的数值传递到Lua函数中?
额外疑问
为什么所有txn:Alert的输出都打印了两次?
解决方案
1. 正确传递变量的方法
问题出在变量的命名空间引用上,在Lua中获取事务变量时,需要加上完整的命名空间前缀txn.:
修改Lua脚本中的变量获取逻辑,同时增加空值判断避免报错:
function delay_request(txn) local cr = txn:get_var("txn.sc1_conn_rate") if cr ~= nil then local delay = tonumber(cr) * 500 txn:Alert(string.format("conn_rate: %d, delay: %dms\n", cr, delay)) core.msleep(delay) else txn:Alert("conn_rate is nil, using default delay 1000ms\n") core.msleep(1000) end end core.register_action("delay_request", { "http-req" }, delay_request);
同时确保HAProxy配置中,设置变量的语句在http-request lua.delay_request之前执行(HAProxy按配置顺序执行指令):
http-request set-var(txn.sc1_conn_rate) sc1_conn_rate(ipsticktable) acl conn_rate_high sc1_conn_rate(ipsticktable) gt 20 http-request lua.delay_request if conn_rate_high
2. Alert输出重复的原因
HAProxy在处理HTTP请求时,可能会对同一个请求执行多次检查(比如请求的不同阶段触发了相同的逻辑,或是配置中存在重复的触发条件),导致Lua函数被调用两次,进而Alert输出重复。只要核心逻辑正常运行,重复日志不会影响功能;若想避免,可通过检查请求阶段或添加唯一标记来过滤重复执行。
内容的提问来源于stack exchange,提问作者P.Péter
相关产品推荐
相关产品推荐

