NGINX反向代理:原理、配置与实践指南

NGINX反向代理:原理、配置与实践指南

在分布式系统和微服务架构盛行的今天,反向代理已成为现代Web架构中不可或缺的组件。NGINX作为一款高性能的HTTP和反向代理服务器,以其轻量级、高并发处理能力和丰富的功能特性,成为众多企业的首选解决方案。本文将深入探讨NGINX反向代理的工作原理、核心配置及实际应用场景。

什么是反向代理?

反向代理(Reverse Proxy)是位于服务器端的代理服务,它代表服务器接收客户端请求,然后将请求转发到内部服务器,并将响应返回给客户端。与正向代理(如VPN)代表客户端访问服务器不同,反向代理隐藏了真实的服务器架构,对外提供统一的访问入口。

反向代理的核心价值

  1. 负载均衡:将请求分发到多台服务器,提高系统整体处理能力
  2. 安全防护:隐藏后端服务器信息,防止直接暴露于公网
  3. 缓存加速:缓存静态内容,减少后端服务器压力
  4. SSL终止:集中处理SSL加密/解密,减轻后端服务器负担
  5. 统一入口:为多个服务提供单一访问点,简化客户端配置

NGINX反向代理工作原理

NGINX反向代理的核心工作流程如下:

  1. 接收请求:NGINX监听特定端口(如80/443)接收客户端HTTP/HTTPS请求
  2. 路由决策:根据配置的规则(如域名、路径)决定将请求转发到哪个后端服务
  3. 请求转发:修改请求头(如Host头),将请求转发到选定的后端服务器
  4. 响应接收:接收后端服务器的响应
  5. 响应返回:将响应发送回客户端,可能包含内容修改或缓存处理

核心配置详解

基本反向代理配置

server { listen 80; server_name example.com; 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_pass:指定后端服务器地址,可以是域名、IP或upstream组
  • proxy_set_header:设置转发给后端服务器的请求头

负载均衡配置

upstream backend_servers { server 192.168.1.100:8080 weight=3; server 192.168.1.101:8080; server 192.168.1.102:8080 backup; } server { listen 80; server_name example.com; location / { proxy_pass http://backend_servers; } }

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

  • 轮询(默认):请求按顺序分配到各服务器
  • 加权轮询:根据权重分配请求
  • IP哈希:相同客户端IP总是访问同一后端
  • 最少连接:优先分配给当前连接数最少的服务器

SSL终止配置

server { listen 443 ssl; server_name example.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; location / { proxy_pass http://backend_server; proxy_set_header X-Forwarded-Proto https; } }

WebSocket支持

server { listen 80; server_name example.com; location /ws { proxy_pass http://backend_server; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }

高级应用场景

1. 基于路径的路由

server { listen 80; server_name example.com; location /api/ { proxy_pass http://api_backend; } location /static/ { alias /var/www/static/; expires 30d; } location / { proxy_pass http://web_backend; } }

2. A/B测试与流量分割

upstream backend { server old_version weight=90; server new_version weight=10; }

3. 灰度发布实现

map $cookie_version $target_backend { default old_backend; "new" new_backend; } server { location / { proxy_pass http://$target_backend; } }

4. 安全防护配置

# 限制请求速率 limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { location / { limit_req zone=one burst=5; proxy_pass http://backend; } } # 防止DDoS攻击 server { listen 80 default_server; return 444; # 关闭连接而不响应 }

性能优化技巧

  1. 连接池优化

    proxy_http_version 1.1; proxy_set_header Connection "";
  2. 缓冲区设置

    proxy_buffers 16 8k; proxy_buffer_size 4k;
  3. 超时配置

    proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s;
  4. Gzip压缩

    gzip on; gzip_types text/css application/javascript image/svg+xml;

监控与日志

http { log_format proxy_log '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$upstream_addr $upstream_status $request_time'; access_log /var/log/nginx/access.log proxy_log; error_log /var/log/nginx/error.log warn; }

一个demo

upstream test.a.com {        server  192.168.0.100:8888; } server{        server_name test.a.com;        root /Users/peng/work/jim;        index index.html index.php;        location / {                proxy_pass http://192.168.0.100:8888;        }        location ^~ /gen/ {                proxy_pass http://192.168.0.100:8888;        }        location ~ .*\.(html|css|js|gif|jpg|png|jpeg|woff|woff2|ttf|eot|svg)$ {                root /Users/peng/work/jim;        }        #error_log /usr/logs/jimcloud.error.log;        #access_log  /usr/logs/jimcloud.access.log ; }