• 08 nginx 的一次请求处理调试


    前言

    呵呵 这里来看一下 nginx 是如何处理一次请求的 

    这里 会有两个 case, 一个是 代理请求 upstream 的, 一个是请求 nginx 所在服务器的静态资源 

    监听端口, 处理请求的是 worker process 

    以下截图, 调试基于 nginx-1.18.0

    带 upstream 的请求处理

    配置如下, upstream "localhost:8080" 对应的是一个 SpringBoot 项目 

    1. location ^~ /api/ {
    2. root html;
    3. index index.html index.htm;
    4. proxy_pass http://localhost:8080/;
    5. proxy_redirect 80 83;
    6. }

    localhost:8080 对应的服务 

    1. @RestController
    2. @RequestMapping("/HelloWorld")
    3. public class HelloWorldController {
    4. @Resource
    5. private UserService userService;
    6. @GetMapping("/listFormWithoutHeader")
    7. public List<JSONObject> listFormWithoutHeader(
    8. String param01, String param02
    9. ) {
    10. List<JSONObject> result = new ArrayList<>();
    11. result.add(wrapEntity("param01", param01));
    12. result.add(wrapEntity("param02", param02));
    13. userService.list();
    14. return result;
    15. }
    16. // wrapEntity
    17. public JSONObject wrapEntity(String name, String age) {
    18. JSONObject result = new JSONObject();
    19. result.put("name", name);
    20. result.put("age", age);
    21. return result;
    22. }
    23. }

    直接请求 localhost:8080 的服务, 服务通畅 

    通过 nginx 代理访问

    我们这里关注的流程如下 

    1. 客户端请求 nginx, nginx 拿到请求之后添加了一个 ngx_http_wait_request_handler 的事件处理 

    2. ngx_http_wait_request_handler 中查询 location, 创建代理请求, 发送代理请求到 upstream 

    3. upstream 拿到请求处理之后, 响应结果给 nginx, nginx 拿到结果之后 处理之后响应给客户端 

    1. 客户端请求 nginx, nginx 拿到请求之后添加了一个 ngx_http_wait_request_handler 的事件处理 

    看一下 accept 中, 对方客户端的 ip 是 127.0.0.1, 对方客户端端口是 "-54 51" = 0xca33 = 51763 

    查看一下 建立的连接, 这里 51763 这个 tcp 连接对应的就是 浏览器访问和 nginx 创建的连接 

    进程为 474 对应的 chrome 进程创建的连接 

    1. ^Cmaster:target jerry$ lsof -i:80
    2. COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    3. SogouInpu 388 jerry 22u IPv4 0x9710be4129a54d89 0t0 TCP 192.168.0.104:51827->49.7.115.35:http (ESTABLISHED)
    4. Google 474 jerry 29u IPv4 0x9710be4129a55711 0t0 TCP localhost:51763->localhost:http (ESTABLISHED)
    5. WeChat 665 jerry 200u IPv4 0x9710be41340f6a79 0t0 TCP 192.168.0.104:51213->113.96.209.106:http (ESTABLISHED)
    6. nginx 2816 jerry 3u IPv4 0x9710be412c1b6d89 0t0 TCP localhost:http->localhost:51763 (ESTABLISHED)
    7. nginx 2816 jerry 8u IPv4 0x9710be413458ba79 0t0 TCP *:http (LISTEN)
    8. nginx 2821 jerry 8u IPv4 0x9710be413458ba79 0t0 TCP *:http (LISTEN)
    9. ?\x98? 6652 jerry 25u IPv4 0x9710be4128f8b711 0t0 TCP 192.168.0.104:51521->118.112.225.41:http (CLOSE_WAIT)

    然后 accept 之后, 向事件队列中抛了一个事件, 来处理当前连接的读取事件 

    handler 是 ngx_http_wait_request_handler

    2. ngx_http_wait_request_handler 中查询 location, 创建代理请求, 发送代理请求到 upstream 

    这里是从客户端的连接中读取数据, 请求信息如下, 看这个 b->start  

    在解析了客户端的请求行, 请求头之后, 会处理客户端请求 

    我们的这里的 upstream 的场景, 会被 ngx_http_core_content_phase 处理

    ngx_http_core_content_phase 中有一个 ngx_http_proxy_handler, 来和 upstream 创建连接, 创建代理请求, 发送代理请求 

    如下便是和 upstream 创建链接之前, 创建代理请求, 在之前的一部分文章中也提到过 

    如下这里是 和 upstream 创建 tcp 连接, 这里的 pc 的主机是 127.0.0.1, 端口是 "31 -112" = 0x1f90 = 8080 

    如下地方是 发送代理请求到 upstream, 可以看见该处理的地方已经处理过了 

    3. upstream 拿到请求处理之后, 响应结果给 nginx, nginx 拿到结果之后 处理之后响应给客户端 

    upstream 响应结果之后 使用 ngx_http_upstream_handler 处理响应, nginx 拿到响应的地方如下 

    这里可以看到 upstream 响应的 http 响应

    可以看到的是 nginx 还对响应做一定程度的处理, 比如响应头中 location 的替换, 增加 Server 响应头, 增加其他自定义响应头 等等

    c, connection 响应头的处理

    看一下对方客户端的信息, 对方客户端的 ip 是 127.0.0.1, 对方客户端端口是 "-54 51" = 0xca33 = 51763 

    比如这里增加了一个 Server 的响应头的处理 

    请求 nginx 所在服务器的静态资源

     看一下 accept 中, 对方客户端的 ip 是 127.0.0.1, 对方客户端端口是 "-50 101" = 0xce65 = 52837 

    然后 accept 之后, 向事件队列中抛了一个事件, 来处理当前连接的读取事件 

    handler 是 ngx_http_wait_request_handler

    查看一下 建立的连接, 这里 52837 这个 tcp 连接对应的就是 浏览器访问和 nginx 创建的连接 

    进程为 474 对应的 chrome 进程创建的连接 

    1. master:target jerry$ lsof -i:80
    2. COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    3. Google 474 jerry 48u IPv4 0x9710be412ee46d89 0t0 TCP localhost:52837->localhost:http (ESTABLISHED)
    4. Google 474 jerry 51u IPv4 0x9710be4129ae5a79 0t0 TCP localhost:52839->localhost:http (ESTABLISHED)
    5. WeChat 665 jerry 200u IPv4 0x9710be41340f6a79 0t0 TCP 192.168.0.104:51213->113.96.209.106:http (ESTABLISHED)
    6. nginx 2816 jerry 3u IPv4 0x9710be412f84d401 0t0 TCP localhost:http->localhost:52837 (ESTABLISHED)
    7. nginx 2816 jerry 8u IPv4 0x9710be413458ba79 0t0 TCP *:http (LISTEN)
    8. nginx 2821 jerry 8u IPv4 0x9710be413458ba79 0t0 TCP *:http (LISTEN)
    9. ?\x98? 6652 jerry 25u IPv4 0x9710be4128f8b711 0t0 TCP 192.168.0.104:51521->118.112.225.41:http (CLOSE_WAIT)

    这里是从客户端的连接中读取数据, 请求信息如下, 看这个 b->start  

    这里可以看到的是 这里的 http_content_phase 处理阶段, 已经到了 ngx_http_static_handler, 来处理静态资源  

    这里将 请求 映射到了 "/usr/local/nginx/html/index.html", 然后这个 handler 会响应这个文件的相关信息给客户端 

    nginx 将文件内容响应给客户端 

    完  

  • 相关阅读:
    项目经验3
    抖音直播招聘报白企业人力资源公司多渠道展示职位
    【消息队列笔记】chp3-如何确保消息不丢失
    举例说明计算机视觉(CV)技术的优势和挑战
    @Override 的作用
    SAP MM学习笔记35 - 请求书照合中的差额处理(发票扣减,受入)
    JS高级(二):继承、数组的一些api、Object.defineProperty()、call、apply、bind
    【物理】斜面交点之处机械能/动量损失问题
    Serverless Devs 重大更新,基于 Serverless 架构的 CI/CD 框架:Serverless-cd
    网络安全/渗透测试工具AWVS14.9下载/使用教程/安装教程
  • 原文地址:https://blog.csdn.net/u011039332/article/details/125711333