NGINX `ngx_stream_core_module` 模块概览

一、模块定位与功能

  1. 通用 TCP/UDP 代理

    • 支持同时处理 TCP 和 UDP 流量,透明转发请求到后端服务器组(upstream)。
    • 可作为四层负载均衡,根据客户端 IP、权重、最少连接等策略将连接分发给后端。
  2. 预读(preread)机制

    • 在代理决策前预先读取部分客户端数据(如协议握手头),可用于后端选择或日志统计。
  3. 动态 DNS 解析

    • resolver 指令允许在运行时解析后端主机名,适用于后端节点 IP 可能变动的场景。
  4. 高级监听配置

    • listen 指令支持多种参数(udp/proxy_protocol/reuseport/so_keepalive 等),可细粒度控制监听 socket 特性。
  5. 内置 Hash、变量机制

    • 可通过 $remote_addr 等内置变量实现基于客户端 IP 的一致性哈希、最少连接等负载均衡方式。
    • variables_hash_bucket_sizevariables_hash_max_size 用于调优内部变量哈希表。

二、关键指令详解

1. stream { … }

位于主配置最顶层,用于开启“流”模块上下文,所有流相关配置都置于其内:

stream {…  
}

2. upstream <name> { … }

定义一组后端服务器,用于负载均衡:

stream {upstream backend {hash $remote_addr consistent;server backend1.example.com:12345 weight=5;server 192.168.0.2:12345      max_fails=3 fail_timeout=30s;server unix:/tmp/backend.sock;}… 
}
  • hash <key> [consistent]:基于 key(如 $remote_addr)做哈希,一致性模式下后端增删时扰动最小。
  • weightmax_failsfail_timeout:与 HTTP upstream 相同,用于调整权重与健康检查策略。

3. server { … }

stream 块内定义一个虚拟服务器,监听指定端口并将流量转发到某个 upstream 或单个后端:

stream {server {listen              12345;             # 监听 TCP 端口 12345proxy_connect_timeout 1s;               # 连接后端超时proxy_timeout        3s;               # 读写后端超时proxy_pass          backend;            # 转发到 upstream backend}server {listen              127.0.0.1:53 udp reuseport;  # 监听本地 UDP 53proxy_timeout        20s;proxy_pass          dns_upstream;       # 转发到 upstream dns_upstream}server {listen              [::1]:12345;       # IPv6 地址监听proxy_pass          unix:/tmp/stream.sock; # 转发到 Unix 域套接字}
}
  • listen <address:port> [参数...]:配置监听地址和端口,可附加 udpssl(若启用 TLS)、proxy_protocolreuseport 等。
  • proxy_pass <upstream|address>:将流量转发到指定 upstream 名称或后端地址(支持 Unix Socket)。
  • proxy_connect_timeout:与后端建立连接的最长期限。
  • proxy_timeout:包括连接、读、写操作的总体超时,若在此期间无数据交换则断开。
常用 listen 参数
  • udp:将该监听 socket 切换为 UDP 模式(默认 TCP)。
  • proxy_protocol:启用 PROXY 协议解码,用于获取客户端真实 IP(需后端或网络层支持 PROXY 协议)。
  • reuseport:为每个工作进程分别创建监听 socket,实现内核级负载均衡。
  • so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]:细粒度控制 TCP Keepalive 行为。
  • fastopen=number:启用 TCP Fast Open,需谨慎使用(允许跨握手发送少量数据)。
  • bind:强制对每个监听地址单独执行 bind(),以便与高级参数兼容。

4. preread_buffer_size <size>

默认16k
上下文stream, server

在真正将客户端流量代理给后端之前,预先在 NGINX 层读取的数据量,用于协议判断、日志或统计。

server {listen               54321;preread_buffer_size  32k;     # 预读 32KBproxy_pass           backend;
}

若需要从预读数据中提取特征(如协议头部),可相应调大此缓冲。

5. preread_timeout <time>

默认30s
上下文stream, server

预读阶段超时时间,若在此期间客户端无数据发送,则关闭连接。

server {listen               54321;preread_timeout      5s;      # 5 秒未接收数据则关闭proxy_pass           backend;
}

6. proxy_protocol_timeout <time>

默认30s
上下文stream, server

当在 listen … proxy_protocol 模式下启用 PROXY 协议,此指令规定在读取完整 PROXY 协议头前的最大等待时间:

server {listen                   12345 proxy_protocol;proxy_protocol_timeout   2s;    # 2 秒读完 PROXY 协议头proxy_pass               backend;
}

如果客户端连接后未在 proxy_protocol_timeout 指定时间内发送完整的 PROXY 头,则会被关闭。

7. resolver <address> […] [valid=time] [ipv4=on|off] [ipv6=on|off] [status_zone=zone]

默认:无
上下文stream, server

为后端 upstream 名称解析提供 DNS 服务器列表:

stream {resolver 127.0.0.1 [::1]:5353 valid=30s;resolver_timeout 5s;upstream dynamic_backend {server  backend1.example.com:12345 resolve;server  backend2.example.com:12345 resolve;}server {listen      12345;proxy_pass  dynamic_backend;}
}
  • valid=30s:覆盖 DNS TTL,强制每隔 30 秒刷新缓存。
  • ipv4=off / ipv6=off:控制是否解析 IPv4/IPv6。
  • resolver_timeout:DNS 查询超时时间。

8. tcp_nodelay on|off

默认on
上下文stream, server

开启或关闭 TCP_NODELAY, 用于禁用 Nagle 算法,减少小包延迟:

stream {tcp_nodelay on;server {listen      10000;proxy_pass  backend;}
}

多数场景下推荐开启(on),尤其对低延迟要求较高的协议(如 Redis、Memcached 等)。

9. 哈希表调优:variables_hash_bucket_size / variables_hash_max_size

默认64 / 1024
上下文stream

  • 用途:当你在 Stream 配置中使用自定义变量或正则表达式时,会在内部构建哈希表。通过这两项指令可手动调整哈希桶大小及最大容量,避免“桶冲突”或占用过多内存。
stream {variables_hash_bucket_size  128;variables_hash_max_size    2048;server {listen       11000;set $client_ip $remote_addr;             # 使用自定义变量proxy_pass   "$client_ip:20000";}
}

10. server_nameserver_names_hash_bucket_sizeserver_names_hash_max_size

上下文stream, server(自 1.25.5 起支持 Server Name Matching)

  • 仅在需要基于 TLS SNI(Server Name Indication)或IP+端口 匹配多个虚拟服务器时使用。
  • server_name 声明可匹配的主机名(支持通配符、正则);
  • 对应的哈希表调优参数与上文类似,用于存储大量 server_name 时的性能优化。
stream {variables_hash_bucket_size   64;variables_hash_max_size     1024;server {listen          443 ssl;server_name     example.com www.example.org;ssl_certificate     /etc/nginx/ssl/stream.pem;ssl_certificate_key /etc/nginx/ssl/stream.key;proxy_pass       backend;}
}

三、常用内置变量

stream 配置与日志中,可使用以下常见变量:

  • 客户端信息

    • $remote_addr:客户端 IP;
    • $remote_port:客户端端口;
    • $binary_remote_addr:二进制形式的客户端 IP,适合做哈希。
  • 代理协议(需 proxy_protocol

    • $proxy_protocol_addr / $proxy_protocol_port:来自 PROXY 头中的真实 IP/端口;
    • $proxy_protocol_server_addr / $proxy_protocol_server_port:服务器地址/端口(1.17.6+);
    • $proxy_protocol_tlv_*:支持访问 PROXY Protocol v2 TLV(如 $proxy_protocol_tlv_ssl_version)。
  • 会话统计

    • $bytes_received / $bytes_sent:当前会话已接收/发送字节数(1.11.4+);
    • $session_time:会话时长(秒.msec)(1.11.4+);
    • $status:当前会话状态码(200、400、403、500、502、503)(1.11.4+);
  • 服务器信息

    • $server_addr / $server_port:接收连接的本地地址及端口;
    • $hostname:Nginx 主机名;
    • $pid:工作进程 PID;
  • 时间

    • $msec:当前时间(秒.毫秒);
    • $time_local:本地时间(Common Log 格式);
    • $time_iso8601:本地时间(ISO 8601 格式);
  • 其他

    • $nginx_version:Nginx 编译版本;
    • $connection:会话编号(对当前 worker 进程)。

示例日志格式:

stream {log_format stream_log '$remote_addr:$remote_port ''$proxy_protocol_addr:$proxy_protocol_port - ''bytes_in=$bytes_received bytes_out=$bytes_sent ''status=$status ''time=$msec';access_log /var/log/nginx/stream_access.log stream_log;server {listen       3306;            # MySQL Proxyproxy_pass   mysql_upstream;}
}

四、完整示例

以下示例演示如何基于 ngx_stream_core_module 搭建一个通用的 TCP 流代理环境,支持多个后端集群、动态 DNS、PROXY 协议以及日志统计。

worker_processes auto;error_log /var/log/nginx/error.log info;events {worker_connections 2048;
}stream {################################# 全局调优(哈希、缓冲)   #################################preread_buffer_size       16k;preread_timeout           10s;proxy_protocol_timeout    5s;tcp_nodelay               on;variables_hash_bucket_size   64;variables_hash_max_size     2048;################################# DNS 动态解析与超时       #################################resolver             127.0.0.1 [::1]:5353 valid=30s ipv6=on ipv4=on;resolver_timeout     3s;################################# 定义后端 upstream 集群   #################################upstream mysql_backend {hash               $binary_remote_addr consistent;  server             db1.example.com:3306 weight=5;server             db2.example.com:3306 weight=5;server             192.168.1.100:3306  max_fails=2 fail_timeout=20s;}upstream redis_backend {server             10.0.0.10:6379;server             redis2.example.com:6379 resolve;  # 动态 DNS}upstream dns_servers {server             192.168.0.53:53;server             dns2.example.com:53 resolve;}################################# MySQL TCP 代理 (3306)     #################################server {listen         3306;proxy_connect_timeout   1s;proxy_timeout           5s;proxy_pass      mysql_backend;# 记录访问日志access_log /var/log/nginx/stream_mysql.log '$remote_addr:$remote_port ''bytes_in=$bytes_received bytes_out=$bytes_sent ''time=$msec status=$status';}################################# Redis TCP 代理 (6379)     #################################server {listen         6379;proxy_connect_timeout   0.5s;proxy_timeout           2s;proxy_pass      redis_backend;access_log /var/log/nginx/stream_redis.log '$remote_addr:$remote_port -> $upstream_addr ''rx=$bytes_received tx=$bytes_sent time=$msec';}################################# DNS UDP 代理 (53)         #################################server {listen         53 udp reuseport;proxy_pass     dns_servers;proxy_timeout  10s;access_log /var/log/nginx/stream_dns.log '$remote_addr:$remote_port ''dns_request rx=$bytes_received tx=$bytes_sent ''time=$msec';}################################# Unix Domain Socket 代理示例 ## ###############################server {listen         unix:/var/run/stream.sock;proxy_pass     unix:/var/run/backend.sock;}
}

要点解析:

  • 多协议示例:TCP(MySQL、Redis)和 UDP(DNS)共存,示范了 listen … udp reuseport; 与常规 TCP 监听的区别。
  • 动态 DNS:后端 redis_backenddns_servers 使用 resolve,结合全局 resolver 定期刷新。
  • 健康检查参数max_fails=2 fail_timeout=20s,后端 db1 连续失败 2 次且在 20 秒内失败则被标记为不可用。
  • 日志记录:示例自定义了访问日志格式,记录客户端 IP/端口、上下行字节数、会话时长与状态码。
  • UDP 重用端口reuseport 让内核将 53 端口请求分发给多个 worker 进程,提高并发 DNS 性能。
  • Unix 域套接字:可将流量从一个 Unix Socket 转发到另一个,适用于本机进程间高性能通信。

五、总结

ngx_stream_core_module 是 NGINX 在第四层(L4)协议上的通用解决方案,能够:

  • 支持任意 TCP/UDP 转发与负载均衡;
  • 提供预读、超时、PROXY 协议、安全套接字等高级功能;
  • 允许动态 DNS 解析、哈希负载均衡、TCP 优化(TCP_NODELAY、Keepalive);
  • 与内置变量结合,轻松实现日志统计与会话追踪。

通过合理配置上述指令,你可以根据不同业务场景(MySQL、Redis、DNS、SMTP 等)构建高可用、高并发且安全可靠的四层代理架构。希望本文的指令详解与示例配置,能让你快速掌握 ngx_stream_core_module 并在生产环境中灵活运用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/83813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM类加载高阶实战:从双亲委派到弹性架构的设计进化

前言 作为Java开发者&#xff0c;我们都知道JVM的类加载机制遵循"双亲委派"原则。但在实际开发中&#xff0c;特别是在金融支付、插件化架构等场景下&#xff0c;严格遵循这个原则反而会成为系统扩展的桎梏。本文将带你深入理解双亲委派机制的本质&#xff0c;并分享…

MATLAB | 绘图复刻(十九)| 轻松拿捏 Nature Communications 绘图

hello这次真的是好久不见了&#xff0c;前段时间确实太忙&#xff0c;后台都忙到没时间看&#xff0c;对不住大家的热情&#xff0c;这期复刻两个 Nature Communications 绘图&#xff0c;主要都和弦图有关&#xff1a; 原图 1 复刻图 1 原图 2 复刻图 2 这次绘图使用我自己开…

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享

设计模式(代理设计模式)

代理模式解释清楚&#xff0c;所以如果想对一个类进行功能上增强而又不改变原来的代码情况下&#xff0c;那么只需要让这个类代理类就是我们的顺丰&#xff0c;对吧?并行增强就可以了。具体增强什么?在哪方面增强由代理类进行决定。 代码实现就是使用代理对象代理相关的逻辑…

Flask + ECharts+MYSQL全球贸易数字化大屏

核心功能: 全球贸易热力图:展示中国与各国的贸易关系强度 贸易指标卡片:实时显示贸易总额、投资额等关键指标 贸易伙伴排名:展示中国前10大贸易伙伴 贸易类型分布:展示各类商品的贸易占比 全球实时动态:滚动显示全球贸易、投资等实时事件 技术亮点: 使用WebSocket实现实…

wpf Behaviors库实现支持多选操作进行后台绑定数据的ListView

<ListView ItemsSource"{Binding SchemeItems}" SelectionMode"Extended" VerticalAlignment"Stretch" HorizontalAlignment"Stretch"><ListView.ContextMenu><ContextMenu><MenuItem Header"删除" …

50个JAVA常见代码大全:学完这篇从Java小白到架构师

50个JAVA常见代码大全&#xff1a;学完这篇从Java小白到架构师 Java&#xff0c;作为一门流行多年的编程语言&#xff0c;始终占据着软件开发领域的重要位置。无论是初学者还是经验丰富的程序员&#xff0c;掌握Java中常见的代码和概念都是至关重要的。本文将列出50个Java常用…

【Linux手册】冯诺依曼体系结构

目录 前言 五大组件 数据信号 存储器&#xff08;内存&#xff09;有必要吗 常见面试题 前言 冯诺依曼体系结构是当代计算机基本架构&#xff0c;冯诺依曼体系有五大组件&#xff0c;通过这五大组件直观的描述了计算机的工作原理&#xff1b;学习冯诺依曼体系可以让给我们更…

10_聚类

描述 聚类&#xff08;clustering&#xff09;是将数据集划分成组的任务&#xff0c;这些组叫作簇&#xff08;cluster&#xff09;。其目标是划分数据&#xff0c;使得一个簇内的数据点非常相似且不同簇内的数据点非常不同。与分类算法类似&#xff0c;聚类算法为每个数据点分…

【SSM】SpringBoot学习笔记1:SpringBoot快速入门

前言&#xff1a; 文章是系列学习笔记第9篇。基于黑马程序员课程完成&#xff0c;是笔者的学习笔记与心得总结&#xff0c;供自己和他人参考。笔记大部分是对黑马视频的归纳&#xff0c;少部分自己的理解&#xff0c;微量ai解释的内容&#xff08;ai部分会标出&#xff09;。 …

国产高性能pSRAM选型指南:CSS6404LS-LI 64Mb QSPI伪静态存储器

一、芯片基础特性 核心参数 容量 &#xff1a;64Mb&#xff08;8M 8bit&#xff09;电压 &#xff1a;单电源供电 2.7-3.6V &#xff08;兼容3.3V系统&#xff09;接口 &#xff1a;Quad-SPI&#xff08;QPI/SPI&#xff09;同步模式封装 &#xff1a; SOP-8L (150mil) &#…

Cilium动手实验室: 精通之旅---4.Cilium Gateway API - Lab

Cilium动手实验室: 精通之旅---4.Cilium Gateway API - Lab 1. 环境准备2. API 网关--HTTP2.1 部署应用2.2 部署网关2.3 HTTP路径匹配2.4 HTTP头匹配 3. API网关--HTTPS3.1 创建TLS证书和私钥3.2 部署HTTPS网关3.3 HTTPS请求测试 4. API网关--TLS 路由4.1 部署应用4.2 部署网关…

20250605在微星X99主板中配置WIN10和ubuntu22.04.6双系统启动的引导设置

rootrootrootroot-X99-Turbo:~$ sudo apt-get install boot-repair rootrootrootroot-X99-Turbo:~$ sudo add-apt-repository ppa:yannubuntu/boot-repair rootrootrootroot-X99-Turbo:~$ sudo apt-get install boot-repair 20250605在微星X99主板中配置WIN10和ubuntu22.04.6双…

MyBatis之测试添加功能

1. 首先Mybatis为我们提供了一个操作数据库的会话对象叫Sqlsession&#xff0c;所以我们就需要先获取sqlsession对象&#xff1a; //加载核心配置文件 InputStream is Resources.getResourceAsStream("mybatis-config.xml"); //获取sqlSessionFactoryBuilder(是我…

[论文阅读] 人工智能+软件工程 | MemFL:给大模型装上“项目记忆”,让软件故障定位又快又准

【论文解读】MemFL&#xff1a;给大模型装上“项目记忆”&#xff0c;让软件故障定位又快又准 论文信息 arXiv:2506.03585 Improving LLM-Based Fault Localization with External Memory and Project Context Inseok Yeo, Duksan Ryu, Jongmoon Baik Subjects: Software Engi…

Java开发中复用公共SQL的方法

在一次Java后端开发的面试中&#xff0c;面试官问了我一个问题&#xff1a;“你在写代码时会复用公共SQL吗&#xff1f;如果会的话&#xff0c;能详细介绍一下你是如何实现的吗&#xff1f;”这个问题让我眼前一亮&#xff0c;因为在实际项目中&#xff0c;SQL复用确实是一个非…

C#学习26天:内存优化的几种方法

1.减少对象创建 使用场景&#xff1a; 在循环或密集计算中频繁创建对象时。涉及大量短生命周期对象的场景&#xff0c;比如日志记录或字符串拼接。游戏开发中&#xff0c;需要频繁更新对象状态时。 说明&#xff1a; 重用对象可以降低内存分配和垃圾回收的开销。使用对象池…

【opencv】基础知识到进阶(更新中)

安装&#xff1a;pip install opencv-python 入门案例 读取图片 本节我们将来学习,如何使用opencv显示一张图片出来,我们首先需要掌握一条图片读取的api cv.imread("图片路径","读取的方式") # 图片路径: 需要在工程目录中,或者一个文件的绝对路径 # 读取…

【Part 3 Unity VR眼镜端播放器开发与优化】第二节|VR眼镜端的开发适配与交互设计

文章目录 《VR 360全景视频开发》专栏Part 3&#xff5c;Unity VR眼镜端播放器开发与优化第一节&#xff5c;基于Unity的360全景视频播放实现方案第二节&#xff5c;VR眼镜端的开发适配与交互设计一、Unity XR开发环境与设备适配1.1 启用XR Plugin Management1.2 配置OpenXR与平…

SQL进阶之旅 Day 16:特定数据库引擎高级特性

【SQL进阶之旅 Day 16】特定数据库引擎高级特性 开篇 在“SQL进阶之旅”系列的第16天&#xff0c;我们将探讨特定数据库引擎的高级特性。这些特性通常为某些特定场景设计&#xff0c;能够显著提升查询性能或简化复杂任务。本篇文章将覆盖MySQL、PostgreSQL和Oracle的核心高级…