nginx语法

nginx语法

nginx语法解析

Nginx 配置文件超详细解读

为了方便日后查阅,我就以我项目中的 nginx.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行)

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 块(虚拟主机)

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 块(路由规则)- 最重要!

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 渲染 │ └─────────────────────────────────────────────────────────┘ 

六、错误页面配置

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) │ │ │ │ │ │ ... │ │ │ │ │ └─────────────────────────────────────────────┘ │ │ │ └───────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ 

八、项目的配置

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

配置示例

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目前配置文件没有,生产环境需要添加
跨域通过代理解决,不需要额外配置
限流目前没用到,可以根据需要添加

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