如何在openresty lua中通过内容的第一个字节将tcp请求分发到后端

我已经启动了一个具有一个tcp服务器和两个后端的openresty。tcp服务器根据来自tcp流的内容将请求分派到后端。以下是openresty配置的示例:

stream {
  # 定义一个监听端口1234的TCP服务器:
  upstream backend1 {
    server  172.17.0.1:8081;
  }
  upstream backend2 {
    server  172.17.0.1:8082;
  }

  server {
    listen 1234;

    content_by_lua_block {
      local sock = ngx.req.socket( true )
      -- 接收第一个字节
      local data, err = sock:receive( 1 )

      -- 如果数据大于'a',则将其分配到两个backend1,否则将其分配到backend2
      local a = string.byte(data, 1, 1 )
      if a > 'a' then
        -- 如何发送到backend1
      else
        -- 如何发送到backend2
      end
    }
  }
}

我不知道如何使用lua脚本根据请求中的第一个字节在请求和后端之间建立桥梁。

如果有人能够帮助这个问题,那就太好了。

点赞
用户9783845
用户9783845

这个问题很旧了,但我希望我的回答仍然适合你。

stream {

  lua_code_cache on;

  init_by_lua_block {
    -- 在启动时缓存包
    require('ngx.balancer')
    -- 通过全局表共享后端地址(仅作演示用途,不建议使用)
    _G.BACKENDS = {
      {'172.17.0.1', 8081},
      {'172.17.0.1', 8082},
    }
  }

  upstream lua_dispatcher {
    # 作为占位符的无效地址
    server 0.0.0.1:1234;

    balancer_by_lua_block {
      local balancer = require('ngx.balancer')
      local backend_index
      if ngx.ctx.request_first_byte > 'a' then
        backend_index = 1
      else
        backend_index = 2
      end
      local backend_table = _G.BACKENDS[backend_index]
      local ok, err = balancer.set_current_peer(table.unpack(backend_table))
      if not ok then
          ngx.log(ngx.ERR, err)
          ngx.exit(ngx.ERROR)
      end
    }
  }

  # 代理
  server {
    listen 9000;

    proxy_pass lua_dispatcher;

    # balancer_by_lua_block 中不可用的 cosocket API,
    # 所以我们在这里读取第一个字节并将其保存在 ngx.ctx 表中
    preread_by_lua_block {
      local sock = ngx.req.socket()
      local data, err = sock:receive(1)
      if not data then
        ngx.log(ngx.ERR, err)
        ngx.exit(ngx.ERROR)
      end
      ngx.ctx.request_first_byte = data:sub(1, 1)
    }
  }

  # 模拟上游 1
  server {
      listen 172.17.0.1:8081;
      content_by_lua_block {
        ngx.say('first')
      }
  }

  # 模拟上游 2
  server {
      listen 172.17.0.1:8082;
      content_by_lua_block {
        ngx.say('second')
      }
  }

}

$ nc -C localhost 9000 <<< '123'
second
$ nc -C localhost 9000 <<< '223'
second
$ nc -C localhost 9000 <<< 'a23'
second
$ nc -C localhost 9000 <<< 'b23'
first
$ nc -C localhost 9000 <<< 'c23'
first
2019-03-19 21:26:27