Nginx 反向代理

反向代理(Reverse Proxy)是一种服务器架构模式,它作为代理服务器接收来自客户端的连接请求,然后将这些请求转发到内部网络上的一个或多个后端服务器,并将从后端服务器得到的结果返回给客户端 。在此过程中,代理服务器对外表现为一个独立的服务器,有效隐藏了后端服务器的真实细节。

与正向代理代表客户端与服务器通信不同,​反向代理代表服务器与客户端通信。正向代理隐藏真实客户端,而反向代理隐藏真实服务器,客户端只与反向代理服务器交互,不知道后端服务器的存在。

Nginx作为一个高性能的HTTP和反向代理服务器,以其高性能、稳定性、丰富的功能集、简单的配置和低资源消耗而闻名。

1. Nginx反向代理工作原理

Nginx反向代理的工作流程可以分为以下几个关键步骤:

  1. ​客户端请求​:客户端通过HTTP或HTTPS协议向Nginx服务器发送请求。

  2. ​请求接收与转发​:Nginx接收到请求后,根据预先配置的反向代理规则,将请求转发到一个或多个指定的后端服务器。

  3. ​资源处理与响应​:后端服务器接收到来自Nginx的请求,处理该请求并生成相应的资源响应。

  4. ​响应返回客户端​:Nginx从后端服务器接收到资源响应后,将其转发回原始请求的客户端,完成整个请求-响应周期。

在这一过程中,Nginx支持对多种协议进行代理,包括HTTP、HTTPS、TCP、WebSocket、gRPC等。

2. 配置Nginx反向代理

2.1 基本配置

配置Nginx反向代理的核心是使用proxy_pass指令。以下是一个基本的反向代理配置示例:

server {
    listen 80;
    server_name example.com;
    
    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

配置说明

  • listen 80:指定Nginx监听的端口(此处为80)

  • server_name example.com:指定该配置响应的域名

  • location /:定义匹配的URL路径(此处匹配所有路径)

  • proxy_pass http://localhost:8080:核心指令,指定请求转发的目标地址

  • proxy_set_header:设置转发到后端服务器的请求头信息

2.2 关键配置参数详解

除了基本配置外,Nginx反向代理还提供了一系列重要参数用于优化和控制代理行为:

参数 说明 示例值
proxy_connect_timeout 与后端服务器建立连接的超时时间 60s
proxy_send_timeout 向后端服务器发送请求的超时时间 60s
proxy_read_timeout 从后端服务器读取响应的超时时间 60s
proxy_buffers 代理缓冲区的数量和大小 84k
client_body_buffer_size 客户端请求主体的缓冲区大小 8k

完整配置示例:

location / {
    proxy_pass http://backend-server;
    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
    proxy_buffers 8 4k;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

2.3 路径处理规则

在配置反向代理时,location块和proxy_pass指令的路径配置对最终转发路径有重要影响。以下是不同配置情况的路径处理规则:

location路径 proxy_pass路径 实际转发路径 说明
/test/ http://backend.com/ http://backend.com/index.html location有尾随斜杠,proxy_pass也有斜杠时,location匹配的路径会被替换
/test/ http://backend.com http://backend.com/test/index.html proxy_pass无尾随斜杠时,location匹配的路径会保留
/test http://backend.com/ http://backend.com//index.html 可能产生双斜杠,需要特别注意
/test http://backend.com http://backend.com/test/index.html 路径原样传递

3 反向代理高级功能

3.1 负载均衡

Nginx可以通过upstream模块实现负载均衡,将请求分发到多个后端服务器:

http {
    upstream backend {
        server backend1.example.com:8080 weight=3;
        server backend2.example.com:8080;
        server backend3.example.com:8080;
    }
    
    server {
        listen 80;
        server_name example.com;
        
        location / {
            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

Nginx支持多种负载均衡算法:

  • ​轮询(默认)​​:按顺序将请求分发到各后端服务器

  • ​加权轮询​:根据服务器权重分配请求

  • ​IP哈希​:根据客户端IP地址分配,保证同一客户端访问同一服务器

  • ​最少连接​:优先将请求分发给当前连接数最少的服务器

3.2 缓存功能

Nginx可以缓存后端服务器的响应,显著提升性能

http {
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g 
                     inactive=60m use_temp_path=off;
    
    server {
        listen 80;
        server_name example.com;
        
        location / {
            proxy_pass http://backend;
            proxy_cache my_cache;
            proxy_cache_valid 200 304 12h;
            proxy_cache_valid 301 302 1m;
            proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        }
    }
}

3.3 SSL终止

Nginx可以处理SSL/TLS加密,减轻后端服务器负担:

server {
    listen 443 ssl;
    server_name example.com;
    
    ssl_certificate /path/to/certificate.crt;
    ssl_certificate_key /path/to/private.key;
    
    location / {
        proxy_pass http://backend-server;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
}

4 实际应用场景

4.1 提高访问速度

代理服务器可以缓存静态资源,减少对后端服务器的直接请求,尤其对于热门站点可以显著提升请求速度。

4.2 安全性和访问控制

反向代理充当安全屏障,隐藏后端服务器的真实IP地址和架构细节。它可以实施访问控制、身份验证和授权策略,保护后端服务器免受恶意请求和攻击。

4.3 负载分发与高可用

通过将请求分发到多个服务器,提高系统吞吐量和可靠性。结合健康检查机制,可以自动剔除故障节点,保证服务连续性。

4.4 流量控制与DDoS防护

通过配置限流指令(如limit_req和limit_conn),Nginx可以实现流量控制功能,限制来自客户端的请求速率和并发连接数,有效防御DDoS攻击。

5 配置实践与最佳实践

5.1 完整配置示例

以下是一个结合了多种最佳实践的反向代理配置示例:

# 定义上游服务器组
upstream backend {
    server 192.168.1.100:8080 weight=3;
    server 192.168.1.101:8080;
    server 192.168.1.102:8080 backup;
}

# HTTP服务器配置
server {
    listen 80;
    server_name example.com;
    
    # 访问日志配置
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    
    # 安全头设置
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    
    # 反向代理配置
    location / {
        proxy_pass http://backend;
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        
        # 请求头设置
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # 缓冲优化
        proxy_buffers 8 16k;
        proxy_buffer_size 32k;
    }
    
    # 健康检查端点(限制访问)
    location /nginx_status {
        stub_status;
        allow 127.0.0.1;
        deny all;
    }
}

5.2 配置检查与故障排查

  1. ​语法检查​:修改配置后,务必执行语法检查
sudo nginx -t
  1. 重载配置​:检查无误后重载Nginx
sudo systemctl reload nginx
  1. 日志监控​:遇到问题时查看错误日志
tail -f /var/log/nginx/error.log

5.3 安全最佳实践

  • ​限制直接IP访问​:配置默认server块拒绝非域名访问

  • ​设置适当的超时时间​:防止资源被长期占用

  • ​使用最小权限原则​:Nginx进程应以非root用户运行

  • ​定期更新​:保持Nginx版本最新,修复安全漏洞

6 完整示例

一个完整的示例:

user nginx;
worker_processes 1;  # 根据需要调整

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;  # 允许每个 worker 进程的最大连接数
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    # 启用 gzip 压缩
    gzip  on;
    
    #禁用版本信息
    server_tokens off;

    # 访问日志配置
    access_log  /var/log/nginx/access.log;

    # 设置 SSL
    server {
        listen 443 ssl;
        server_name xxx.cn www.xxx.cn;

        ssl_certificate /etc/nginx/certs/fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;

        location / {
            proxy_pass http://172.17.0.1:8001;  # halo 服务的地址和端口
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }

    # 设置 SSL
    server {
        listen 443 ssl;
        server_name store.xxx.cn;

        ssl_certificate /etc/nginx/certs/store.xxx.cn_chain.crt;
        ssl_certificate_key /etc/nginx/certs/store.xxx.cn_key.key;

        location / {
            proxy_pass http://172.17.0.1:8002;  # halo 服务的地址和端口
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }

    # HTTP 到 HTTPS 重定向
    server {
        listen 80;
        server_name xxx.cn www.xxx.cn store.xxx.cn;

        return 301 https://$host$request_uri;
    }

    server {
        listen 80 default_server;
        listen 443 ssl default_server;

        server_name _;

        ssl_certificate /etc/nginx/certs/fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;
        
        return 403;
    }
    
}

7 总结

Nginx反向代理是一个功能强大且灵活的工具,通过合理的配置可以实现负载均衡、缓存加速、安全防护等多种功能。掌握其基本原理和配置技巧,对于构建高性能、高可用的Web服务架构至关重要。在实际应用中,应根据具体需求选择合适的配置策略,并遵循安全最佳实践,以确保系统的稳定性和安全性。

通过本文的介绍,您应该对Nginx反向代理有了全面的了解,能够根据实际需求配置和优化自己的反向代理服务器。

相关阅读:如果你的后端服务部署在内网,需要先从外网访问,可以搭配 FRP 内网穿透工具 将内网服务暴露到公网,再通过 Nginx 反向代理进行流量管理和 SSL 加密。

分享文章