Nginx系列-11 HTTP消息处理流程

背景

了解Nginx处理HTTP请求的11个阶段,有助于理解和配置nginx、自定义模块、基于lua模块自定义功能。按如下配置,执行"curl http://localhost:8001/query/test.html",如果读者对结果不是很确定,建议阅读本文。

server {
    listen 8001;
    server_name localhost;
    
    rewrite ^/query/(.*)$ /ask/$1;
    
    location /ask {
        root html;
        try_files index.html =500;
        proxy_pass http://localhost:8002;
        rewrite ^/ask(.*)$ /query;
        index 50.html;
        return 200 "ask success";
    }
}

1.HTTP消息处理流程

以下分小节进行讲解Http请求进入Nginx后,处理流程按顺序分为以下11个阶段:
在这里插入图片描述

说明:所有阶段不是必须经历的,可能在某个阶段结束请求,如return指令后,请求就不再向下传递。

1.1 消息读取

[1] post_read
接收完完整的请求头后进入该阶段,由于未经过处理,此时保留请求的原始信息,如客户端的真实IP和原始请求路径。

说明:realip模块使用可参考:Nginx系列-10 realIp模块使用

1.2 rewrite

[2] server_rewrite
匹配server块后进行该阶段,处理server块中的return、rewrite等指令;
说明:return和rewrite根据配置的先后顺序执行,rewrite后可以继续执行return;而return指令执行完,直接退出处理流程,直接发送响应给客户端(即配置在return后的rewrite失效)。

server {
 rewrite指令1;
 return指令;
 rewrite指令2;
}

此时,rewrite指令1和return指令依次执行,而rewrite指令2不会执行。

说明:rewrite指令的使用可以参考:Nginx系列-6 rewrite使用介绍

[3] find_config
根据url(被rewrite后-使用重新后的url)查找匹配的location。此阶段根据请求url和location的配置进行匹配。

说明:url匹配可以参考:Nginx系列-3 servername优先级和location优先级和常用正则表达式Nginx系列-4 proxy_pass使用和路径拼接问题

[4] rewrite
进入匹配的location块后,处理location块内的return、rewrite等指令。
由此,在location中,return、rewrite指令优先级高于allow/deny, try_files, proxy_pass, index等指令。
[5] post_rewrite
判断location块内是否有重写,如果没有,进入下一阶段;如果有重写,跳到find_config阶段查询匹配的location.
此过程会判断url重写是否达到上线,如果达到上限会返回500异常,不再进行重写。

1.3 access

access包括3个阶段,用于对客户端的请求进行访问控制。
[6] pre_access
在access访问控制的前置阶段,侧重于从链路层面限制,如使用limit_req、limit_conn、limit_rate分别来控制请求数、访问速率、链接数等。
[7] access
access阶段侧重于进行业务层面的限制,如使用deny/allow实现黑白名单、使用auth模块进行用户密码校验.

说明:deny/allow的使用可以参考:Nginx系列-8 常见指令收集

[8] post_access
配合access阶段使用,如果ACCESS阶段返回了NGX_HTTP_FORBIDDEN或NGX_HTTP_UNAUTHORIZED, 会中断请求。

1.4 content

content包括2个阶段,用于生成实际的响应内容。
[9] pre_content
处理try_files指令,如果没有直接进入下一个阶段。
[10] content
处理proxy_pass、index等指令,生成响应内容。
由此可以看出,try_files的优先级高于proxy_pass和index,即当try_files和proxy_pass和index共处于location块内时,只有try_files生效。

location /ask {
    proxy_pass http://localhost:8002; #不生效
    index 50.html; #不生效
    try_files index.html =500; #生效
}

说明:try_files的使用可以参考Nginx系列-5 root和alias和index和try_files

1.* filter模块

对生成的content内容,进行进一步处理。
如ngx_http_sub_module模块提供的sub_filter可对生成的content进行字符替换。
filter模块不仅可以处理content阶段的响应,还可以处理return指令的结果:

server {
    listen 8001;
    server_name localhost;
    location /query {
        return 200 "8001 query success";
        
        # 将响应体中消息的success转为大写
  sub_filter success SUCCESS;
        sub_filter_types *;
        sub_filter_once off;
    }
}

测试结果如下所示:

[root@124 conf]# curl http://localhost:8001/query
8001 query SUCCESS

1.5 log

[11] log
access_log模块工作在此阶段,当请求发送给客户端后,记录访问日志,此时access.log文件中新增一条记录。

2.扩展

后续将介绍Nginx基于Lua模块扩展功能,会结合本文的http处理流程进行介绍。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值