You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于TCP首包数据实现Nginx TCP连接路由转发

Nginx 基于TCP首包内容实现路由转发的实现方案

原生Nginx的stream模块默认不支持基于首包payload内容的路由,你可以通过以下两种可行路径实现需求:

方案一:使用ngx_stream_lua_module模块实现(推荐)

这是落地成本最低的定制方案,具体逻辑如下:

  • 编译Nginx时加入ngx_stream_lua_module模块即可,也可以直接使用内置了该模块的OpenResty发行版,省掉单独编译的步骤
  • 在stream配置块的preread_by_lua_block阶段读取首包内容,匹配规则后转发到对应上游即可
  • 示例配置片段如下:
stream {
    upstream server1 {
        server 192.168.1.10:1234; # 替换为server1的实际地址
    }
    upstream server2 {
        server 192.168.1.20:1234; # 替换为server2的实际地址
    }

    server {
        listen 8888; # 替换为实际监听端口
        preread_by_lua_block {
            -- 读取首包前2字节,可根据你的实际标识长度调整
            local sock, err = ngx.req.socket()
            if not sock then
                ngx.exit(ngx.ERROR)
            end
            local data, err = sock:receive(2)
            if data == "A1" then
                ngx.var.upstream = "server1"
            elseif data == "A2" then
                ngx.var.upstream = "server2"
            else
                -- 不匹配规则可走默认上游或者直接关闭连接
                ngx.exit(ngx.ERROR)
            end
        }

        proxy_pass $upstream;
        proxy_request_buffering on; # 开启preread缓冲,确保首包数据会同步转发到上游
    }
}
  • 如果首包标识是变长格式,也可以调整receive的参数,比如按分隔符读取receive("\n")来获取完整的标识位再做匹配。

方案二:自研Nginx stream扩展模块

如果不想引入Lua依赖,可以自行开发Nginx stream模块,在preread阶段读取TCP payload,匹配规则后设置对应上游地址即可,开发成本比Lua方案高,适合对性能要求极高、不愿意引入Lua虚拟机的场景。

踩坑提示

  • TCP是流式协议,需要确认你的业务首包标识一定会在第一个TCP段里发送,不会出现粘包拆包导致首包标识被拆分的情况;如果存在拆包可能,需要在逻辑里加缓冲拼接完整的标识位再做匹配。
  • 不要在content阶段读取数据后再转发,会导致首包数据被消费没有传递给上游,preread阶段是最合适的处理位置,该阶段缓冲的数据会自动转发给上游。

内容的提问来源于stack exchange,提问作者perekinsun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 08:36:03