当前位置: 首页 > news >正文

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 并在生产环境中灵活运用。

相关文章:

  • 软考 系统架构设计师系列知识点之杂项集萃(82)
  • centos查看开启关闭防火墙状态
  • 9.axios底层原理,和promise的对比(2)
  • AI Agent 项目 SUNA 部署环境搭建 - 基于 MSYS2 的 Poetry+Python3.11 虚拟环境
  • git连接本地仓库以及gitee
  • 验证电机理论与性能:电机试验平板提升测试效率
  • 智慧照明:集中控制器、单双灯控制器与智慧灯杆网关的高效协同
  • 18650锂电池组点焊机:高效组装锂电池的关键工具|比斯特自动化
  • 【Pinia】Pinia和Vuex对比
  • 计算机程序文档
  • 虎扑正式易主,迅雷完成收购会带来什么变化?
  • es在Linux安装
  • 美化显示LLDB调试的数据结构
  • 如何基于Mihomo Party http端口配置git与bash命令行代理
  • 护网面试题目2025
  • 计算机网络领域所有CCF-A/B/C类期刊汇总!
  • Java 依赖注入、控制反转与面向切面:面试深度解析
  • 【PmHub面试篇】PmHub集成Redission分布式锁保障流程状态更新面试专题解析
  • ubuntu24.04 使用apt指令只下载不安装软件
  • Ubuntu中常用的网络命令指南
  • 北京 网站建设 京icp/厦门seo管理
  • 护士公共课在哪个网站做/营销手段
  • 网站制作咨询公司/百度网络推广营销
  • 做网站页面的需要哪些技巧/磁力天堂最新版地址
  • 手机网站建设找哪家/营销软文范例大全
  • 国外做黄色网站/电商代运营十大公司排名