nginx 是一个基于事件驱动的框架,其核心事件主要是网络事件。每个网络连接在 nginx 中会触发两个事件:一个是读事件,另一个是写事件。为了深入理解 nginx 的各种原理以及在极端场景下的错误处理,我们需要首先掌握网络事件的概念。
网络传输
让我们来看这张图,假设主机 A 是一台家用笔记本电脑,而主机 B 是一台运行 Nginx 服务的服务器。当主机 A 向主机 B 发送一个 HTTP GET 请求时,这个过程中会经历哪些事件呢?从图中的数据流部分可以看出:
应用层会发送一个 GET 请求 -> 传输层的主要任务是浏览器打开一个端口,这在 Windows 任务管理器中可以看到,浏览器会记录这个端口以及 Nginx 打开的端口(如 80 或 443) -> 网络层会记录主机的 IP 地址和目标主机(即 Nginx 服务器)的公网 IP -> 然后进入链路层 -> 通过以太网 -> 到达家用路由器(网络层),家用路由器会记录运营商的下一跳 IP -> 通过广域网 -> 到达主机 B -> 报文会经过链路层 -> 网络层 -> 传输层,操作系统会识别出是哪个进程(Nginx)打开了 80 或 443 端口 -> Nginx 在其 HTTP 状态机(应用层)中处理这个请求。
在上述过程中,网络报文扮演了什么角色呢?
TCP流与报文
数据链路层会在数据的 Header 和 Footer 部分添加源 MAC 地址和目标 MAC 地址 -> 网络层会使用 Nginx 的公网地址(目标 IP 地址)和浏览器的公网地址(源 IP 地址)-> 传输层(TCP 层)会指定 Nginx 打开的端口(目标端口)和浏览器打开的端口(源端口)-> 应用层则是 HTTP 协议。
这就是一个报文,也就是说我们发送的 HTTP 协议会被分割成许多小的报文。在网络层,这些报文被称为 MTU,以太网的每个 MTU 是 1500 字节;在传输层(TCP 层),会考虑中间每个环节中最大的 MTU 值,通常每个报文只有几百字节,这个报文大小称为 MSS。因此,每次接收到一个小于 MSS 大小的报文时,就是一个网络事件。
接下来,我们来看 TCP 协议中的许多事件是如何与我们日常调用的一些接口(如 Accept、Read、Write、Close)关联在一起的?
TCP 协议与非阻塞接口
请求建立 TCP 连接的事件实际上是发送了一个 TCP 报文,通过上述流程到达 Nginx,对应的是读事件。因为对于 Nginx 来说,读取到一个报文就是 Accept 建立连接事件。
如果是 TCP 连接可读事件,就是发送了一个消息,对于 Nginx 也是一个读事件,即 Read 读消息。
如果是浏览器主动关闭连接,相当于 Windows 操作系统会发送一个请求关闭连接的事件,对于 Nginx 来说仍然是一个读事件,因为它只是读取一个报文。
那么什么是写事件呢?当 Nginx 需要向浏览器发送响应时,需要将消息写入操作系统中,要求操作系统发送到网络中,这就是一个写事件。
像这样的网络读写事件,通常在 Nginx 或任何异步事件处理框架中,会有一个称为事件收集和分发器的机制。它会定义每类事件的处理消费者,也就是说事件是一个生产者,通过网络自动生成到 Nginx 中,我们需要为每种事件建立一个消费者。例如,连接建立事件的消费者会调用 Accept,HTTP 模块会建立一个新的连接。还有许多读消息或写消息的事件,在 HTTP 状态机的不同时间段会调用不同的方法,即每个消费者处理。
以上就是浅析 Nginx 网络事件的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号