Nginx是一个事件驱动的框架。事件主要是指网络事件。Nginx的每一个网络连接对应两个网络事件,一个读,一个写。在了解Nginx的各种原理和处理一些极端场景下的错误场景时,首先需要了解什么是网络事件。网络传输接下来看上图。比如主机A是家里的一台笔记本电脑,主机B是一台运行Nginx服务的服务器。从主机A向主机B发送一个HTTPGET请求,这个过程中有哪些主要事件?从上图的数据流向部分可以看出:在应用层发送一个GET请求->到传输层,这一步主要是浏览器打开一个端口,在Windows中可以看到任务管理器。它会把这个端口和Nginx开放的端口,比如80或者443记录到传输层。->然后在网络层,我们会记录我们主机和目标主机的IP,也就是Nginx所在服务器的公网IP->到达链路层后->通过以太网->到达routerathome(网络层),在家里路由器会记录下运营商的一些IP->通过广域网->跳转到主机B所在的机器->报文会经过链路层->网络层->到传输层,而在传输层操作系统知道是那个进程为那个进程开了80或者443。这个过程自然是Nginx->然后Nginx会在它的HTTP状态处理器(应用层)中处理这个请求。网络消息在上述过程中起到什么作用呢?TCP流和报文数据链路层会在数据前面的Header和Footer部分加上源MAC地址和源-目的地址->在网络层,是Nginx的公网地址(目的IP地址)和浏览器的公网地址(源IP地址)->到达TCP层(传输层)时,Nginx打开的端口(目的端口)和浏览器打开的端口(源IP地址)为指定端口)->然后应用层是HTTP协议。这是一个消息,也就是说我们发送的HTTP协议会被切割成很多小的消息,在网络层会被切割成MTU,以太网的每个MTU是1500字节;在TCP层(传输层)会考虑中间每条链路中最大的MTU值。这时,每条消息通常只有几百个字节。这个消息大小叫做MSS,所以每次收到MSS小于这个大小的消息,其实就是一次网络事件。这个时候我们来看看TCP协议中有多少事件是和我们日常调用的一些接口(比如Accept、Read、Write、Close)相关的?TCP协议和非阻塞接口请求建立TCP连接事件其实上面就是发送了一个TCP报文,通过上面第二部分讲解的流程到达Nginx,对应read事件。因为对于Nginx来说,我读了一条消息,所以是Accept连接建立事件。如果是TCP连接可读事件,说明有消息发送,对于Nginx来说也是read事件,即Read读取消息。如果对端(即浏览器)主动关闭,相当于Windows操作系统会发送事件请求关闭链接。对于Nginx来说,它仍然是一个读取事件,因为它只是读取一条消息。.那么什么是写事件呢?当我们的浏览器需要向浏览器发送响应时,它需要将消息写入操作系统,要求操作系统将其发送到网络。这是一个写事件。一些像这样的网络读写事件,一般在Nginx或者任何异步事件处理框架中,他都会有个东西叫事件收集器和分发器。每一类事件处理的消费者都会被定义,也就是说事件是一个生产者,通过网络在我们的Nginx中自动产生,我们需要为每一类事件建立一个消费者。比如连接建立事件消费者调用Accept,HTTP模块会建立一个新的连接。还有很多读取或写入消息,在HTTP状态机,即每个消费者进程中,不同的时间段会调用不同的方法。上面是一个事件分发和消费者,包括异步读写磁盘事件等AIO,以及是否超时(worker_shutdown_timeout)等定时器事件。上面的Nginx网络事件示例介绍了网络数据包的发送以及Nginx中对应的网络事件。例如,当Accept建立一个新的连接时,它实际上接收到一个读事件。下面我们通过抓包来分析三次握手是如何建立的。Nginx接收到read事件,使用的抓包工具是Wireshark。首先我们安装Wireshark软件,抓取Nginx所在的IP和端口,然后访问页面。TCP层主要有两件事:?浏览器会先打开这个页面,本地打开一个1875端口,Nginx启动的是8080端口。?TCP层主要做进程间的通信。IP层主要解决机器之间如何相互发现的问题。三向握手的意思是windows先发一个[SYN]给Nginx,然后Nginx所在的服务器也会发一个[SYN]给windows。这个时候Nginx是感知不到的,因为连接还处于半开状态。.直到这台windows服务器再次向Nginx所在的服务器发送[ACK],Nginx所在的操作系统就会通知Nginx我们收到了一个read事件,对应建立了一个新的连接,所以此时Nginx的Accept应该调用方法来建立新的连接。上面我们已经演示了正常的三次握手是如何通过Wireshark抓包触发读事件,让Nginx处理这样的读事件来建立新连接的。小结本文主要讲解网络事件,通过抓包分析Nginx网络事件,对我们理解Nginx的异步处理框架,包括OpenResty也是非常有帮助的,OpenResty也是强依赖网络事件和事件分发的。
