Nginx 代理 PostgreSQL 与 Redis 端口配置指南

⚠️ 核心要点:PostgreSQL 和 Redis 使用二进制 TCP 协议,必须通过 Nginx 的 stream 模块(4层代理)进行转发,不能使用 http 模块的 proxy_pass


一、检查 Nginx 是否支持 Stream 模块

bash

复制

nginx -V 2>&1 | grep -E 'with-stream|--with-stream'

# 应输出包含:
# --with-stream           # 启用stream模块
# --with-stream_ssl_module # 启用stream SSL支持

如果没有,需重新编译或安装完整版 Nginx:

bash

复制

# Ubuntu/Debian
sudo apt-get install nginx-full

# CentOS/RHEL
sudo yum install nginx-all-modules

二、Nginx 核心配置(stream 块)

nginx.conf顶层(与 http 块同级)添加 stream 配置:

nginx

复制

# /etc/nginx/nginx.conf

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;

# 关键:stream块必须放在顶层,与http块并列
stream {
    # 1. PostgreSQL 代理配置
    upstream postgres_backend {
        # 一致性哈希,确保同一客户端连接到同一后端
        hash $remote_addr consistent;
        
        # 后端PostgreSQL实例(可配置多个实现负载均衡)
        server 192.168.1.100:5432 weight=5 max_fails=3 fail_timeout=30s;
        # server 192.168.1.101:5432 weight=5 max_fails=3 fail_timeout=30s;
    }

    server {
        # Nginx监听端口(对外暴露)
        listen 5433 so_keepalive=on;  # so_keepalive保持会话,防止查询中断
        
        # 连接超时配置
        proxy_connect_timeout 10s;
        proxy_timeout 300s;  # 数据库长连接超时时间
        
        # 转发到后端
        proxy_pass postgres_backend;
    }

    # 2. Redis 代理配置
    upstream redis_backend {
        hash $remote_addr consistent;
        
        # 后端Redis实例
        server 192.168.1.200:6379 weight=5 max_fails=3 fail_timeout=30s;
    }

    server {
        listen 6380 so_keepalive=on;
        
        proxy_connect_timeout 10s;
        proxy_timeout 200s;  # Redis空闲连接超时
        
        proxy_pass redis_backend;
    }
    
    # 3. 可继续添加其他TCP服务
    # upstream mysql_backend { ... }
}

http {
    # 原有的HTTP配置保持不变
    include /etc/nginx/conf.d/*.conf;
}

三、防火墙配置

开放 Nginx 监听端口:

bash

复制

# PostgreSQL 代理端口(示例使用5433)
sudo firewall-cmd --zone=public --add-port=5433/tcp --permanent

# Redis 代理端口(示例使用6380)
sudo firewall-cmd --zone=public --add-port=6380/tcp --permanent

# 重新加载规则
sudo firewall-cmd --reload

如果是云服务器,还需在安全组中放行相应端口。


四、连接测试

1. 测试 PostgreSQL 代理

bash

复制

# 通过Nginx代理端口连接
psql -h your-nginx-ip -p 5433 -U postgres -d mydb

# 或
psql "host=your-nginx-ip port=5433 user=postgres dbname=mydb"

2. 测试 Redis 代理

bash

复制

# 通过Nginx代理端口连接
redis-cli -h your-nginx-ip -p 6380 -a yourpassword

# 测试命令
127.0.0.1:6380> ping
PONG

公网访问场景

  • {your-nginx-ip} 应为跳板机的公网IP(弹性IP)

  • 跳板机与数据库应在同一VPC内,通过内网IP访问后端


五、高级配置选项

1. SSL/TLS 加密

nginx

复制

stream {
    upstream postgres_ssl {
        server 192.168.1.100:5432;
    }
    
    server {
        listen 5433 ssl;
        ssl_certificate /etc/nginx/ssl/server.crt;
        ssl_certificate_key /etc/nginx/ssl/server.key;
        
        proxy_pass postgres_ssl;
    }
}

2. 访问日志

nginx

复制

stream {
    log_format proxy '$remote_addr [$time_local] '
                     '$protocol $status $bytes_sent $bytes_received '
                     '$session_time "$upstream_addr"';
    
    access_log /var/log/nginx/stream-access.log proxy;
    
    # ... upstream 配置
}

3. 连接数限制

nginx

复制

stream {
    # 每个IP最大连接数
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    
    server {
        listen 5433;
        proxy_pass postgres_backend;
        limit_conn addr 10;  # 每个IP最多10个连接
    }
}

六、常见误区与错误配置

❌ 错误示例(来自部分网络文章)

切勿使用 HTTP 代理配置

nginx

复制

# 错误!HTTP模块无法代理Redis/PostgreSQL协议
http {
    server {
        listen 80;
        location / {
            proxy_pass http://localhost:5432;  # × PostgreSQL不是HTTP协议
        }
    }
}

错误原因

  • Redis 和 PostgreSQL 使用二进制 TCP 协议,不是 HTTP

  • HTTP 模块的 proxy_pass 无法理解数据库协议握手

  • 会导致连接失败或协议错误

✅ 正确配置(必须 stream 模块)

nginx

复制

# 正确!使用stream块进行4层TCP代理
stream {
    server {
        listen 5433;
        proxy_pass localhost:5432;  # √ 直接TCP转发
    }
}

七、生产环境建议

  1. 连接保持:必须配置 so_keepalive=on,防止空闲连接被防火墙断开

  2. 超时设置proxy_timeout 应大于数据库空闲超时时间

  3. 健康检查:定期使用 psqlredis-cli 测试代理端口可用性

  4. 监控告警:监控 stream-access.log 中的连接错误和超时

  5. 安全加固

    • 限制访问IP:allow 10.0.0.0/8; deny all;

    • 使用跳板机方案,不直接暴露数据库端口到公网


八、配置重载

bash

复制

# 测试配置语法
sudo nginx -t

# 重载配置(不中断连接)
sudo nginx -s reload

# 查看stream连接状态
sudo netstat -anp | grep :5433

总结:Nginx 代理数据库的核心是 stream 模块的 TCP 转发,与 HTTP 反向代理完全不同。配置时务必注意 stream 块与 http 块同级,且使用 proxy_pass 直接指向后端 TCP 端口

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐