avatar👋
fighting27fighting27的博客 | 壹人小站

今人不见古时月,今月曾经照古人

总是畏惧海洋的人,是无法离开岸边的

Nginx 反向代理与负载均衡入门笔记

Nginx 反向代理与负载均衡入门笔记

能读懂常见的 Nginx 配置,并完成静态站点、后端反向代理和多实例负载均衡。

  • 反向代理:你访问的是代理服务器,代理服务器再帮你去找真正的服务器。
    例子:去餐厅吃饭,你不会直接进后厨点菜,而是告诉服务员。服务员(反向代理)再把你的需求传给后厨(服务器)。
  • 负载均衡:把请求平均分给多个服务器,每个服务器处理部分请求。
    例子:超市结账,有三个收银台。工作人员会让顾客分别去不同窗口排队,而不是所有人都挤到一个窗口。

1. Nginx 配置通常在哪里

不同系统的路径略有差异:

系统主配置站点配置
Ubuntu / Debian/etc/nginx/nginx.conf/etc/nginx/sites-available//etc/nginx/sites-enabled/
CentOS / Rocky / RHEL/etc/nginx/nginx.conf/etc/nginx/conf.d/*.conf

修改配置后的常用命令:

bash
sudo nginx -t                 # 检查配置语法
sudo systemctl reload nginx   # 平滑加载新配置
sudo systemctl status nginx   # 查看服务状态
sudo journalctl -u nginx -f   # 持续查看服务日志

每次修改配置后,都应先执行 nginx -t,确认成功后再 reload。

2. 配置文件基本结构

nginx
user nginx;
worker_processes auto;

events {
    worker_connections 1024;
}

http {
    include mime.types;

    server {
        listen 80;
        server_name example.com;

        location / {
            root /var/www/site;
            index index.html;
        }
    }
}
  • events:连接处理相关配置,初学阶段通常无需改动。
  • http:HTTP 服务的总配置容器。
  • server:一个网站、域名或监听端口的配置。
  • location:匹配特定请求路径后应如何处理。

3. location 匹配方式

nginx
location = /login { }       # 精确匹配,只匹配 /login
location /api/ { }          # 前缀匹配,匹配 /api/ 开头的路径
location ^~ /static/ { }    # 优先前缀匹配,命中后不再匹配正则
location ~ \.php$ { }       # 区分大小写的正则匹配
location ~* \.(jpg|png)$ { } # 不区分大小写的正则匹配

日常反向代理最常见的是 location /api/;静态资源常用 location /static/

4. 静态网站配置

nginx
server {
    listen 80;
    server_name blog.example.com;

    root /var/www/blog;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

try_files 的最后一个 /index.html 适合 Vue、React 等前端单页应用:当访问前端路由时,Nginx 会回退到入口页面。

5. 反向代理

反向代理是指用户请求先到 Nginx,再由 Nginx 转发给内部后端服务。后端服务可以只监听本机端口,不直接暴露到公网。

text
浏览器 -> Nginx:80/443 -> 后端应用:8080

假设 Spring Boot 服务监听 127.0.0.1:8080

nginx
server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://127.0.0.1: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;

        proxy_connect_timeout 5s;
        proxy_read_timeout 60s;
    }
}

几个常用请求头:

配置作用
Host $host把用户访问的域名传给后端
X-Real-IP $remote_addr将真实客户端 IP 传给后端
X-Forwarded-For保留经过代理链路的客户端 IP 列表
X-Forwarded-Proto $scheme告诉后端原始请求是 HTTP 还是 HTTPS

proxy_pass 末尾斜杠的区别

nginx
# 请求 /api/users 会转发为 http://127.0.0.1:8080/api/users
location /api/ {
    proxy_pass http://127.0.0.1:8080;
}

# 请求 /api/users 会转发为 http://127.0.0.1:8080/users
location /api/ {
    proxy_pass http://127.0.0.1:8080/;
}

这个差异很常见。是否保留 /api 前缀,取决于后端接口路径。

6. 前后端分离部署示例

nginx
server {
    listen 80;
    server_name www.example.com;

    root /var/www/frontend;
    index index.html;

    # 前端页面与路由
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 转发 API 请求到后端
    location /api/ {
        proxy_pass http://127.0.0.1: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;
    }
}

7. 负载均衡

当一个后端应用部署为多个实例时,使用 upstream 定义服务组,再将请求转发到该组。

nginx
upstream backend_servers {
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
    server 127.0.0.1:8083;
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://backend_servers;
        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;
    }
}

默认策略是轮询:请求依次分配给各个正常服务。

常见均衡策略

nginx
# 1. 轮询:默认策略
upstream backend_servers {
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
}

# 2. 权重:性能更好的机器承担更多请求
upstream backend_servers {
    server 10.0.0.11:8080 weight=3;
    server 10.0.0.12:8080 weight=1;
}

# 3. 最少连接:优先分配到当前连接最少的实例
upstream backend_servers {
    least_conn;
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
}

# 4. IP 哈希:同一客户端通常会落到同一实例
upstream backend_servers {
    ip_hash;
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
}

为后端实例增加失败处理:

nginx
upstream backend_servers {
    server 10.0.0.11:8080 max_fails=3 fail_timeout=30s;
    server 10.0.0.12:8080 max_fails=3 fail_timeout=30s;
}

含义:某个实例在 30 秒内失败 3 次后,会被暂时视为不可用。

8. HTTPS 的常见写法

nginx
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

9. 排错顺序

  1. sudo nginx -t:确认配置是否有语法错误。
  2. sudo systemctl status nginx:确认 Nginx 是否启动。
  3. curl -I http://127.0.0.1:后端端口:在服务器本机确认后端是否可访问。
  4. sudo ss -lntp:确认 Nginx 和后端程序是否在监听对应端口。
  5. sudo tail -f /var/log/nginx/error.log:查看 Nginx 错误日志。
  6. 检查云服务器安全组和系统防火墙是否放行 80、443 端口。

10. 最小速查

bash
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl restart nginx
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

理解 serverlocationproxy_passupstream 后,已经能够阅读并维护大多数小型项目的 Nginx 配置。

Docker 基础与实战入门笔记
Git 基础学习笔记