如何使用openresty lua中的第一个字节内容将tcp请求发送到后端 [英] How to dispatch tcp request to backends with first byte of content in openresty lua

查看:424
本文介绍了如何使用openresty lua中的第一个字节内容将tcp请求发送到后端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have started a openresty with one tcp server and two backends. The tcp server dispatch the request to backends according to the content from tcp stream. Following is an example of openresty configuration:

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脚本根据请求中的第一个字节在请求和后端之间建立桥梁.

I don't know how to make a bridge between the request and the backend according to the first byte in the request with lua script.

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

If anyone can help one this?

推荐答案

这个问题已经很老了,但我希望我的回答对你仍然有用.

The question is pretty old, but I hope that my answer is still relevant for you.

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

这篇关于如何使用openresty lua中的第一个字节内容将tcp请求发送到后端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆