文章目录
- 前言
- 一、发版本后旧版本可以用
- 项目基本情况
- Nginx 配置
- **解释每一行的作用:**
- **表现和行为:**
- **适用场景**:
- 资源的缓存策略
- 在这里插入图片描述
- 二, nginx处理http的流程
- Nginx 的 GitHub 源码地址
- **Nginx 核心源码解读(HTTP 处理流程)**
- **1. Nginx 处理 HTTP 请求的完整流程**
- **2. Nginx 处理 HTTP 请求的核心源码**
- **3. HTTP 请求解析:`ngx_http_request.c`**
- **关键结构体:`ngx_http_request_t`**
- **3.1 解析 HTTP 请求行**
- **3.2 解析 HTTP 头**
- **4. 匹配 Server/Location:`ngx_http_core_module.c`**
- **4.1 解析 `server {}`**
- **4.2 解析 `location {}`**
- **5. 处理 HTTP 请求 Handler**
- **6. 发送 HTTP 响应**
- **7. Nginx HTTP 请求完整流程**
- **8. 经典优化**
- ✅ **优化 Worker**
- ✅ **开启 `sendfile`**
- ✅ **启用 Gzip**
- **总结**
前言
一、发版本后旧版本可以用
发版本后旧版本可以用,需要手动刷新后才可获取新版本。
项目基本情况
版本配置:
vue :" ^3.2.25"
vite : “^3.1.0”
element-plus: “^2.1.7”
vite.config.js
export default ({ command, mode }: ConfigEnv): UserConfig => {return {plugins: [vue(),vueJsx({}),AutoImport({resolvers: [ElementPlusResolver()]}),Components({resolvers: [ElementPlusResolver()]}),createSvgIconsPlugin({// 需要缓存的文件夹iconDirs: [resolve(process.cwd(), 'src/assets/svgs')],// 指定symbolIdsymbolId: 'icon-[dir]-[name]'})],build: {},}
}
Nginx 配置
# 禁用 /pc/index.html 缓存location /pc/index.html {expires -1; # 不缓存add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";add_header Pragma "no-cache";add_header Expires "0";}
在 Nginx 配置中设置 location /mobile/index.html
来禁用缓存,具体来说,配置如下:
location /mobile/index.html {expires -1; # 不缓存add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";add_header Pragma "no-cache";add_header Expires "0";
}
解释每一行的作用:
-
expires -1;
- 该指令会禁用对
/pc/index.html
文件的缓存。expires -1
表示资源过期时间设置为负值,浏览器会认为该资源立即过期。
- 该指令会禁用对
-
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
no-store
:要求浏览器不要缓存任何响应内容。no-cache
:即使缓存了该资源,也要求浏览器每次都向服务器验证资源是否更新(即使是缓存的资源也不能直接使用,必须验证)。must-revalidate
:在缓存过期后,必须向服务器验证缓存的有效性。proxy-revalidate
:在代理缓存过期后,必须验证缓存的有效性。max-age=0
:表示资源的最大有效时间为 0 秒。即使缓存了该文件,也需要每次请求都重新验证。
-
add_header Pragma "no-cache";
Pragma: no-cache
是 HTTP/1.0 中用于禁用缓存的指令,虽然它现在已经较少使用,但为了兼容老旧的 HTTP/1.0 客户端,它仍然添加。
-
add_header Expires "0";
- 这表示
Expires
头部设置为0
,使得资源立即过期。Expires
是 HTTP/1.0 中用来指定资源过期时间的字段,设置为0
等同于禁止缓存。
- 这表示
表现和行为:
-
浏览器行为:
- 当用户访问
/pc/index.html
时,浏览器将不会缓存该文件,每次请求时都会向服务器发起新的请求。 - 浏览器会每次请求时验证该文件是否有更新,服务器每次返回
index.html
文件时都会重新加载,而不使用缓存中的文件。
- 当用户访问
-
代理缓存:
- 如果该请求通过代理(例如 CDN 或缓存代理),代理也会被指示不缓存该资源。即便代理缓存了该文件,也会在缓存过期后重新验证文件的有效性。
-
确保文件每次都重新请求:
- 这种配置主要用于动态文件,确保用户始终获取到最新版本的文件,而不被浏览器或代理缓存。
适用场景:
这种配置适用于你希望某些页面 始终从服务器获取最新版本,而不依赖于浏览器缓存的情况。例如:
- 动态生成的页面(如登录页、用户界面等)。
- 某些特殊的
index.html
页面,其中包含根据请求而动态变化的内容或配置。
该配置会 完全禁用 /mobile/index.html
的缓存,确保浏览器每次访问时都从服务器重新获取该文件,无论文件内容是否发生变化。
资源的缓存策略
二, nginx处理http的流程
Nginx 的 GitHub 源码地址
Nginx 的官方源码托管在 GitHub 和 官方 Mercurial 仓库:
GitHub 镜像(非官方维护,仅同步):
nginx
官方 Mercurial(hg)仓库:
http://hg.nginx.org/nginx/
Nginx 核心源码解读(HTTP 处理流程)
Nginx 作为高性能 Web 服务器,采用 事件驱动 + 多进程架构,核心 HTTP 处理流程涉及 请求解析、匹配 location、调用模块处理请求、返回响应。
1. Nginx 处理 HTTP 请求的完整流程
当一个 HTTP 请求到达 Nginx 时,Nginx 主要执行以下 6 个阶段:
阶段 | 作用 |
---|---|
1. 接收请求 | accept() 监听连接,创建 ngx_connection_t 结构体 |
2. 解析请求 | 解析 GET /index.html HTTP/1.1 ,存储在 ngx_http_request_t 结构体 |
3. 匹配 Server/Location | 根据 server_name 和 location 规则,找到相应的配置 |
4. 执行 HTTP 过滤模块 | 例如 rewrite , access , gzip 等模块 |
5. 选择 Handler 处理请求 | 例如 ngx_http_static_module 处理静态文件,ngx_http_proxy_module 代理请求 |
6. 发送响应 | 发送 200 OK 响应头,返回 HTML/JSON/静态文件 |
2. Nginx 处理 HTTP 请求的核心源码
Nginx 处理 HTTP 请求的核心代码主要在:
src/http/ngx_http_request.c
(请求解析)src/http/ngx_http_core_module.c
(匹配server
和location
)src/http/ngx_http_handler.c
(调用不同的 handler)src/http/ngx_http_output_filter.c
(返回 HTTP 响应)
3. HTTP 请求解析:ngx_http_request.c
📌 作用:
- 解析 HTTP 请求行(
GET /index.html HTTP/1.1
) - 解析 HTTP 头部(
Host
、User-Agent
等) - 解析请求体(
Content-Length
、POST
数据)
关键结构体:ngx_http_request_t
所有 HTTP 请求的信息都会存储在 ngx_http_request_t
结构体:
struct ngx_http_request_s {ngx_http_connection_t *connection; // 关联客户端连接ngx_str_t uri; // 请求的 URIngx_str_t args; // URL 查询参数 ?id=123ngx_uint_t method; // HTTP 方法 (GET, POST)ngx_http_headers_in_t headers_in; // HTTP 请求头ngx_http_headers_out_t headers_out; // HTTP 响应头ngx_http_core_loc_conf_t *loc_conf; // 匹配的 location 配置
};
3.1 解析 HTTP 请求行
📌 代码位置:ngx_http_parse_request_line()
ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
解析 GET /index.html HTTP/1.1
:
if (ngx_str3_cmp(m, 'G', 'E', 'T', ' ')) {r->method = NGX_HTTP_GET;
} else if (ngx_str3_cmp(m, 'P', 'O', 'S', 'T')) {r->method = NGX_HTTP_POST;
}
- 解析 URI:
r->uri_start = p;
while (*p && *p != '?' && *p != ' ') { p++; }
r->uri_end = p;
- 解析 HTTP 版本:
if (ngx_str3_cmp(p, 'H', 'T', 'T', 'P')) { r->http_version = NGX_HTTP_VERSION_11; }
3.2 解析 HTTP 头
📌 代码位置:ngx_http_parse_header_line()
ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b, ngx_uint_t allow_underscores)
解析请求头(示例):
Host: example.com
User-Agent: curl/7.68.0
代码:
if (ngx_str3_cmp(h, 'H', 'o', 's', 't')) {r->headers_in.host = h;
} else if (ngx_str3_cmp(h, 'C', 'o', 'n', 't', 'e', 'n', 't', '-', 'L', 'e', 'n', 'g', 't', 'h')) {r->headers_in.content_length_n = ngx_atoi(value, len);
}
4. 匹配 Server/Location:ngx_http_core_module.c
📌 作用:
- 解析
server {}
和location {}
配置 - 选择最匹配的
server {}
块 - 选择最匹配的
location {}
规则
4.1 解析 server {}
📌 代码位置:ngx_http_core_server()
static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
- 解析
listen 80;
- 解析
server_name example.com;
- 解析
location / {}
4.2 解析 location {}
📌 代码位置:ngx_http_core_location()
static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
- 解析
root /var/www/html;
- 解析
proxy_pass http://backend;
5. 处理 HTTP 请求 Handler
📌 代码位置:ngx_http_handler.c
ngx_int_t ngx_http_handler(ngx_http_request_t *r)
- 选择合适的模块处理请求:
ngx_http_static_module
(静态文件)ngx_http_proxy_module
(反向代理)ngx_http_rewrite_module
(重写)ngx_http_gzip_module
(Gzip 压缩)
6. 发送 HTTP 响应
📌 代码位置:ngx_http_output_filter.c
ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
1️⃣ 设置 HTTP 状态码
r->headers_out.status = NGX_HTTP_OK;
2️⃣ 设置响应头
r->headers_out.content_length_n = size;
r->headers_out.content_type = ngx_string("text/html");
3️⃣ 发送数据
ngx_http_send_header(r);
ngx_http_output_filter(r, &out);
7. Nginx HTTP 请求完整流程
1. 客户端请求: GET /index.html HTTP/1.1
2. Nginx 解析请求 (ngx_http_request.c)
3. 匹配 server/location (ngx_http_core_module.c)
4. 选择模块处理请求 (ngx_http_handler.c)
5. 发送 HTTP 响应 (ngx_http_output_filter.c)
8. 经典优化
✅ 优化 Worker
worker_processes auto;
worker_connections 4096;
✅ 开启 sendfile
sendfile on;
tcp_nopush on;
✅ 启用 Gzip
gzip on;
gzip_types text/html text/css application/json;
总结
- Nginx 解析 HTTP 请求 →
ngx_http_request.c
- 匹配
server
/location
→ngx_http_core_module.c
- 调用合适的处理模块 →
ngx_http_handler.c
- 发送响应 →
ngx_http_output_filter.c
这个 完整 HTTP 处理流程 让 Nginx 成为一个高性能 Web 服务器 🚀