在haproxy中执行lua脚本会出现"yield not allowed"错误

我想把来自客户端的SOAP请求负载均衡到我的服务的不同实例之间。我不能改变客户端并希望通过查看请求的负载并提取某个ID来使请求粘附到特定实例上,以确保具有相同ID的所有请求最终在同一实例上结束。

我编写了一个Lua脚本来查看负载和额外的信息,但由于某种原因,每5-6个请求有50-60毫秒的延迟来建立连接(在之间的请求中具有0毫秒的延迟),并且我看到以下日志条目

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)
点赞
用户4273524
用户4273524

实际上,我刚刚发现了我配置文件中的问题。

  1. 后端应该运行在 http 模式下,因此我在 backend my_backend 中添加了 mode http.

  2. Lua 脚本尝试访问请求体 (txn.req),但是当脚本被执行时,如果请求体还没有到达,则无法访问。你可以通过在 backend my_backend 中添加 option http-buffer-request 来强制 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
2017-10-15 22:29:48