View on GitHub

我的极简博客

记录学习与生活

第一阶段:从浏览器到服务器机房(网络传输层)

  1. UI/浏览器处理

    • 解析:浏览器解析URL协议(HTTP/HTTPS)、Host(域名)、端口和API路径。
    • 封装:将上述信息封装成HTTP/HTTPS Request请求。
    • DNS解析

      • 先查本地缓存和hosts文件。
      • 若无,向DNS服务器发起请求,获取目标服务器IP。

        默认自动获得IP地址和DNS服务器地址,使用DHCP协议由ISP分配

    • 路由与NAT

      • 请求经过本地网关和路由器。
      • NAT将用户的私有IP转换为公网IP,以便服务器回包时能找到路径。
      • 经过ISP的骨干网路由跳转,最终定位到目标服务器所在的机房。
  2. 机房入口

    • 防火墙:根据策略对流量进行拦截(丢弃、拒绝)或放行。

第二阶段:服务器硬件与操作系统层(内核层)

  1. 网卡接收(NIC)

    • 物理层:通过光纤接收物理信号。

    • 数据链路层:网卡检查以太网帧中的目标MAC地址,匹配本机MAC则接收。

    • DMA技术(关键点):网卡使用直接内存访问(DMA)技术,不消耗CPU资源,直接将数据写入内存中的环形缓冲区(Ring Buffer/Rx Ring)

      当I/O设备要进行数据传送时,通过DMA控制器 ( 多数外设已内置,PCH或SoC中亦有保留 ) 向CPU提出DMA传送请求, CPU响应之后将让出系统总线,由DMA控制器接管总线进行数据传送。

      DMA的流程包括预处理、数据传送和后处理,整个数据块的传送过程都不需要 CPU 参 与 , CPU 只在最初的 DMA控制器初始化和最后的 DMA 结束处理时才介入 。

      为保证降低CPU负载同时高速数据流零拷贝、不间断、不丢失,DMA利用硬件上的“循环模式(Circular Mode)”配合内存中的“环形缓冲区”实现永不停歇的数据接收,

  2. 中断处理

    • 硬中断:网卡向CPU发送硬中断信号,CPU暂停当前任务。硬中断作用是快速响应,并防止中断风暴。
    • 软中断:硬中断触发软中断,异步进行耗时的数据解析工作(从上下文剥离数据、协议栈处理),防止CPU长时间被占用,CPU以轮询(Polling)方式批量处理Ring中有所有权的数据,消费完成后分配新缓冲并回填到Ring中(将所有权交还DMA),最后重新开启中断等待下一轮触发

    中断分为外中断或狭义的中断和内中断/异常。

    外中断是由外部硬件设备(如键盘、网卡、磁盘控制器)或内部逻辑(如CPU定时器)发出的信号。

    内中断由CPU在执行特定指令或遇到特定条件时触发。

    外中断又可分为可屏蔽中断(可通过改变屏蔽字实现多重中断)和不可屏蔽中断(通常是严重的硬件故障)。

    内中断可分为故障(指令执行异常,可修复后返回到产生故障的指令重新执行),自陷(有意的异常,通常用于调试或系统调用)和终止(使cpu无法继续执行的硬件故障,如存储器校验错误)

    外中断和终止属于硬件中断,故障和自陷属于软件中断。

    Linux为了提高处理效率,将中断处理过程分为了硬中断/上半部软中断/下半部

    上半部 (Top Half) = 硬中断:直接响应硬件信号,做最少、最紧急的工作。

    下半部 (Bottom Half) = 软中断/Tasklet/工作队列:处理耗时的数据操作,延迟执行。

  3. TCP协议栈处理

    • 三次握手

      1. 客户端发SYN包。

      2. 服务端回SYN+ACK包,将连接存入半连接队列

        半连接队列提供有状态服务,记录正确的协商信息并避免冗余或历史连接的建立,同时提供安全防护:通过限制队列长度,防止瞬间过多的请求撑爆内存,队列爆满后第二次握手报文需要结合 SYN Cookies,但会导致资源消耗转移到了CPU,为状态信息而舍弃部分高级特性,并使防火墙的一些规则失效。

      3. 客户端回ACK包,服务端收到后将连接移入全连接队列

      TCP是全双工的可靠通信协议,而在不可靠的网络上要实现可靠通信就需要使用确认机制,使用SYN同步报文和ACK确认报文建立连接,确保通信双方的数据发送和接受能力正常,第一次握手和第二次握手建立客户端到服务器的连接,第二次握手和第三次握手建立服务器和客户端的连接。第二次握手复用了确认报文和同步报文,同时第三次握手也可以携带数据。

    • Socket缓冲:TCP层通过请求的Host/Port在内核Socket哈希表中找到对应的Socket Structure,将Payload(剥离了TCP头部之后的业务数据)放入该Socket对应的接收缓冲区(Receive Buffer)

      socket哈希表的key为(源IP地址,源端口,目的IP地址,目的端口,传输层协议)

      socket structure记录这个连接的所有状态信息(是否已建立连接、拥塞窗口大小、超时时间等),以及缓冲区指针

第三阶段:从Tomcat容器到Java应用(应用层)

  1. Tomcat 线程模型

    • Poller线程:通过epoll机制监听Socket缓冲区。一旦发现有数据可读,将Socket封装成SocketProcessor对象。
    • 任务队列:Poller将SocketProcessor提交到任务队列(Task Queue)。
    • 工作线程池(Worker Threads):工作线程从Waiting状态被唤醒,从队列中取出Processor并执行run方法。

    tomcat的connector组件负责网络通信、应用层协议解析和Request/Response的转化。

    连接器用 ProtocolHandler 接口来封装通信协议和 I/O 模型的差异。ProtocolHandler 内部又分为 EndPoint 和 Processor 模块,EndPoint 负责底层 Socket 通信,默认使用NIO模式,采用Reactor线程模型。

  2. 进入JVM

    • 数据拷贝:工作线程将数据从内核缓冲区复制到JVM内存(Heap/Direct Memory)
    • 协议解析:解析HTTP报文(头、行、体),封装成标准的HttpServletRequestHttpServletResponse对象。

    连接器中的Proccesor 负责应用层协议解析,从SocketChannel读取字节流到ByteBuffer并解析为tomcat request对象。然后连接器通过适配器 Adapter 将tomcat request/response对象包装成servlet request/response对象传递给容器(该设计是容器不需要关心具体协议)。

  3. Spring MVC / Spring Boot 处理流程

    • Filter Chain:请求经过一系列过滤器(责任链模式)。

      一个 Tomcat 实例(Server)可以包含多个 Service,而一个 Service 包含多个 Connector 和一个 Container(Engine)。

      Tomcat 设计了 4 种容器,分别是 Engine、Host、Context 和 Wrapper。

      • Engine - Servlet 的顶层容器,包含一 个或多个 Host 子容器;
      • Host - 虚拟主机,负责 web 应用的部署和 Context 的创建;
      • Context - Web 应用上下文,包含多个 Wrapper,负责 web 配置的解析、管理所有的 Web 资源;
      • Wrapper - 最底层的容器,是对 Servlet 的封装,负责 Servlet 实例的创 建、执行和销毁

      每个容器层级(Engine, Host, Context, Wrapper)都有自己的 Pipeline。请求像水流一样流过管道,途经一个个 Valve(阀门,用于做拦截、鉴权、日志等),最后到达底层的 Servlet 执行业务逻辑。

    • DispatcherServlet:前端控制器入口。
    • HandlerMapping:根据URL找到对应的Controller和Method(@RequestMapping)。
    • HandlerInterceptor:执行拦截器的preHandle方法(权限校验等)。
    • HandlerAdapter

      • 解析参数(@RequestParam, @PathVariable)。
      • 对象转换:处理@RequestBody,将JSON数据反序列化为Java对象。
    • 业务执行:调用Controller -> Service -> DAO,执行Java业务逻辑。
  4. 响应返回(Return)

    • ReturnValueHandler:处理方法的返回值。
    • MessageConverter:处理@ResponseBody,将Java对象序列化(如转为JSON字节流)。
    • 写入响应:将数据写入HttpServletResponse的输出流。
    • 后置处理:执行拦截器的postHandle
    • 回流:数据沿原路返回(JVM -> 内核Socket发送缓冲区 -> 网卡 -> 网络 -> 客户端)。