欢迎光临
我们一直在努力

nginx如何通过stream配置4层代理转发

在现代AI基础设施中,高性能的模型服务通常不只依赖标准的HTTP协议(L7)。例如,gRPC服务、Redis缓存层、或自定义的高速二进制协议通常需要进行四层(L4,TCP/UDP)的负载均衡和代理。Nginx凭借其强大的stream模块,可以轻松胜任这一任务,成为L4流量的核心路由器。

1. Stream模块概述与必要性

Nginx默认主要处理HTTP流量。但为了处理纯TCP或UDP流量,我们需要启用stream模块。如果你的Nginx是通过源码编译安装,需要确保在配置时加入了–with-stream参数。对于大多数使用包管理器安装的现代Nginx版本,stream模块通常已内置。

四层代理的优势在于:
1. 协议无关性: 代理任何基于TCP或UDP的流量,无需解析应用层协议(如HTTP头部)。
2. 高性能: 处理速度更快,延迟更低,适用于高吞吐量的模型推理服务。
3. 服务分离: 可以在统一的入口端口上对不同类型的后端服务进行分流。

2. Nginx Stream配置实操

与L7配置不同,L4配置需要在主配置文件(通常是/etc/nginx/nginx.conf)的根级别定义一个独立的stream上下文,它与http上下文是并列关系。

步骤一:配置Upstream后端服务

首先,定义我们的AI推理服务集群。假设我们有两个推理服务实例运行在8001和8002端口上。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# /etc/nginx/nginx.conf 核心配置

worker_processes auto;

# 定义 stream 上下文,与 http 上下文并列
stream {

    # 1. 定义后端服务器集群 (Upstream)
    upstream inference_tcp_backends {
        # 负载均衡算法:默认为 round-robin
        server 127.0.0.1:8001 weight=3; # 权重更高,分发更多流量
        server 127.0.0.1:8002;
        # 可以在此处添加健康检查:
        # server 127.0.0.1:8003 max_fails=3 fail_timeout=30s;
    }

    # 2. 定义前端监听服务 (Server)
    server {
        listen 9000;             # 监听 9000 端口,接收 TCP 流量
        proxy_pass inference_tcp_backends; # 转发到后端集群

        # L4 相关参数配置
        proxy_timeout 30s;       # 客户端与后端连接的超时时间
        proxy_connect_timeout 5s; # Nginx连接后端服务器的超时时间
    }

    # 示例:如果是 UDP 代理 (例如 DNS 或某些数据采集)
    # server {
    #     listen 53 udp;
    #     proxy_pass dns_servers;
    # }

}

http {
    # ... L7 HTTP 配置
}

步骤二:启动测试环境

为了验证配置,我们创建一个简单的Python脚本,模拟两个监听不同端口的TCP推理服务器。

首先,确保安装了python环境,并保存以下代码为 tcp_servers.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import socket
import threading
import time

def run_server(port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('127.0.0.1', port))
    s.listen(5)
    print(f"[SERVER {port}] TCP server started at 127.0.0.1:{port}")

    while True:
        try:
            conn, addr = s.accept()
            # time.sleep(0.1) # 模拟处理延迟
            data = conn.recv(1024).decode().strip()
            response = f"[Server {port}] Received: {data}. Time: {time.time()}"
            print(f"-> Handling request on {port}: {data}")
            conn.sendall(response.encode())
            conn.close()
        except Exception as e:
            print(f"Error on server {port}: {e}")

# 启动两个后端服务
tcp_ports = [8001, 8002]
for port in tcp_ports:
    threading.Thread(target=run_server, args=(port,)).start()

运行Python服务器:


1
2
3
python3 tcp_servers.py
# [SERVER 8001] TCP server started at 127.0.0.1:8001
# [SERVER 8002] TCP server started at 127.0.0.1:8002

步骤三:测试L4代理转发

重启Nginx并使用netcat (nc) 或 telnet 测试Nginx监听的9000端口。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 重启Nginx加载新配置
sudo nginx -s reload

# 第一次请求,应到达8001 (因为8001权重更高)
echo "Inference Request A" | nc 127.0.0.1 9000

# 第二次请求,应到达8001
echo "Inference Request B" | nc 127.0.0.1 9000

# 第三次请求,应到达8001
echo "Inference Request C" | nc 127.0.0.1 9000

# 第四次请求,应到达8002 (权重分配生效)
echo "Inference Request D" | nc 127.0.0.1 9000

根据Python服务器的输出,你可以看到流量根据Nginx配置的Round-Robin策略和权重被正确地转发到了不同的后端端口。

3. 高级Stream配置技巧

A. 基于源IP的哈希负载均衡 (会话保持)

对于需要保持客户端连接状态的推理服务(例如,需要特定Session ID),可以使用hash负载均衡算法:


1
2
3
4
5
upstream sticky_backends {
    hash $remote_addr consistent; # consistent确保在增减服务器时影响最小
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
}

B. L4 SSL/TLS Termination

如果流量是加密的,Nginx的stream模块也可以进行TLS终止(即解密客户端连接,再以明文或再次加密的方式转发给后端)。


1
2
3
4
5
6
server {
    listen 9443 ssl;
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    proxy_pass inference_tcp_backends;
}

通过配置stream模块,Nginx不仅是L7的代理神器,也能轻松成为AI基础设施中不可或缺的L4高性能流量分配器。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » nginx如何通过stream配置4层代理转发
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址