如何使用openresty lua中的第一个内容字节将tcp请求发送到后端

问题描述 投票:1回答:1

我已经开始使用一个tcp服务器和两个后端的openresty。 tcp服务器根据来自tcp流的内容将请求分派给后端。以下是openresty配置的示例:

stream {
  # define a TCP server listening on the port 1234:
  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 )
      -- reveive first byte
      local data, err = sock:receive( 1 )

      --dispatch two backend1 if data is greater than 'a', otherwise dispatch to backend2
      local a = string.byte(data, 1, 1 )
      if a > 'a' then
        --how to send to backend1
      else
        --how to send to backend2
      end
    }
  }
}

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

如果有人可以帮助一个吗?

tcp proxy dispatch bridge openresty
1个回答
0
投票

这个问题已经过时了,但我希望我的回答仍然适合你。

stream {

  lua_code_cache on;

  init_by_lua_block {
    -- cache package on startup
    require('ngx.balancer')
    -- share backend addresses via global table
    -- (not recommended, only for demo purposes)
    _G.BACKENDS = {
      {'172.17.0.1', 8081},
      {'172.17.0.1', 8082},
    }
  }

  upstream lua_dispatcher {
    # just an invalid address as a placeholder
    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
    }
  }

  # proxy
  server {
    listen 9000;

    proxy_pass lua_dispatcher;

    # cosocket API not available in balancer_by_lua_block,
    # so we read the first byte here and keep it in ngx.ctx table
    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)
    }
  }

  # mock upstream 1
  server {
      listen 172.17.0.1:8081;
      content_by_lua_block {
        ngx.say('first')
      }
  }

  # mock upstream 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
© www.soinside.com 2019 - 2024. All rights reserved.