Nginx处理http的流程


前言


一、发版本后旧版本可以用

发版本后旧版本可以用,需要手动刷新后才可获取新版本。

项目基本情况

版本配置:
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')],
        // 指定symbolId
        symbolId: '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";
}

解释每一行的作用:

  1. expires -1;

    • 该指令会禁用对 /pc/index.html 文件的缓存。expires -1 表示资源过期时间设置为负值,浏览器会认为该资源立即过期。
  2. 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 秒。即使缓存了该文件,也需要每次请求都重新验证。
  3. add_header Pragma "no-cache";

    • Pragma: no-cache 是 HTTP/1.0 中用于禁用缓存的指令,虽然它现在已经较少使用,但为了兼容老旧的 HTTP/1.0 客户端,它仍然添加。
  4. 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_namelocation 规则,找到相应的配置
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 请求的核心代码主要在:

  1. src/http/ngx_http_request.c (请求解析)
  2. src/http/ngx_http_core_module.c (匹配 serverlocation
  3. src/http/ngx_http_handler.c (调用不同的 handler)
  4. src/http/ngx_http_output_filter.c (返回 HTTP 响应)

3. HTTP 请求解析:ngx_http_request.c

📌 作用

  • 解析 HTTP 请求行(GET /index.html HTTP/1.1
  • 解析 HTTP 头部(HostUser-Agent 等)
  • 解析请求体(Content-LengthPOST 数据)
关键结构体:ngx_http_request_t

所有 HTTP 请求的信息都会存储在 ngx_http_request_t 结构体:

struct ngx_http_request_s {
    ngx_http_connection_t   *connection;  // 关联客户端连接
    ngx_str_t uri;                       // 请求的 URI
    ngx_str_t args;                      // URL 查询参数 ?id=123
    ngx_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 / locationngx_http_core_module.c
  • 调用合适的处理模块ngx_http_handler.c
  • 发送响应ngx_http_output_filter.c

这个 完整 HTTP 处理流程 让 Nginx 成为一个高性能 Web 服务器 🚀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TE-茶叶蛋

踩坑不易,您的打赏,感谢万分

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值