我正在尝试在HAProxy中定义一个LUA挂钩,以便一旦获得响应,就可以执行一个动作(杀死处理请求的容器)。我的问题是处理HAProxy缓冲区。我尝试了不同的实现,这是最接近的实现(尽管一半的时间不会将所有数据发送回客户端):
function hook(txn)
local in_len = txn.res:get_in_len()
while in_len > 0 do
txn.res:forward(in_len)
local out_len = txn.res:get_out_len()
while out_len ~= 0 do
core.yield()
out_len = txn.res:get_out_len()
end
in_len = txn.res:get_in_len()
end
os.execute("docker rm -f server_" .. txn.sf:srv_id())
end
core.register_action("hook", { "http-res" }, hook)
我最大的问题是没有Content-length标头,所以我不知道什么时候处理完所有信息以及何时完成。另外,每次调用get时,我都无法使set和get方法正常工作。
这是HAProxy的配置:
backend my-backend
balance roundrobin
http-response lua.hook
server server_1 192.168.1.3:80 check
在杀死后端服务器之前处理所有信息的正确方法是什么?
答案 0 :(得分:0)
在“ txn.res:forward(in_len)”中使用 forward function 时,您会将数据从http响应缓冲区的输入部分移至输出1 。
接下来,使用 yield (收益),它将把处理交给HAProxy,也就是发生问题的时间。 HAProxy无法分析标头(它们已直接移至输出缓冲区),并将认为响应无效。
所以我认为您总是只在HAProxy之前收到第一个缓冲区
如果您更改脚本并在TCP上下文中使用它,则HAProxy不必检查HTTP响应是否有效并且可以正常工作。 在TCP上下文中,您的脚本甚至可以简化为如下形式:
function hook(txn)
local in_len = txn.res:get_in_len()
while in_len > 0 do
core.yield()
in_len = txn.res:get_in_len()
end
os.execute("docker rm -f server_" .. txn.sf:srv_id())
end
core.register_action("hook", { "tcp-res" }, hook)
另外,您需要知道使用os.execute()不是一个好主意,因为它会阻塞HAProxy,直到执行完成。有关“ here”的更多信息,请参见“非阻塞设计”部分。 因此,最好采用其他选择,例如使用API将操作发送到容器。