在haproxy抛出lua脚本执行"不允许产生"

时间:2017-10-15 21:34:24

标签: lua haproxy

我希望在从客户端到我服务的不同实例之间对soap请求进行加权平衡。我无法更改客户端,并希望通过查看请求的有效负载并提取某个ID来使请求变得粘滞,以确保具有相同ID的所有请求最终都在同一个实例上。

我写了一个lua脚本来查看有效负载和我需要的额外信息。但由于某种原因,每5-6次请求有50-60ms的延迟建立连接(其间的请求有0ms的延迟),我看到日志条目如

Oct 15 23:27:48 rp-proxy-p1 haproxy[30995]: Lua sample-fetch 'parseElement': yield not allowed.
Oct 15 23:27:48 rp-proxy-p1 haproxy[30995]: Lua sample-fetch 'parseElement': yield not allowed.

如何防止此延迟并避免错误发生?它是什么意思?

我的haproxy.cfg

global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

    lua-load /etc/haproxy/routing.lua

defaults
    log global
    mode tcp
    option tcplog
    option dontlognull
    retries 3
    option redispatch
    maxconn 2000
    timeout connect 1000
    timeout client  500000
    timeout server  500000

frontend my_frontend
    bind *:7001
    default_backend my_backend

backend my_backend
    option tcp-check 
    balance source
    stick-table type string size 30000k expire 30m
    stick on "lua.parseElement" 
    server  server1  server1.domain.com:8080 check port 8080 weight 1
    server  server2  server2.domain.com:8080 check port 8080 weight 1

routing.lua

 function parseElement(txn, salt)

    local payload = txn.req:dup()
    local trx_id = payload.match(payload, "<transaction_id>(.-)</transaction_id>")
    core.Info("value: "..trx_id)
    return trx_id
end

core.register_fetches("parseElement", parseElement)

1 个答案:

答案 0 :(得分:1)

实际上我刚刚在配置中发现了错误。

1)后端应该以http模式运行,因此我添加了 mode httpbackend my_backend

第2)lua脚本尝试访问正文(txn.req),但是当执行脚本时Body尚未到达。您可以通过将option http-buffer-request添加到backend my_backend

来强制haproxy在执行脚本之前等待正文到达
backend my_backend
    mode http
    option http-buffer-request
    option tcp-check 
    balance source
    stick-table type string size 30000k expire 30m
    stick on "lua.parseElement" 
    server  server1  server1.domain.com:8080 check port 8080 weight 1
    server  server2  server2.domain.com:8080 check port 8080 weight 1