You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 02:50:39