前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >五分钟学NGINX-详解nginx的11个请求阶段

五分钟学NGINX-详解nginx的11个请求阶段

原创
作者头像
五分钟学SRE
发布2024-04-22 02:05:53
4520
发布2024-04-22 02:05:53
举报
文章被收录于专栏:五分钟学SRE五分钟学SRE

在上一个篇章我们理解了nginx 处理HTTP 头部的原理跟流程,我们继续细化的看下 nginx 处理HTTP请求的过程。

    Nginx,作为当今最流行的开源Web服务器之一,以其高性能、高稳定性和丰富的功能而闻名。在处理HTTP请求的过程中,Nginx采用了模块化的设计,将整个请求处理流程划分为若干个阶段,每个阶段都可以由特定的模块来处理。这种设计不仅使得Nginx具有极高的灵活性和可扩展性,而且也方便了开发者对Nginx进行定制和优化。我们将深入探讨Nginx处理HTTP请求的11个阶段,揭示其背后的工作原理。

在Nginx中,一个HTTP请求从接收到响应的整个生命周期被划分为以下11个阶段:

  1. postread - 读取请求行和请求头后的处理。
  2. server-rewrite - 服务器级别的URL重写。
  3. find-config - 寻找配置文件中的相关指令。
  4. rewrite - 根据配置进行URL重写。
  5. post-rewrite - 重写后的处理。
  6. preaccess - 访问权限前的检查。
  7. access - 访问权限控制。
  8. postaccess - 访问权限控制后的处理。
  9. try-files - 尝试访问文件或目录。
  10. content - 内容生成阶段。
  11. log - 日志记录阶段。

我们来详细的看下nginx 处理的 11 个阶段

POST READ

    这一步是在请求读取之后执行的。在这个阶段,Nginx 可能会执行一些在读取请求头和请求体之后需要进行的操作,例如清理请求体数据,以便后续模块可以使用。里面有一个realip模块: realip 模块用于记录和设置客户端的真实 IP 地址。在代理服务器中,客户端的真实 IP 可能被隐藏在 X-Forwarded-For 头或者通过代理协议传递。realip 模块可以帮助确定真实的客户端 IP 地址,这对于日志记录、安全控制等非常有用。

在HTTP协议中,为了穿越多个代理层并最终确定用户的真实IP地址,通常会使用两个特定的HTTP头部字段:X-Forwarded-ForX-Real-IP。这两个字段在处理通过Nginx等反向代理服务器传输的请求时非常重要。

  1. X-Forwarded-For:X-Forwarded-For头部字段用于传递客户端请求经过的所有代理服务器的IP地址。这个头部通常包含一个或多个IP地址,它们按照请求经过代理的顺序排列。如果请求直接发送到服务器,则此头部可能不存在或只包含客户端的IP地址。在存在多个代理的情况下,X-Forwarded-For头部将包含一个由逗号分隔的IP地址列表,其中列表中的最后一个IP地址是客户端的真实IP地址。
  2. X-Real-IP:X-Real-IP头部字段旨在记录客户端的真实IP地址,它只包含一个IP地址。这个头部字段由第一个代理服务器设置,并且在请求穿越后续代理时不会被更改,因此它代表了客户端的原始IP地址。

    拿到真实用户IP后,Nginx可以通过基于变量的方式来使用这些信息。例如,binary_remote_addrremote_addr这样的变量可以被设置为客户端的真实IP地址。这些变量可以在Nginx的配置文件中使用,以实现各种基于IP地址的功能,如:

  • 连接限制(limit_conn模块):limit_conn模块允许Nginx限制来自单个IP地址的连接数。这是通过使用remote_addr变量来实现的,它可以识别每个连接的客户端IP地址。通过这种方式,Nginx可以防止单个客户端建立过多的连接,从而保护服务器免受拒绝服务攻击或过度负载。
  • 请求速率限制(limit_req模块):limit_req模块可以限制来自单个IP地址的请求速率。这同样依赖于remote_addr变量来追踪每个请求的来源。通过限制每个客户端的请求频率,Nginx有助于防止恶意用户或爬虫对服务器造成过大压力。

realip模块

realip模块是Nginx的一个关键组件,它允许Nginx识别和使用客户端的真实IP地址。这对于反向代理配置、日志记录、访问控制和安全策略等场景至关重要。

编译与启用

  • 默认状态realip模块在Nginx的默认编译版本中是不包含的。
  • 启用方法:通过在Nginx编译时添加--with-http_realip_module参数,可以启用realip模块。

配置指令

  • set_real_ip_from:此指令用于定义信任的代理服务器。只有来自这些服务器的X-Real-IPX-Forwarded-For头部字段才会被Nginx接受和处理。
  • real_ip_header:通过这个指令,管理员可以指定Nginx应该使用X-Real-IP还是X-Forwarded-For头部来确定客户端的真实IP地址。

重要变量

  • http_x_real_ip*:包含X-Real-IP头部的值,即客户端的真实IP地址。如果该头部不存在,则变量为空。
  • remote_addr:默认情况下,这个变量包含服务器接收到的客户端IP地址。当realip模块启用并正确配置后,它会被设置为客户端的真实IP地址。
  • http_x_forwarded_for*:包含X-Forwarded-For头部的值,这是一个IP地址列表,记录了客户端以及所有中间代理服务器的IP。
  • realip_recursive:指示realip模块是否已经递归地处理了X-Forwarded-For头部字段。
  • 存储真实客户端IP地址: realip_remote_addr 这个变量用于存储由 realip 模块解析出的真实客户端IP地址。当 realip 模块启用并且配置正确时,它会覆盖 $remote_addr 变量,确保Nginx使用的是客户端的真实IP地址。
  • 包含客户端端口号: realip_remote_port 变量包含客户端的端口号。如果 X-Real-IP 头部字段中包含了端口号的信息,那么 realip_remote_port 变量就会使用这个端口号。这有助于Nginx在处理请求时,能够获取到完整的客户端连接信息,包括IP地址和端口号。

模块应用场景

  • 日志记录:使用realip模块可以确保日志中记录的是客户端的真实IP地址,这对于分析和审计非常重要。
  • 访问控制:通过基于真实IP地址的访问控制,可以实施如IP黑名单或白名单等策略。
  • 安全策略realip模块有助于防止欺诈和滥用行为,确保服务器的安全。
  • 统计分析:准确的IP地址信息可以用于流量分析和用户行为分析,帮助网站优化和改进服务。

值得注意的是,limit_connlimit_req模块必须在preaccess阶段生效,这是因为在postread阶段之后,请求体可能已经被读取,某些信息可能不再可用。在preaccess阶段,Nginx已经获取了请求头中的X-Forwarded-ForX-Real-IP信息,并将其存储在相应的变量中,这时可以基于这些变量来实施限制。这样,Nginx能够确保连接限制和请求速率限制是在接收到足够信息的情况下进行的,从而有效地管理客户端请求。

SERVER REWRITE

    在 Nginx 的处理流程中,rewrite 阶段扮演着至关重要的角色。该阶段主要负责对请求的 URI 进行重写操作,从而实现复杂的路由逻辑。rewrite 阶段分为两个子阶段:server_rewrite 和 rewrite。这两个子阶段都依赖于 rewrite 模块来执行 URI 的重写操作。

    在 rewrite 模块中,return 指令起着决定性的作用。当 Nginx 执行到 return 指令时,它会立即停止进一步的处理,并根据指令的内容返回相应的响应。return 指令的语法非常灵活,可以返回状态码、文本或 URL,具体取决于实际的应用场景。

 让我们深入了解一下 return 指令的工作原理。return 指令的基本语法如下:

代码语言:javascript
复制
return code [text];:根据指定的状态码和可选的文本返回响应。return code URL;:根据指定的状态码和 URL 进行重定向。return URL;:直接返回指定的 URL。

    状态码的种类繁多,涵盖了 Nginx 自定义状态码以及 HTTP 标准状态码。

    在实际应用中,return 指令经常与 error_page 指令一起使用。error_page 指令用于定义当特定错误代码发生时应该如何处理。通过配置 error_page,可以为用户提供友好的错误页面,而不是简单地显示一个生硬的错误代码。

可以找一些具体的例子来加深对 error_page 指令的理解:

  1. error_page 404 /404.html;:当请求返回 404 错误时,Nginx 会返回 /404.html 页面。
  2. error_page 500 502 503 504 /50x.html;:当请求返回 500、502、503 或 504 错误时,Nginx 都会返回 /50x.html 页面。

    现在,我们来探讨一个实际的问题:当 server 块下包含 error_page 指令,而 location 块下也有 return 指令时,Nginx 会优先执行哪个指令?通过实际测试,我们发现 Nginx 会先执行 location 块下的 return 指令。这是因为 location 块具有更高的优先级,它会覆盖 server 块下的相关设置。

    除了 return 指令外,rewrite 指令也是 rewrite 模块中的重要组成部分。rewrite 指令用于根据正则表达式匹配请求的 URI,并将其替换为新的 URI。这使得我们能够实现复杂的 URL 重写规则,从而满足不同业务场景的需求。

rewrite 指令的语法如下:

    rewrite regex replacement [flag];:根据正则表达式 regex 匹配请求的 URI,并将其替换为 replacement 指定的新 URI。可选的 flag 参数用于指定后续行为。

    rewrite 指令的功能非常强大,它不仅可以实现简单的 URI 替换,还可以利用正则表达式和变量进行复杂的匹配和提取操作。此外,通过设置不同的 flag 参数,我们可以控制重写后的 URI 如何被进一步处理。

 让我们通过一个实际的例子来演示 how rewrite 指令工作。假设我们有以下目录结构

代码语言:javascript
复制
html/first/:包含 1.txt 文件html/second/:包含 2.txt 文件html/third/:包含 3.txt 文件

配置文件如下所示:

代码语言:javascript
复制
server {    listen 80;    server_name rewrite.ziyang.com;
    root html/;    location /first {        rewrite /first(.*) /second$1 last;        return 200 'first!\n';    }
    location /second {        rewrite /second(.*) /third$1;        return 200 'second!\n';    }
    location /third {        return 200 'third!\n';    }}

    当请求到达 /first/3.txt 时,由于 location /first 中的 rewrite 规则,URI 会被重写为 /second/3.txt。然后,Nginx 会继续在 location /second 中查找匹配的规则。由于 /second/3.txt 与 location /second 的匹配模式相匹配,因此 Nginx 会再次执行 rewrite 规则,将 URI 重写为 /third/3.txt。最后,Nginx 在 location /third 中找到匹配的规则,并返回 'third!\n' 作为响应。

    通过以上示例,我们可以看到 rewrite 指令如何根据正则表达式匹配和替换 URI,从而实现复杂的路由逻辑。同时,我们也了解了 return 指令的工作原理以及它与 error_page 指令的关系。这些知识对于编写高效、可维护的 Nginx 配置文件至关重要。

FIND CONFIG

在 Nginx 中,find_config 阶段发生在 URI 重写之后,其目的是在服务器的配置中找到与请求 URI 匹配的 location 块。这一阶段是 Nginx 处理请求过程中的路由环节,确保请求被正确地引导到相应的处理程序。

location 指令

    location 指令是 Nginx 配置中用于定义请求处理上下文的关键部分。它允许开发者根据不同的 URI 路径、正则表达式或命名位置来设置特定的配置。

以下是 location 指令的基本语法:

代码语言:javascript
复制
location [ = | ~ | ~* | ^~ ] uri {    # 配置指令}
  • =:精确匹配,仅当 URI 完全匹配时才使用此 location 块。
  • ^~:前缀匹配,如果匹配成功,则不再搜索正则表达式 location 块。
  • ~:大小写敏感的正则表达式匹配。
  • ~*:大小写不敏感的正则表达式匹配。

此外,还可以使用命名位置

代码语言:javascript
复制
location @name {    # 配置指令}
代码语言:javascript
复制
merge_slashes 指令

    merge_slashes 指令控制 Nginx 是否合并 URI 中的重复斜杠 /。默认情况下,merge_slashes 被设置为 on,这意味着 Nginx 会自动将 URI 中的多个连续斜杠合并为一个。这个行为对于大多数应用来说是透明的,但在处理如 base64 编码的 URI 时,可能需要关闭此功能。

代码语言:javascript
复制
merge_slashes on | off;
匹配规则

Nginx 的 location 匹配遵循以下规则:

  1. 前缀字符串匹配
    • 使用 ^~ 前缀的 location 块将进行前缀匹配,如果匹配成功,则 Nginx 将不会考虑任何正则表达式 location 块。
  2. 常规匹配
    • 使用 = 前缀的 location 块将进行精确匹配,仅当请求的 URI 完全等同于 location 块中定义的 URI 时才会匹配。
  3. 正则表达式匹配
    • 使用 ~~* 前缀的 location 块将根据正则表达式进行匹配。~ 是大小写敏感的,而 ~* 是大小写不敏感的。
  4. 命名位置匹配
    • 使用 @ 前缀的 location 块定义了一个命名位置,可以通过 error_pagetry_files 等指令进行内部跳转。
  5. 参数忽略
    • 在匹配 location 时,Nginx 仅考虑 URI 的路径部分,忽略查询字符串。
  6. 匹配顺序
    • Nginx 首先尝试精确匹配,然后是最长的前缀匹配,接着是正则表达式匹配。如果有多个 location 块匹配同一个 URI,Nginx 将使用第一个找到的匹配项。

REWRITE

这是又一次的重写阶段,但这次是在找到匹配的 location 之后。这允许 location 级别的重写规则来修改请求的 URI。

POST REWRITE

在所有的重写规则应用之后,Nginx 执行这个阶段的处理。这可以用于执行一些在 URI 重写之后需要进行的操作,例如权限检查或者额外的日志记录。

PREACCESS

这个阶段包括 limit_connlimit_req 指令,用于限制每个客户端的连接数和请求速率。这是一个访问控制的阶段,可以在允许请求访问服务器资源之前进行一些限制。

    在 Nginx 的请求处理流程中,preaccess 阶段是一个关键的控制点,它在实际请求处理之前执行,主要用于处理如限制并发连接数和访问频率等任务。以下是对 Nginx 中 limit_connlimit_req 模块的详细描述,以及相关指令的语法和应用场景。

limit_conn 模块

limit_conn 模块(ngx_http_limit_conn_module)用于限制每个客户端的并发连接数。以下是该模块的关键特性和指令语法:

  1. 生效阶段NGX_HTTP_PREACCESS_PHASE,即在请求进入 preaccess 阶段时生效。
  2. 默认编译:默认编译进 Nginx,可以通过编译选项 --without-http_limit_conn_module 禁用。
  3. 生效范围:作用于所有 worker 进程,基于共享内存实现。
  4. 限制有效性:依赖于 key 的设计,通常基于真实 IP 地址进行限制。
指令语法
  • 定义共享内存和 key
代码语言:javascript
复制
limit_conn_zone key zone=name:size;
  • key:用于限制的变量,通常是客户端的真实 IP 地址。
  • zone:共享内存区域的名称和大小。
  • 限制并发连接数
代码语言:javascript
复制
imit_conn zone number;
  • 日志级别
代码语言:javascript
复制
limit_conn_log_level info | notice | warn | error;
  • 错误码
代码语言:javascript
复制
limit_conn_status code;
limit_req 模块

limit_req 模块(ngx_http_limit_req_module)用于限制客户端的访问频率,以防止滥用或过载。以下是该模块的关键特性和指令语法:

  1. 生效阶段NGX_HTTP_PREACCESS_PHASE
  2. 默认编译:默认编译进 Nginx,可以通过编译选项 --without-http_limit_req_module 禁用。
  3. 生效算法:使用漏桶算法(leaky bucket algorithm)。
  4. 生效范围:作用于所有 worker 进程,基于共享内存实现。
漏桶算法

漏桶算法是一种恒定的速率限制算法,它定义了一个固定容量的桶,请求像水一样流入桶中,并以恒定速率流出。如果桶满了,额外的请求就会被拒绝。指令语法

  • 定义共享内存、key 和限制速率

limit_req_zone key zone=name:size rate=rate;

  • key:用于限制的变量,通常是客户端的真实 IP 地址。
  • zone:共享内存区域的名称和大小。
  • rate:请求的处理速率,单位为 r/s(每秒处理的请求数)或 r/m(每分钟处理的请求数)。

  • 限制并发请求

limit_req zone=name [burst=number] [nodelay];

  • zone:指定共享内存区域的名称。
  • burst:桶的初始容量,默认为 0。
  • nodelay:如果设置,即使请求在桶中也会被立即拒绝。

  • 日志级别

limit_req_log_level info | notice | warn | error;

  • 定义当请求频率超过限制时记录的日志级别。

  • 错误码

limit_req_status code;

  • code:当请求频率超过限制时返回给客户端的错误码,默认为 503。

    通过合理配置 limit_connlimit_req 模块,Nginx 能够有效地控制客户端的并发连接数和访问频率,从而提高服务器的稳定性和安全性。 ACCESS 在这个阶段,Nginx 执行 auth_basicaccess 指令,用于基于用户凭证和 IP 地址等条件来控制访问。auth_request 指令允许子请求来验证用户是否有权限访问资源。     在 Nginx 的请求处理流程中,access 阶段负责执行访问控制和用户认证。以下是对 Nginx 中 access 模块、auth_basic 模块和 auth_request 模块的描述,以及相关指令的语法和应用场景。 access 模块     access 模块(ngx_http_access_module)提供了基于 IP 地址的访问控制。以下是该模块的关键特性和指令语法:

  1. 生效阶段NGX_HTTP_ACCESS_PHASE,即在请求进入 access 阶段时生效。
  2. 默认编译:默认编译进 Nginx,可以通过编译选项 --without-http_access_module 禁用。

指令语法

  • 允许或拒绝访问

allow address | CIDR | unix: | all;deny address | CIDR | unix: | all;

  • address:指定的 IP 地址。
  • CIDR:使用无类别域间路由(CIDR)表示法的 IP 地址范围。
  • unix::用于 Unix 套接字的访问控制。
  • all:匹配所有地址。

  • 指令执行顺序
    • allowdeny 指令是顺序执行的。一旦匹配成功,后续指令将不再执行。

    auth_basic 模块     auth_basic 模块用于实现基于 HTTP Basic Authentication 的用户认证。以下是该模块的关键特性和指令语法:

  1. 生效阶段NGX_HTTP_ACCESS_PHASE
  2. 默认编译:默认编译进 Nginx,可以通过编译选项 --without-http_auth_basic_module 禁用。

指令语法

  • 启用基本认证

auth_basic string | off;

  • string:认证领域,如 "test auth_basic"

  • 指定密码文件

auth_basic_user_file file;

  • file:包含用户名和密码的文件,通常使用 htpasswd 工具生成。

  • 密码文件生成

命令创建密码文件:

代码语言:javascript
复制
htpasswd -c file -b user pass

auth_request 模块     auth_request 模块允许 Nginx 将认证请求转发给上游服务。以下是该模块的关键特性和指令语法:

  1. 生效阶段NGX_HTTP_ACCESS_PHASE
  2. 默认编译:默认未编译进 Nginx,需要通过编译选项 --with-http_auth_request_module 启用。

指令语法

  • 转发认证请求

auth_request uri | off;

  • uri:上游服务的 URI,用于处理认证请求。

  • 设置子请求变量

auth_request_set $variable value;

  • 用于设置子请求响应中的变量。

satisfy 指令 satisfy 指令控制 access 阶段模块的满足条件:

  • 全部满足:如果设置为 all,则必须所有 access 阶段的模块都满足条件才会放行请求。
  • 任意满足:如果设置为 any,则任意一个模块满足条件即可放行请求。

satisfy all | any; 常见问题

  1. return 指令与 access 阶段的关系
    • return 指令属于 rewrite 阶段,在 access 阶段之前执行,因此如果 return 指令返回了响应,access 阶段将不会生效。
  2. 多个 access 模块的顺序影响
    • 顺序有影响,因为它们是顺序执行的。一旦某个模块的条件得到满足,后续模块将不再执行。
  3. auth_basic 与密码输入
    • 如果 satisfy 设置为 any,且 auth_basic 模块满足条件,那么即使输入了正确的密码,请求也会被放行,因为后续的 deny all 将不会被执行。
  4. allow all 与密码输入的机会
    • 如果使用 allow all,由于 allow 指令属于 access 模块,它会在 auth_basic 模块之前执行,因此用户将没有机会输入密码,请求将被立即放行。

        通过这些模块和指令,Nginx 提供了灵活的访问控制和用户认证机制,以满足不同的安全需求。 POST ACCESS     在请求通过访问控制之后,Nginx 执行这个阶段的处理。这可以用于执行一些在访问控制之后需要进行的操作,例如记录请求到后端的时间等。 PRECONTENT  在生成内容之前,Nginx 执行这个阶段的处理。try_files 指令通常在这个位置使用,用于尝试按顺序查找文件,如果找不到,则返回 404 或者执行其他操作。     在 Nginx 的请求处理流程中,precontent 阶段是内容生成之前的最后一个阶段。在这个阶段,Nginx 可以执行一些操作,如尝试提供静态文件或重定向到其他 URI。以下是对 Nginx 中 try_files 指令和 mirror 模块的描述,以及相关指令的语法和应用场景。 try_files 指令     try_files 指令允许 Nginx 尝试按顺序查找并提供多个文件。如果请求的文件存在,则 Nginx 会直接返回该文件的内容;如果所有列出的文件都不存在,则 Nginx 可以返回特定的错误码或重定向到一个 URI。 指令语法

try_files file ... uri;try_files file ... =code;

  • file:Nginx 将尝试按顺序提供这些文件。
  • uri:如果所有文件都不存在,Nginx 将重定向到这个 URI。
  • code:如果所有文件都不存在,Nginx 将返回这个 HTTP 状态码。

上下文

  • server:可以在服务器块中使用。
  • location:可以在 location 块中使用。

默认值

  • 默认情况下,try_files 指令不被设置。

模块

  • ngx_http_try_files_module:提供 try_files 指令的模块。

mirror 模块 mirror 模块允许 Nginx 在处理请求时生成子请求,并将请求镜像到其他服务。这个模块对于负载测试或将流量复制到多个环境非常有用。 指令语法

mirror uri | off;mirror_request_body on | off;

  • uri:指定子请求的目标 URI。
  • off:关闭镜像功能。
  • mirror_request_body:控制是否包括请求体在子请求中。

默认值

  • mirror 默认关闭。
  • mirror_request_body 默认开启。

模块

  • ngx_http_mirror_module:提供镜像功能的模块。

编译选项

  • 默认编译进 Nginx。
  • 可以通过编译选项 --without-http_mirror_module 移除模块。

应用场景

  1. 提供静态文件:使用 try_files 可以简化静态文件的提供过程。例如,如果请求 /images/image.png 并且该文件存在,则直接提供;如果不存在,则可能重定向到 /404.html
  2. 实现软链接:通过 try_files 可以创建软链接,将请求重定向到另一个 URI。
  3. 负载测试:使用 mirror 模块可以复制请求到多个服务,进行负载测试。
  4. 多环境部署mirror 模块还可以用于将请求实时复制到开发、测试和生产环境,以便于调试和监控。

    通过合理配置 try_files 指令和 mirror 模块,Nginx 能够灵活地处理请求,提供静态文件,以及进行有效的负载测试和流量复制 CONTENT    这是内容生成阶段。Nginx 根据请求和配置生成响应内容。index 指令用于定义目录索引,autoindex 用于自动生成目录索引,concat 用于合并多个文件作为响应发送。     Nginx 的 content 阶段是处理 HTTP 请求的最终阶段,其中涉及到的模块负责生成或提供请求的内容。以下是对 Nginx 中 static 模块、index 模块、autoindex 模块以及 concat 模块的描述,以及相关指令的语法和应用场景。 static 模块     static 模块在 Nginx 中用于提供静态文件内容,它通过 rootalias 指令将 URL 映射为文件路径。 alias 指令

  • 语法alias path;
  • 上下文location
  • 功能:将 location 块中匹配到的 URL 部分映射到指定的文件路径。

root 指令

  • 语法root path;
  • 默认值root html;
  • 上下文http, server, location, if in location
  • 功能:将完整的 URL 映射到文件路径。

应用场景

  • root 通常用于映射网站根目录。
  • alias 用于为特定的 location 创建快捷路径。

index 模块 index 模块用于指定当请求以 / 结尾的目录时,Nginx 应返回的 index 文件。 指令语法

  • 语法index file ...;
  • 默认值index index.html;
  • 上下文http, server, location

应用场景

  • 当用户访问如 http://example.com/ 这样的 URL 时,Nginx 会尝试提供 index.html 或其他指定的文件。

autoindex 模块 autoindex 模块可以自动生成目录索引,以 HTML 格式展示目录内容。 指令语法

  • 开启或关闭autoindex on | off;
  • 默认值autoindex off;
  • 上下文http, server, location

其他相关指令

  • autoindex_exact_size
  • autoindex_format
  • autoindex_localtime

应用场景

  • 当需要展示目录结构,如在开发环境中,可以使用 autoindex 模块。

concat 模块 concat 模块由阿里巴巴开发,用于合并多个小文件请求,提升 HTTP 请求性能。 指令语法

  • 开启或关闭concat on | off;
  • 默认值default concat off;
  • 上下文http, server, location

其他相关指令

  • concat_types:指定可以合并的文件 MIME 类型。
  • concat_unique:控制是否允许重复文件的合并。
  • concat_max_files:设置合并文件的最大数量。
  • concat_delimiter:定义合并文件时的分隔符。
  • concat_ignore_file_error:控制是否忽略文件错误。

应用场景

  • 在提供多个小文件,如 CSS 或 JavaScript 文件时,使用 concat 模块可以减少 HTTP 请求次数,提高网站性能。

    通过这些模块和指令,Nginx 能够高效地处理静态资源的提供、目录索引的生成以及小文件合并,从而优化网站的性能和用户体验。 LOG 最后,在 access_log 阶段,Nginx 记录请求的日志。日志可以记录请求的处理结果、性能数据等,对于分析服务器性能和调试问题非常重要。     在 Nginx 的请求处理流程中,log 阶段是最后一个阶段,负责将 HTTP 请求的相关信息记录到日志文件中。以下是对 Nginx 中 log 模块的功能、访问日志格式、日志文件路径配置、日志缓存、日志压缩以及对包含变量的日志文件名的优化的描述。 log 模块     log 模块(ngx_http_log_module)是 Nginx 中用于记录日志的核心模块,无法被禁用。它负责生成和维护访问日志,这对于分析流量、监控请求和排错非常重要。 访问日志格式 Nginx 允许自定义访问日志的格式,使用 log_format 指令定义。 指令语法

log_format name [escape=default|json|none] string ...;

  • name:自定义的日志格式名称。
  • escape:设置变量值的转义方式。
  • string:日志的具体格式,可以包含各种变量,如 $request$status 等。

默认日志格式 Nginx 默认使用 combined 格式,包含以下信息:

log_format combined '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; 配置日志文件路径 access_log 指令用于指定日志文件的存储路径和格式。 指令语法

access_log path [format=name [buffer=size] [gzip[=level]] [flush=time] [if=condition]];access_log off;

  • path:日志文件的路径,可以包含变量。
  • format:指定日志格式的名称。
  • buffer:设置日志写入的缓冲区大小。
  • gzip:启用日志文件的压缩,并可选地设置压缩级别。
  • flush:设置日志刷新的频率。
  • if:通过条件判断来控制是否记录日志。

日志缓存     日志缓存功能可以减少磁盘 I/O 操作,通过批量写入日志来提高性能。 写入磁盘的条件

  • 待写入磁盘的日志大小超出缓存大小。
  • 达到 flush 指定的时间。
  • worker 进程执行 reopen 命令,或者正在关闭。

日志压缩 日志压缩功能可以在写入磁盘前压缩日志内容,以节省存储空间。 功能特点

  • 压缩级别默认为 1,范围从 1 到 9(1 压缩速度最快,压缩率最低;9 压缩速度最慢,压缩率最高)。
  • 日志压缩默认启用日志缓存功能。

对日志文件名包含变量的优化 open_log_file_cache 指令用于优化包含变量的日志文件名的处理。 指令语法

open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];open_log_file_cache off;

  • max:缓存内的最大文件句柄数。
  • inactive:文件句柄在这段时间内未被访问则会被关闭。
  • min_uses:在 inactive 时间内,文件句柄被访问的次数超过 min_uses 才会保持在内存中。
  • valid:缓存的日志文件在这段时间后会进行检查,确认文件是否仍然存在。
  • off:关闭日志文件句柄的缓存功能。

    通过合理配置 log 模块,Nginx 能够高效地记录和维护访问日志,同时提供了日志格式自定义、日志文件路径配置、日志缓存和压缩等高级功能,以满足不同的日志记录需求。  通过上述11个阶段的解析,我们可以看到Nginx在处理HTTP请求时的严谨和细致。每个阶段都承担着特定的任务,确保了请求能够正确、高效地被处理。Nginx的模块化设计和清晰的处理流程,不仅提高了服务器的性能,也极大地方便了SRE进行功能扩展和问题排查。理解这些阶段对于深入学习Nginx原理、优化配置和解决实际问题具有重要意义。

具体可看微信公号:五分钟学SRE

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • POST READ
  • realip模块
  • 编译与启用
  • 配置指令
  • 重要变量
  • 模块应用场景
  • SERVER REWRITE
  • FIND CONFIG
    • location 指令
      • 匹配规则
      • REWRITE
      • POST REWRITE
      • PREACCESS
        • limit_conn 模块
          • 指令语法
            • limit_req 模块
              • 漏桶算法
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档