文章目录
Nginx Stream TCP 协议按 IP 转发
背景
为了优化网络性能和提升服务的可用性,我们需要在 Nginx 中配置 stream 模块 ,使其根据客户端的 IP地址 将 TCP 请求 动态转发到不同的后端服务器节点。此需求适用于场景如数据库代理(如 MySQL)、TCP 服务负载均衡、以及地域或来源IP分流的流量调度。
需求目标
-
按客户端 IP 路由:
- 系统需根据客户端的来源 IP,将 TCP 请求智能地转发到指定的后端服务器节点。
- 支持自定义 IP 段或单个 IP 的匹配规则。
-
后端节点配置:
- 后端服务器节点可能为多台,并且每个节点对应不同的业务数据或服务端口。
- 默认情况下,如果 IP 未匹配任何指定规则,需将请求转发到预设的默认节点。
-
负载均衡与健康检查(可选):
- 每个后端节点需要支持健康检查机制,当某个节点不可用时自动切换到其他节点。
- 系统应具有一定的容错能力,避免单点故障影响整体服务。
-
日志与监控:
- Nginx 需记录所有连接的来源 IP 及其转发的后端服务器节点,支持日志分析与故障排查。
- 系统需兼容现有的日志采集与监控平台,实现对转发情况的实时监控。
-
可扩展性:
- 配置应支持动态扩展,即可在不重启 Nginx 的情况下更新 IP 路由规则或后端节点。
- 后端节点可根据业务需求随时增加或减少。
使用场景
- 数据库代理:根据客户端所在的网络段,将数据库查询请求分发到不同的数据中心。
- TCP 业务调度:如按地域 IP 将 TCP 连接转发到最近的服务器节点,提升访问速度。
- 安全过滤:部分高风险 IP 或网络段的请求可路由到专用节点进行安全处理。
成功标准
- 按 IP 匹配的请求能正确转发到目标后端服务器。
- 未匹配的请求能转发到默认节点,且整体服务稳定。
- 后端服务器节点状态异常时,能自动切换到其他可用节点。
技术要求
- 使用 Nginx 的 stream 模块 实现 TCP 转发。
- 支持 TCP 协议的端口监听和请求代理。
- 后续可能扩展到 UDP 支持,因此设计应考虑模块化和扩展性。
Ng配置
java
stream {
upstream socket_proxy1 {
hash $remote_addr consistent;
# 转发的目的地址和端口
server 20.100.105.172:6789;
}
upstream socket_proxy2 {
hash $remote_addr consistent;
# 转发的目的地址和端口
server 20.100.105.250:6789;
}
map $remote_addr $socket_proxy {
20.101.106.69 socket_proxy1; # 或者是 CIDR格式的IP段
20.101.106.68 socket_proxy2;
default socket_proxy2; # 默认转发的节点
}
server {
listen 4321;
proxy_connect_timeout 600s;
proxy_timeout 600s;
#动态选择后端节点
proxy_pass $socket_proxy;
}
log_format detailed '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time $upstream_addr '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
map $time_iso8601 $logdate {
default 'date-not-found';
'~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd;
}
access_log logs/stream-access-$logdate.log detailed;
}
- stream 块:用于处理基于 TCP 或 UDP 的流量。
- upstream:定义了不同的后端服务器组。
- map 指令:根据客户端的 IP地址,将请求映射到不同的后端组。
- server:定义一个 TCP 端口监听服务,并将连接动态转发给对应的后端
在完成配置后,使用以下命令验证 Nginx 配置是否正确:
java
nginx -t
重新加载 Nginx 服务
java
nginx -s reload
测试验证
- 使用客户端工具(如 telnet 或 nc)从指定 IP 进行连接。
- 从stream的日志中确认请求是否正确转发到对应的后端服务器。