nginx语法

nginx语法解析

Nginx 配置文件超详细解读

为了方便日后查阅,我就以我项目中的 nginx.conf 为例,进行讲解:

conf 复制代码
user  nginx;
worker_processes  auto;

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

events {
    worker_connections  1024;
}

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

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}

一、全局块(第1-5行)

user nginx;

复制代码
作用:指定 Nginx 以哪个用户身份运行

比喻:公司规定,这个员工用什么工牌上班

详解:
- nginx 是一个 Linux 用户名
- 为什么要指定用户?出于安全考虑
- 不用 root 用户,是因为 root 权限太大,万一被黑客攻击,损失更大
- 用一个权限有限的用户更安全

worker_processes auto;

复制代码
作用:开启几个工作进程

比喻:餐厅雇佣几个服务员

详解:
- auto = 自动根据 CPU 核心数决定
- 如果你的服务器是 4 核 CPU,就会开 4 个进程
- 每个进程独立工作,互不干扰
- 进程越多,能同时处理的请求越多

可选值:
- auto(推荐)
- 具体数字,如 4、8

error_log /var/log/nginx/error.log notice;

复制代码
作用:错误日志保存在哪里,记录什么级别的错误

比喻:投诉记录本放在哪里,记录什么程度的投诉

详解:
- /var/log/nginx/error.log 是文件路径
- notice 是日志级别

日志级别(从低到高):
┌─────────┬────────────────────────────┐
│  级别   │          记录内容          │
├─────────┼────────────────────────────┤
│ debug   │ 调试信息(最详细,最多)   │
│ info    │ 一般信息                   │
│ notice  │ 值得注意的信息             │
│ warn    │ 警告                       │
│ error   │ 错误                       │
│ crit    │ 严重错误(最少)           │
└─────────┴────────────────────────────┘

级别越高,记录的内容越少,文件越小
生产环境通常用 warn 或 error

pid /var/run/nginx.pid;

复制代码
作用:记录 Nginx 主进程的进程号(PID)

比喻:员工工号记录在哪个文件里

详解:
- 这个文件里只有一个数字,比如 "12345"
- 其他程序可以通过读这个文件,知道 Nginx 的进程号
- 用于停止、重启 Nginx 时找到正确的进程

二、events 块(第7-9行)

nginx 复制代码
events {
    worker_connections  1024;
}

worker_connections 1024;

复制代码
作用:每个工作进程最多能同时处理多少个连接

比喻:每个服务员最多同时服务多少桌客人

详解:
- 1024 表示每个进程最多 1024 个连接
- 总连接数 = worker_processes × worker_connections
- 如果 4 个进程,每个 1024,总共最多 4096 个同时连接

实际计算:
┌──────────────────────────────────────────┐
│  4 个进程 × 1024 连接 = 4096 最大连接    │
│                                          │
│  一般网站足够了                          │
│  高并发网站可以调到 65535               │
└──────────────────────────────────────────┘

三、http 块(第11-43行)

http 块是最重要的部分,配置 HTTP 服务的所有内容。

include /etc/nginx/mime.types;

复制代码
作用:引入文件类型映射表

比喻:引入一本"文件类型字典"

详解:
- mime.types 文件里定义了文件扩展名和内容类型的对应关系
- 比如:
  .html → text/html
  .css  → text/css
  .js   → application/javascript
  .png  → image/png
  .jpg  → image/jpeg

为什么需要?
- 浏览器需要知道文件类型才能正确处理
- 比如 .css 文件要当成样式表解析
- 如果类型错了,浏览器可能无法正常显示

default_type application/octet-stream;

复制代码
作用:如果文件类型未知,默认当什么类型处理

比喻:如果字典里查不到,就当成"未知物品"处理

详解:
- application/octet-stream 表示"二进制流"
- 意思是:不知道是啥,就当成普通文件下载
- 浏览器遇到这种类型,会弹出下载框

log_format main '...'

复制代码
作用:定义访问日志的格式

比喻:设计来客登记表的格式

详解:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';

这里定义了一个叫 "main" 的日志格式:

┌────────────────────────┬─────────────────────────────────┐
│        变量            │            含义                 │
├────────────────────────┼─────────────────────────────────┤
│ $remote_addr           │ 访客的 IP 地址                  │
│ $remote_user           │ 访客用户名(通常是 -)          │
│ $time_local            │ 访问时间                        │
│ $request               │ 请求内容(如 GET /index.html)  │
│ $status                │ HTTP 状态码(200、404 等)      │
│ $body_bytes_sent       │ 发送的字节数                    │
│ $http_referer          │ 从哪个页面跳转来的              │
│ $http_user_agent       │ 浏览器信息                      │
│ $http_x_forwarded_for  │ 代理链中的真实 IP               │
└────────────────────────┴─────────────────────────────────┘

实际日志长这样:
192.168.1.100 - - [04/Feb/2026:10:30:00 +0800] "GET /index.html HTTP/1.1" 200 1234 "-" "Mozilla/5.0..."

access_log /var/log/nginx/access.log main;

复制代码
作用:访问日志保存在哪里,用什么格式

比喻:来客登记表放在哪里,用哪种表格

详解:
- /var/log/nginx/access.log 是文件路径
- main 是上面定义的日志格式名称

每个人访问你的网站,都会在这个文件里留下一条记录

sendfile on;

复制代码
作用:开启高效文件传输模式

比喻:开启"快速传菜通道"

详解:
┌─────────────────────────────────────────────────────────┐
│  sendfile off(关闭):                                 │
│  磁盘 → 内核缓冲区 → 用户空间 → 内核缓冲区 → 网络       │
│  (数据要复制好几次,慢)                               │
├─────────────────────────────────────────────────────────┤
│  sendfile on(开启):                                  │
│  磁盘 → 内核缓冲区 → 网络                               │
│  (数据只复制一次,快)                                 │
└─────────────────────────────────────────────────────────┘

结论:永远开启,没有理由关闭

#tcp_nopush on;

复制代码
作用:优化网络传输(被注释掉了,没启用)

详解:
- # 开头表示注释,这行不生效
- tcp_nopush 开启后,会把小数据包攒在一起发送
- 减少网络包数量,提高效率
- 通常和 sendfile 一起使用效果更好

keepalive_timeout 65;

复制代码
作用:保持连接的超时时间(秒)

比喻:客人点完餐后,服务员等他 65 秒再去服务下一桌

详解:
┌─────────────────────────────────────────────────────────┐
│  没有 keepalive:                                       │
│  请求1 → 建立连接 → 传输 → 断开连接                     │
│  请求2 → 建立连接 → 传输 → 断开连接(每次都要重新连接) │
├─────────────────────────────────────────────────────────┤
│  有 keepalive:                                         │
│  请求1 → 建立连接 → 传输                                │
│  请求2 → 复用连接 → 传输                                │
│  请求3 → 复用连接 → 传输                                │
│  ...65秒没有新请求... → 断开连接                        │
└─────────────────────────────────────────────────────────┘

好处:减少建立连接的开销,提高性能

#gzip on;

复制代码
作用:开启压缩(被注释掉了,没启用)

详解:
- 开启后,会把文件压缩后再传输
- 比如 100KB 的 JS 文件,压缩后可能只有 30KB
- 传输更快,节省带宽

为什么注释掉?
- 可能是为了简单起见
- 生产环境建议开启

四、server 块(虚拟主机)

nginx 复制代码
server {
    listen       80;
    server_name  localhost;
    ...
}

server { ... }

复制代码
作用:定义一个虚拟主机(网站)

比喻:定义餐厅里的一个"独立包间"

详解:
- 一个 Nginx 可以同时运行多个网站
- 每个 server 块就是一个网站
- 通过不同的端口或域名区分

例如:
server {
    server_name www.site1.com;   # 网站1
}
server {
    server_name www.site2.com;   # 网站2
}
server {
    listen 8080;                  # 网站3(不同端口)
}

listen 80;

复制代码
作用:监听哪个端口

比喻:餐厅开在哪条街的几号门

详解:
- 80 是 HTTP 的默认端口
- 443 是 HTTPS 的默认端口
- 浏览器访问 http://example.com 时,默认用 80 端口
- 所以 http://example.com 等于 http://example.com:80

其他写法:
listen 80;                    # 监听所有 IP 的 80 端口
listen 127.0.0.1:80;          # 只监听本机
listen 443 ssl;               # 监听 443 并启用 HTTPS
listen 80 default_server;     # 设为默认网站

server_name localhost;

复制代码
作用:这个网站响应哪个域名

比喻:餐厅的名字叫什么

详解:
- localhost 表示本机
- 可以配置实际域名,如 www.example.com
- 可以配置多个,用空格分隔

例如:
server_name www.example.com example.com;  # 两个域名指向同一网站
server_name *.example.com;                # 通配符,匹配所有子域名
server_name ~^www\d+\.example\.com$;      # 正则表达式

访问流程:
用户输入 www.example.com
    ↓
DNS 解析到服务器 IP
    ↓
请求到达 Nginx
    ↓
Nginx 看 Host 头,找到匹配的 server_name
    ↓
由对应的 server 块处理

五、location 块(路由规则)- 最重要!

nginx 复制代码
location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
}

location / { ... }

复制代码
作用:匹配 URL 路径,决定如何处理请求

比喻:根据客人要去的楼层,决定走哪部电梯

详解:
location 后面的 / 表示匹配所有路径

不同的匹配规则:
┌──────────────┬─────────────────────────────────────────┐
│   写法       │              匹配规则                   │
├──────────────┼─────────────────────────────────────────┤
│ location /   │ 匹配所有路径(兜底)                    │
│ location /api│ 匹配以 /api 开头的路径                  │
│ location = / │ 精确匹配,只匹配 /                      │
│ location ^~ /static │ 前缀匹配,优先级高              │
│ location ~ \.php$   │ 正则匹配(区分大小写)          │
│ location ~* \.(jpg|png)$ │ 正则匹配(不区分大小写)  │
└──────────────┴─────────────────────────────────────────┘

root /usr/share/nginx/html;

复制代码
作用:网站文件存放的根目录

比喻:食材仓库在哪里

详解:
- 当用户访问 http://localhost/index.html
- Nginx 会去 /usr/share/nginx/html/index.html 找文件
- 当用户访问 http://localhost/css/style.css
- Nginx 会去 /usr/share/nginx/html/css/style.css 找文件

计算公式:
实际文件路径 = root + 请求路径

例如:
root = /var/www/html
请求 = /images/logo.png
实际 = /var/www/html/images/logo.png

index index.html index.htm;

复制代码
作用:默认首页文件名

比喻:客人说"我要进门",默认带他去大厅

详解:
- 当用户访问目录(如 http://localhost/)
- Nginx 会按顺序查找:
  1. 先找 index.html
  2. 找不到再找 index.htm
  3. 都找不到就报错

可以设置多个,按顺序查找:
index index.html index.htm default.html;

try_files uri uri/ /index.html;(最关键!)

复制代码
作用:按顺序尝试查找文件,都找不到就用最后一个

比喻:
1. 先看客人要的菜有没有
2. 没有的话看看是不是套餐
3. 都不是就给他推荐招牌菜

详解:
$uri      = 用户请求的路径(如 /about)
$uri/     = 把路径当目录查找(如 /about/index.html)
/index.html = 最终兜底方案

流程图:
用户访问 /about
    ↓
1、找 /usr/share/nginx/html/about 文件
    ↓ 找不到
2、找 /usr/share/nginx/html/about/index.html 文件
    ↓ 找不到
3、返回 /usr/share/nginx/html/index.html
    ↓
Vue Router 接管,显示 /about 页面

为什么 Vue 项目需要这个?
┌─────────────────────────────────────────────────────────┐
│  Vue 是单页应用(SPA),只有一个 index.html             │
│  /login、/about、/user 这些"页面"其实都不存在           │
│  都是由 Vue Router 在前端渲染出来的                     │
│                                                         │
│  没有 try_files:                                       │
│    访问 /login → 404 Not Found(因为没有 login 文件)   │
│                                                         │
│  有 try_files:                                         │
│    访问 /login → 找不到 → 返回 index.html → Vue 渲染    │
└─────────────────────────────────────────────────────────┘

六、错误页面配置

nginx 复制代码
error_page   500 502 503 504  /50x.html;
location = /50x.html {
    root   /usr/share/nginx/html;
}

error_page 500 502 503 504 /50x.html;

复制代码
作用:当发生这些错误时,显示指定页面

比喻:出了问题时,给客人看道歉信

详解:
500 = Internal Server Error(服务器内部错误)
502 = Bad Gateway(网关错误,通常是后端挂了)
503 = Service Unavailable(服务不可用)
504 = Gateway Timeout(网关超时)

当出现这些错误时,不显示默认的丑陋错误页面
而是显示你自定义的 /50x.html 页面

location = /50x.html { ... }

复制代码
作用:精确匹配 /50x.html 这个路径

详解:
- = 表示精确匹配,必须完全相等
- 只有访问 /50x.html 才会匹配
- /50x.html?a=1 不匹配
- /50x.html/ 不匹配

这里指定了错误页面文件的位置

七、配置块层级总结

复制代码
nginx.conf 结构图:

┌─────────────────────────────────────────────────────────┐
│  nginx.conf                                             │
│  ┌───────────────────────────────────────────────────┐  │
│  │  全局块                                           │  │
│  │  - user nginx                                     │  │
│  │  - worker_processes auto                          │  │
│  │  - error_log ...                                  │  │
│  │  - pid ...                                        │  │
│  └───────────────────────────────────────────────────┘  │
│                                                         │
│  ┌───────────────────────────────────────────────────┐  │
│  │  events 块                                        │  │
│  │  - worker_connections 1024                        │  │
│  └───────────────────────────────────────────────────┘  │
│                                                         │
│  ┌───────────────────────────────────────────────────┐  │
│  │  http 块                                          │  │
│  │  ┌─────────────────────────────────────────────┐  │  │
│  │  │  http 全局配置                              │  │  │
│  │  │  - include mime.types                       │  │  │
│  │  │  - sendfile on                              │  │  │
│  │  │  - keepalive_timeout 65                     │  │  │
│  │  └─────────────────────────────────────────────┘  │  │
│  │                                                   │  │
│  │  ┌─────────────────────────────────────────────┐  │  │
│  │  │  server 块(网站1)                         │  │  │
│  │  │  - listen 80                                │  │  │
│  │  │  - server_name localhost                    │  │  │
│  │  │  ┌───────────────────────────────────────┐  │  │  │
│  │  │  │  location / { ... }                   │  │  │  │
│  │  │  └───────────────────────────────────────┘  │  │  │
│  │  │  ┌───────────────────────────────────────┐  │  │  │
│  │  │  │  location /api { ... }                │  │  │  │
│  │  │  └───────────────────────────────────────┘  │  │  │
│  │  └─────────────────────────────────────────────┘  │  │
│  │                                                   │  │
│  │  ┌─────────────────────────────────────────────┐  │  │
│  │  │  server 块(网站2)                         │  │  │
│  │  │  ...                                        │  │  │
│  │  └─────────────────────────────────────────────┘  │  │
│  └───────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘

八、项目的配置

行号 配置 作用 是否必须
1 user nginx 运行用户 推荐
2 worker_processes auto 工作进程数 必须
4 error_log ... 错误日志 推荐
5 pid ... 进程号文件 必须
8 worker_connections 1024 最大连接数 必须
12 include mime.types 文件类型 必须
13 default_type ... 默认类型 推荐
15-17 log_format ... 日志格式 可选
19 access_log ... 访问日志 推荐
21 sendfile on 高效传输 推荐
24 keepalive_timeout 65 保持连接 推荐
29 listen 80 监听端口 必须
30 server_name localhost 域名 必须
33 root ... 文件目录 必须
34 index ... 默认首页 必须
35 try_files ... SPA 关键 Vue 必须
38-40 error_page ... 错误页面 可选

现在你应该对配置文件的每一部分都有了清晰的理解!有任何具体的配置项还不明白的,随时问我。

我是 Claude Opus 4.5 模型。

没关系!这些概念确实比较抽象,让我用最通俗的大白话,一个一个给你讲清楚。


拓展 - Web 核心概念详解


概念一:静态托管

什么是"静态"?

复制代码
┌─────────────────────────────────────────────────────────┐
│                                                         │
│  【静态文件】= 写死的、不会变的文件                      │
│                                                         │
│  比如:                                                 │
│  - HTML 文件(网页骨架)                                │
│  - CSS 文件(网页样式)                                 │
│  - JS 文件(网页交互)                                  │
│  - 图片(.png, .jpg)                                   │
│  - 字体文件                                             │
│                                                         │
│  特点:你写什么,用户看到的就是什么,不会变              │
│                                                         │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│                                                         │
│  【动态内容】= 根据情况变化的内容                        │
│                                                         │
│  比如:                                                 │
│  - 用户登录后显示的用户名                               │
│  - 购物车里的商品数量                                   │
│  - 数据库查询出来的文章列表                             │
│                                                         │
│  特点:需要后端程序实时计算/查询                        │
│                                                         │
└─────────────────────────────────────────────────────────┘

什么是"托管"?

复制代码
托管 = 把文件放到服务器上,让别人能访问

生活比喻:
┌─────────────────────────────────────────────────────────┐
│                                                         │
│  你写了一本书(你的网站代码)                            │
│      ↓                                                  │
│  放到图书馆(服务器)                                   │
│      ↓                                                  │
│  别人可以来借阅(访问你的网站)                         │
│                                                         │
│  "静态托管" = 图书馆帮你保管书,别人来了直接给他看      │
│                                                         │
└─────────────────────────────────────────────────────────┘

静态托管的工作流程

复制代码
你的电脑                    服务器(Nginx)               用户浏览器
   │                            │                            │
   │  npm run build             │                            │
   │  生成 dist 文件夹          │                            │
   │         │                  │                            │
   │         └──────上传────────→│                            │
   │                            │  保存在                    │
   │                            │  /usr/share/nginx/html     │
   │                            │                            │
   │                            │←───── 请求 index.html ─────│
   │                            │                            │
   │                            │────── 返回文件内容 ────────→│
   │                            │                            │
   │                            │←───── 请求 style.css ──────│
   │                            │                            │
   │                            │────── 返回文件内容 ────────→│

一句话总结:静态托管就是把你写好的网页文件放到服务器上,让别人能通过网址访问。


概念二:单页应用(SPA)

传统网站 vs 单页应用

复制代码
【传统网站】(多页应用)

用户点击"关于我们"
    ↓
浏览器向服务器请求 about.html
    ↓
服务器返回 about.html(整个页面)
    ↓
浏览器完全刷新,显示新页面
    ↓
白屏一下,重新加载所有内容

文件结构:
├── index.html      ← 首页
├── about.html      ← 关于页面
├── contact.html    ← 联系页面
├── products.html   ← 产品页面
└── ...             ← 每个页面一个文件

【单页应用】(SPA = Single Page Application)

用户点击"关于我们"
    ↓
浏览器不刷新!
    ↓
JavaScript 把页面内容换掉
    ↓
地址栏从 / 变成 /about
    ↓
看起来像换了页面,其实还是同一个页面

文件结构:
├── index.html      ← 只有这一个 HTML!
├── app.js          ← 所有页面逻辑都在这里
└── style.css

生活比喻

复制代码
【传统网站】像翻书:
┌─────────────────────────────────────────────────────────┐
│  想看第 5 章?                                          │
│      ↓                                                  │
│  翻到第 5 章(请求新页面)                              │
│      ↓                                                  │
│  看到全新的一页(页面完全刷新)                         │
└─────────────────────────────────────────────────────────┘

【单页应用】像看魔术表演:
┌─────────────────────────────────────────────────────────┐
│  想看第 5 章?                                          │
│      ↓                                                  │
│  魔术师挥挥手(JavaScript 执行)                        │
│      ↓                                                  │
│  书上的字变了,但书还是那本书(页面不刷新)             │
└─────────────────────────────────────────────────────────┘

为什么你的 Vue 项目是单页应用?

复制代码
你用 npm run build 打包后,dist 文件夹里只有:

dist/
├── index.html          ← 唯一的 HTML 文件!
├── assets/
│   ├── index-xxx.js    ← 所有 Vue 组件编译后的代码
│   └── index-xxx.css   ← 所有样式
└── ...

不管用户访问:
- http://你的网站/           → 显示首页(index.html)
- http://你的网站/login      → 还是 index.html,Vue Router 显示登录页
- http://你的网站/about      → 还是 index.html,Vue Router 显示关于页
- http://你的网站/user/123   → 还是 index.html,Vue Router 显示用户页

所有"页面"都是由 JavaScript 动态渲染出来的!

为什么需要 try_files 配置?

复制代码
问题:

用户直接访问 http://你的网站/login
    ↓
Nginx 收到请求:"/login"
    ↓
Nginx 去找 /usr/share/nginx/html/login 文件
    ↓
找不到!(因为根本没有这个文件)
    ↓
返回 404 错误
    ↓
用户看到"页面不存在" 😢


解决方案(try_files):

用户直接访问 http://你的网站/login
    ↓
Nginx 收到请求:"/login"
    ↓
try_files $uri $uri/ /index.html
    ↓
① 先找 /login 文件 → 没有
② 再找 /login/ 目录 → 没有
③ 返回 /index.html ← 兜底!
    ↓
浏览器收到 index.html
    ↓
Vue 和 Vue Router 加载
    ↓
Vue Router 看到地址是 /login
    ↓
渲染登录页面组件 😊

一句话总结:单页应用只有一个 HTML,所有"页面"都是 JS 渲染的,所以服务器要配置"找不到就返回 index.html"。


概念三:反向代理

先理解"代理"

复制代码
【正向代理】你的代理人

场景:你想买国外的东西,但你出不去
    ↓
找个代购(代理)
    ↓
代购帮你去国外买
    ↓
代购把东西给你

技术场景:科学上网
你 → VPN(代理)→ 谷歌
         ↑
    代理帮你访问你访问不了的网站

【反向代理】服务器的代理人

场景:客人来餐厅吃饭
    ↓
前台接待(Nginx)接待客人
    ↓
前台把点的菜告诉后厨(后端服务器)
    ↓
后厨做好菜,给前台
    ↓
前台把菜端给客人

客人不知道后厨在哪、有几个厨师
客人只跟前台打交道

图解

复制代码
【没有反向代理】

用户浏览器 ──────────────────────→ 后端服务器(:3000)
                                         │
                                   暴露在外面,不安全


【有反向代理】

                              ┌──→ 后端服务器1(:3000)
                              │
用户浏览器 ───→ Nginx(:80)──┼──→ 后端服务器2(:3001)
                              │
                              └──→ 后端服务器3(:3002)
        ↑                 ↑
    用户只能看到 Nginx    后端服务器藏在后面,更安全

为什么需要反向代理?

复制代码
好处1:隐藏后端
┌─────────────────────────────────────────────────────────┐
│  用户只知道 www.example.com                             │
│  不知道后端服务器在哪个 IP、什么端口                    │
│  更安全                                                 │
└─────────────────────────────────────────────────────────┘

好处2:统一入口
┌─────────────────────────────────────────────────────────┐
│  前端:www.example.com                                  │
│  API:www.example.com/api/                              │
│  图片:www.example.com/images/                          │
│                                                         │
│  看起来是一个网站,实际上背后可能是多个服务器           │
└─────────────────────────────────────────────────────────┘

好处3:SSL 终端
┌─────────────────────────────────────────────────────────┐
│  用户 ←──HTTPS──→ Nginx ←──HTTP──→ 后端                 │
│                                                         │
│  只需要在 Nginx 配置 HTTPS                              │
│  后端不用管证书的事                                     │
└─────────────────────────────────────────────────────────┘

配置示例

nginx 复制代码
server {
    listen 80;
    server_name www.example.com;

    # 静态文件
    location / {
        root /var/www/html;
        index index.html;
    }

    # API 请求转发给后端
    location /api/ {
        proxy_pass http://127.0.0.1:3000/;
        #           ↑
        # 把 /api/xxx 请求转发给本机 3000 端口的服务
    }
}
复制代码
用户请求:http://www.example.com/api/users
    ↓
Nginx 匹配到 location /api/
    ↓
转发给 http://127.0.0.1:3000/users
    ↓
后端返回数据给 Nginx
    ↓
Nginx 返回给用户

一句话总结:反向代理就是 Nginx 当"中间人",把用户的请求转发给后端服务器,用户不直接接触后端。


概念四:负载均衡

什么是负载均衡?

复制代码
场景:双十一,淘宝有几亿人同时访问

一台服务器能扛住吗?
    ↓
扛不住!会崩!
    ↓
怎么办?
    ↓
用很多台服务器一起扛!
    ↓
怎么分配请求?
    ↓
负载均衡!

生活比喻

复制代码
【没有负载均衡】

银行只有 1 个窗口
    ↓
100 个客人排队
    ↓
队伍排到门外
    ↓
客人等得不耐烦,走了

【有负载均衡】

银行开 5 个窗口
    ↓
大堂经理(Nginx)分配客人
    ↓
"1号去1窗口,2号去2窗口..."
    ↓
每个窗口只排 20 人
    ↓
很快就办完了

图解

复制代码
                              ┌──→ 服务器1(处理 33%)
                              │
用户请求 ───→ Nginx(负载均衡)──┼──→ 服务器2(处理 33%)
                              │
                              └──→ 服务器3(处理 33%)

分配策略

复制代码
【轮询】默认方式
请求1 → 服务器1
请求2 → 服务器2
请求3 → 服务器3
请求4 → 服务器1(又回来了)
...
像发牌一样,一人一张

【权重】按能力分配
服务器1(性能强)weight=3,处理 60%
服务器2(性能弱)weight=2,处理 40%
能力强的多干点活

【IP 哈希】同一用户固定服务器
用户A(IP: 1.1.1.1)→ 永远去服务器1
用户B(IP: 2.2.2.2)→ 永远去服务器2
保证用户的购物车、登录状态不丢失

配置示例:

复制代码
# 定义后端服务器组
upstream backend_servers {
    # 负载均衡策略:
    # 默认:轮询(round-robin)
    # ip_hash:根据 IP 分配(会话保持)
    # least_conn:最少连接
    # weight:权重

    ip_hash;  # 使用 IP 哈希

    server 192.168.1.101:8080 weight=3;  # 权重 3
    server 192.168.1.102:8080 weight=2;  # 权重 2
    server 192.168.1.103:8080 weight=1;  # 权重 1
    server 192.168.1.104:8080 backup;    # 备用服务器
}

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

    location / {
        proxy_pass http://backend_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

一句话总结:负载均衡就是把很多请求分散到多台服务器,避免一台服务器被压垮。


概念五:HTTPS

HTTP vs HTTPS

复制代码
【HTTP】明文传输
┌─────────────────────────────────────────────────────────┐
│                                                         │
│  你 ──────"密码是123456"─────→ 网站                     │
│                ↑                                        │
│        黑客可以偷听到!                                 │
│        就像在公共场合大声说话                           │
│                                                         │
└─────────────────────────────────────────────────────────┘

【HTTPS】加密传输
┌─────────────────────────────────────────────────────────┐
│                                                         │
│  你 ──────"@#$%^&*加密内容"─────→ 网站                  │
│                ↑                                        │
│        黑客听到也看不懂!                               │
│        就像用密码本传递信息                             │
│                                                         │
└─────────────────────────────────────────────────────────┘

生活比喻

复制代码
HTTP = 明信片
┌─────────────────────────────────────────────────────────┐
│  邮递员、路人都能看到你写的内容                         │
└─────────────────────────────────────────────────────────┘

HTTPS = 带锁的保险箱
┌─────────────────────────────────────────────────────────┐
│  只有收件人有钥匙,别人打不开                           │
└─────────────────────────────────────────────────────────┘

HTTPS 工作原理(简化版)

复制代码
1. 你访问 https://银行.com

2. 网站出示"身份证"(SSL证书)
   证书上写着:"我确实是银行.com,不是假冒的"
   证书由权威机构(CA)签发

3. 浏览器验证证书
   "证书是真的,你确实是银行.com"

4. 双方协商一个"密码本"(加密密钥)

5. 之后所有通信都用这个"密码本"加密
   黑客即使截获也看不懂

为什么需要 HTTPS?

复制代码
✓ 数据加密 - 密码、银行卡号不会被偷
✓ 身份验证 - 确保你访问的是真网站,不是钓鱼网站
✓ 数据完整 - 确保数据没被篡改

现代浏览器对 HTTP 网站会显示"不安全"警告
搜索引擎优先收录 HTTPS 网站

示例

复制代码
server {
    listen 443 ssl http2;
    server_name www.example.com;

    # SSL 证书配置
    ssl_certificate /etc/nginx/ssl/example.com.pem;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    # SSL 安全配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # HSTS(强制 HTTPS)
    add_header Strict-Transport-Security "max-age=31536000" always;

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

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

# HTTP 跳转 HTTPS
server {
    listen 80;
    server_name www.example.com example.com;
    return 301 https://www.example.com$request_uri;
}

一句话总结:HTTPS 就是给 HTTP 加了一把锁,让数据传输更安全。


概念六:跨域(CORS)

什么是跨域?

复制代码
【同源】
你的网页:https://www.example.com
请求地址:https://www.example.com/api/users
    ↓
协议相同(https)、域名相同(www.example.com)、端口相同
    ↓
这是"同源",浏览器允许


【跨域】
你的网页:https://www.example.com
请求地址:https://api.other.com/users
    ↓
域名不同!
    ↓
这是"跨域",浏览器默认禁止!

为什么浏览器要禁止跨域?

复制代码
安全考虑!

假设没有跨域限制:

1. 你登录了银行网站,有登录状态(Cookie)

2. 你不小心打开了一个恶意网站

3. 恶意网站的 JS 代码偷偷请求:
   fetch('https://银行.com/api/转账?to=黑客&amount=100万')

4. 因为你有银行的 Cookie,请求会带上你的身份

5. 钱就被转走了!

有了跨域限制:

恶意网站的 JS 无法请求其他网站的 API
你的银行账户就安全了

生活比喻

复制代码
跨域限制 = 小区门禁

你是 A 小区的住户(www.a.com)
    ↓
你可以自由进出 A 小区(请求 www.a.com)
    ↓
但你不能随便进 B 小区(请求 www.b.com)
    ↓
除非 B 小区物业说"让他进来"(服务器允许跨域)

怎么解决跨域?

复制代码
方法:服务器告诉浏览器"我允许他访问"

服务器返回响应头:
Access-Control-Allow-Origin: https://www.example.com

意思是:
"我允许 https://www.example.com 这个网站的 JS 访问我"

浏览器看到这个头,就放行了

你的项目为什么没有跨域问题?

复制代码
开发时:
┌─────────────────────────────────────────────────────────┐
│  你的前端:http://localhost:5173                        │
│  后端 API:http://localhost:8080                        │
│                                                         │
│  端口不同,本来会跨域                                   │
│                                                         │
│  但是 Vite 开发服务器配置了代理:                       │
│  /api/* → 转发到 localhost:8080                         │
│                                                         │
│  所以前端请求 /api/xxx                                  │
│  实际上是请求 localhost:5173/api/xxx                    │
│  Vite 再转发给 localhost:8080                           │
│                                                         │
│  浏览器看到的是同源请求,不会跨域!                     │
└─────────────────────────────────────────────────────────┘

生产时(用 Nginx):
┌─────────────────────────────────────────────────────────┐
│  前端和 API 都走 www.example.com                        │
│                                                         │
│  前端:www.example.com/                                 │
│  API:www.example.com/api/                              │
│                                                         │
│  Nginx 把 /api/ 转发给后端                              │
│  用户浏览器看到的都是同一个域名                         │
│  没有跨域问题!                                         │
└─────────────────────────────────────────────────────────┘

一句话总结:跨域是浏览器的安全限制,阻止网页 JS 请求其他网站;通过服务器配置或代理可以解决。


概念七:限流

什么是限流?

复制代码
场景:
你开了一家小餐厅,最多同时接待 50 人
    ↓
突然来了 500 人
    ↓
厨房爆炸,服务员崩溃,谁都吃不上饭
    ↓
餐厅倒闭

解决方案:
在门口放个保安(限流)
    ↓
"店里已经 50 人了,请排队等候"
    ↓
控制进入的人数
    ↓
餐厅正常运营

限流的作用

复制代码
1. 保护服务器不被压垮

2. 防止恶意攻击
   - 有人写脚本疯狂请求你的网站
   - 1秒钟请求1万次
   - 想把你的服务器搞崩
   - 限流:每秒最多10次,超过的拒绝

3. 公平分配资源
   - 不让一个用户占用所有资源
   - 大家都能用

限流策略

复制代码
【按请求频率限制】
每秒最多处理 100 个请求
第 101 个请求:等一下或者返回错误

【按 IP 限制】
每个 IP 每秒最多 10 个请求
防止单个用户/攻击者发太多请求

【按用户限制】
每个登录用户每分钟最多 100 个请求
API 接口常用这种

【按并发连接限制】
同时最多 1000 个连接
超过的等着

一句话总结:限流就是控制请求数量,防止服务器被压垮或被攻击。


总结:一张图理解所有概念

复制代码
                                    互联网
                                       │
                                       ▼
                            ┌──────────────────┐
                            │                  │
                            │   用户的浏览器   │
                            │                  │
                            └────────┬─────────┘
                                     │
                                     │ HTTPS(加密传输)
                                     │
                                     ▼
┌────────────────────────────────────────────────────────────────┐
│                                                                │
│                     Nginx(门卫 + 前台)                        │
│                                                                │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐         │
│  │   限流       │  │   跨域处理   │  │  负载均衡    │         │
│  │   控制流量   │  │   允许/拒绝  │  │  分发请求    │         │
│  └──────────────┘  └──────────────┘  └──────────────┘         │
│                                                                │
│  ┌─────────────────────────┐  ┌─────────────────────────┐     │
│  │                         │  │                         │     │
│  │  静态托管               │  │  反向代理               │     │
│  │  返回 HTML/CSS/JS/图片  │  │  转发 API 请求给后端    │     │
│  │                         │  │                         │     │
│  └─────────────────────────┘  └───────────┬─────────────┘     │
│           │                               │                   │
└───────────┼───────────────────────────────┼───────────────────┘
            │                               │
            ▼                               ▼
    ┌───────────────┐             ┌───────────────────────┐
    │               │             │                       │
    │  dist 文件夹  │             │  后端服务器集群       │
    │  (Vue 打包)   │             │  ┌─────┐ ┌─────┐      │
    │               │             │  │ 1   │ │ 2   │ ...  │
    │  index.html   │             │  └─────┘ └─────┘      │
    │  app.js       │             │                       │
    │  style.css    │             │  处理 API 请求        │
    │               │             │  查询数据库           │
    └───────────────┘             └───────────────────────┘
            │
            │
            ▼
    ┌───────────────┐
    │               │
    │  单页应用     │
    │  (SPA)        │
    │               │
    │  Vue Router   │
    │  处理前端路由 │
    │               │
    └───────────────┘

对应你项目的情况

概念 你的项目怎么用的
静态托管 Nginx 托管 dist 文件夹里的 Vue 打包文件
单页应用 Vue + Vue Router,只有一个 index.html
反向代理 开发时 Vite 代理 /api,生产时 Nginx 代理
负载均衡 目前没用到(单服务器),以后可以扩展
HTTPS 目前配置文件没有,生产环境需要添加
跨域 通过代理解决,不需要额外配置
限流 目前没用到,可以根据需要添加

现在这些概念应该清楚多了吧?有任何还不理解的地方,随时问我!

相关推荐
何中应17 小时前
Nginx转发请求错误
前端·后端·nginx
芝士雪豹只抽瑞克五1 天前
Nginx 高性能Web服务器笔记
服务器·nginx
失重外太空啦1 天前
nginx
运维·nginx
天蓝不会忘记022 天前
lvs,haproxy,keepalived,nginx,tomcat介绍和实验
nginx·tomcat·lvs
feng68_2 天前
Nginx高性能Web服务器
linux·运维·服务器·nginx
unfeeling_2 天前
Nginx实验
运维·nginx
倚肆2 天前
在 Windows Docker 中安装并配置 Nginx (映射 Windows 端口与路径)
windows·nginx·docker
shawnyz2 天前
Nginx的源码编译
运维·nginx
简离2 天前
Nginx限流触发原因排查及前端优化方案
前端·nginx