Nginx学习笔记之网络收发与Nginx事件间的对应关系
分类:
文章
•
2024-06-30 15:12:34
网络收发与Nginx事件间的对应关系
-
Nginx是一个事件驱动的框架
- 所谓事件,主要指的是网络事件。
-
Nginx每个连接,会自然对应两个网络事件,一个读事件,一个写事件。所以,我们在深入了解Nginx各种原理以及在极端情况下一些错误场景的处理时,必须首先理解什么是网络事件。

- 如图,比如主机A就是我们家里的一台笔记本电脑,主机B就是我们的服务器,上面跑着Nginx。
- 从主机A发送一个http的get请求,发送到主机B,这样一个过程中究竟经历了哪些网络事件呢?如在下面数据流层。

- 应用层里我们发送了一个get请求
- 到了传输层了它主要在做一件事情,就是我们的浏览器打开了一个端口,从Windows的任务管理器里可以看到这一点,然后它会把这个端口记下来以及把Nginx打开的端口比如80,443也记到传输层
- 然后在网络层会记录下我们主机所在的IP和目标主机也就是Nginx服务器的公网IP
- 之后到链路层以后,经过以太网到达我们家的路由器,我们家的路由器里会记录下我们所在的运营商一些下一段的IP,通过广域网以后,跳转到主机B所在的机器中,这时候报文会通过链路层,网络层到传输层,经过传输层以后操作系统就知道是给那个打开了80或者443的进程,这个进程是Nginx。
-
Nginx在它的HTTP状态处理机里面,应用层里面处理这个请求。在这样一个过程中,网络报文扮演了一个怎样的角色?我们看一下TCP的报文。

- 比如数据链路层,会在数据的前面和尾部添加源和目的的MAC地址,到了网络层则是我们Nginx的公网地址和我们浏览器的公网地址,到了TCP层,指定了Nginx打开的端口和我们浏览器打开的端口,应用层就是我们http协议。那么这就是一个报文。
- 我们发送http协议,它会被切割成很多小的报文,在网络层会切割掉MTU,以太网每个MTU是1500字节,在TCP层,它会考虑中间每个环节最大的一个MTU值。这个时候,往往我们每个报文只有几百字节。这个报文大小我们称为MSS。所以每收到一个MSS小于这么大小的一个报文时,其实就是一个网络事件。
- 这个时候我们再看一看TCP协议中许多事件是怎样和我们日常调用一些接口,比如accept,read,write,close这些事件是怎样关联在一起的。

- 比如请求建立TCP连接事件实际上是发送了一个TCP 的报文,通过之前讲的流程到达了Nginx,它其实是一个读事件。因为对Nginx来说,我读取了一个报文,所以就是Accept建立连接的事件。
- 如果是TCP连接可读事件,我们发送了一个消息对Nginx也是一个读事件,就是Read读消息。
- 如果是对端,也就是我们浏览器主动地关掉了,相当于Windows操作系统会去发送一个要求关闭连接的一个事件。对应Nginx来说,还是一个读事件,它只是去读取一个报文。
- 什么样是写事件呢?
- 当我们的Nginx需要向浏览器发送我们的响应的时候,我们需要把消息写到我们的操作系统中,要求操作系统发到网络中,这就是一个写事件。
- 像这样一些网络中的读写事件,通常在Nginx中, 在任何一个异步事件处理框架中,它会有一个东西叫做事件收集分发器。
- 我们会定义每一类事件它处理的消费者。也就是说事件是一个生产者,是通过网络中自动生产到我们的Nginx中的,我们对每种事件要建立一个消费者。
- 比如连接建立的事件消费者,就是我们对accept调用,http模块就会去建立一个新的连接。
- 还有很多读消息或者写消息在HTTP状态机中不同的时间段我们会调用不同的方法也就是每一个消费者去处理。
- 以上就是一个事件分发消费器,包括AIO像异步读写磁盘的事件还有我们的定时器事件,比如说我们是否超时(上面提到worker_shutdown_timeout),也有相应的消费者。