在HAProxy中使用LUA处理HTTP响应

时间:2018-11-09 15:37:04

标签: lua haproxy

我正在尝试在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时,我都无法使setget方法正常工作。

这是HAProxy的配置:

backend my-backend
  balance roundrobin
  http-response lua.hook
  server server_1 192.168.1.3:80 check

在杀死后端服务器之前处理所有信息的正确方法是什么?

1 个答案:

答案 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​​将操作发送到容器。