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流与报文

数据链路层会在数据的前面 Header 部分和 Footer 部分添加上源 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 中的,我们要对每种事件建立一个消费者。比如连接建立事件消费者,就是对 Accept 调用,HTTP 模块就会去建立一个新的连接。还有很多读消息或者写消息,在 HTTP 状态机中不同的时间段会调用不同的方法也就是每个消费者处理。

以上就是一个事件分发、消费器,包括 AIO 像异步读写磁盘事件,还有定时器事件,比如是否超时(worker_shutdown_timeout)。

Nginx 网络事件实例

上面介绍了网络报文的发送以及对应的 Nginx 中的网络事件,比如 Accept 建立一条新连接其实是收到一条读事件,接下来我们通过抓包来分析建立三次握手时时怎么样让 Nginx 收到读事件,使用的抓包工具是 Wireshark。

首先我们安装 Wireshark 软件,并对 Nginx 所在 IP 和端口进行抓包,然后访问页面,在 TCP 层主要说两件事情:

  • 浏览器首先会打开这个页面,本地打开了一个 1875 端口,而 Nginx 启动的是 8080 端口。
  • TCP 层主要做的是进程与进程之间通讯这件事。

IP 层主要解决机器与机器之间怎样互相找到的问题。

三次握手也就是 windows 先向 Nginx 发送了一次 [SYN],那么相反的 Nginx 所在的服务器也会向 windows 发送一个 [SYN],这个时候 Nginx 是没有感知到的,因为这个连接还是处于半打开的状态。直到这台 windows 服务器再次发送 [ACK] 到 Nginx 所在的服务器之上时,Nginx 所在的操作系统才会去通知 Nginx 我们收到了一个读事件,这个读事件对应是建立一个新连接,所以此时 Nginx 应该调用 Accept 方法去建立一个新的连接。

以上我们通过 Wireshark 抓包演示了正常的三次握手是怎么样引发一个读事件来使得 Nginx 去处理这样一个读事件来建立新的连接的。

总结

这篇文章主要讲解了网络事件,并通过抓包来分析 Nginx 网络事件,这对我们理解 Nginx 异步处理框架是非常有帮助的,包括 OpenResty 也是强依赖于网络事件以及事件分发的。

浅析 Nginx 网络事件的更多相关文章

  1. Nginx 网络事件

    L27-29 应用层(如浏览器等一系列组成的发送get请求) 传输层 系统内核打开一个端口将客户端IP及端口和服务端IP及端口记录下来一并传输到网络层 网络层 打包后到链路层 再到客户端路由器至广域网

  2. 利用epoll写一个"迷你"的网络事件库

    epoll是linux下高性能的IO复用技术,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率.另一点原因就是获取 ...

  3. Nginx的事件循环

    首先事件循环的起点就是监听端口获取连接,我们可以在ngx_event_core_module模块的ngx_event_process_init函数中看到如下的代码: /* for each liste ...

  4. 一次VLAN标签引发的网络事件的处置

    一次VLAN标签引发的网络事件的处置 一.背景介绍 事件背景: HZ某分公司新装一套业务系统,通过一条专线和BJ总公司连通.分配给HZ公司的ip地址为:a.b.c.X,掩码24位,网关a.b.c.1. ...

  5. [日常]nginx与网络事件模型

    Nginx 的特点: 1.处理静态文件 2.反向代理加速 3.fastCGI,简单的负载均衡和容错 4.模块化的结构 5.分阶段资源分配技术,使得它的 CPU 与内存占用率非常低,保持 10,000 ...

  6. 【Nginx】事件和连接

    不同的操作系统相应不同的事件驱动机制.在Linux 2.6之后使用epoll机制.相应的事件驱动模块是ngx_epoll_module.Nginx的ngx_event_core_module模块依据操 ...

  7. Nginx网络负载均衡,负载均衡,网络负载,网络均衡

    本节就聊聊采用Nginx负载均衡之后碰到的问题: Session问题 文件上传下载 通常解决服务器负载问题,都会通过多服务器分载来解决.常见的解决方案有: 网站入口通过分站链接负载(天空软件站,华军软 ...

  8. Nginx网络压缩 CSS压缩 图片压缩 JSON压缩

    一.序言 使用Nginx作为web应用服务时,会代理如下常见文件:js.css.JSON.图片等,本文提供基于Nginx内置的压缩技术,提供网络请求响应速度的解决方案. 1.网络压缩原理 网络压缩的原 ...

  9. 浅析nginx的负载均衡

    Nginx 的 HttpUpstreamModule 提供对后端(backend)服务器的简单负载均衡.一个最简单的 upstream 写法如下: upstream backend { server ...

随机推荐

  1. 2019-3-13-win10-uwp-使用-ScaleTransform-放大某个元素

    title author date CreateTime categories win10 uwp 使用 ScaleTransform 放大某个元素 lindexi 2019-3-13 19:5:56 ...

  2. js原生复习2.0

    // 1.闭包的作用// 实现共有变量,函数累加器的实现// 可以做缓存以及储存结构// 可以实现封装,实现属性私有化// 模块开发,防止全局污染// var name = 123;// var in ...

  3. TCP之单项通信

    TestServer.java package com.sxt.tcp; /* * 服务端 */ import java.io.DataInputStream; import java.io.IOEx ...

  4. 模板—扩展GCD*2

    有必要重新学一下扩展GCD emmmm. 主要是扩展GCD求解线性同余方程$ax≡b (mod p)$. 1.方程有解的充分必要条件:b%gcd(a,p)=0. 证明: $ax-py=b$ 由于求解整 ...

  5. 17-3 cookie和session

    一 . Cookie 1.cookie 是什么? 保存在浏览器端的键值对! 服务端在返回响应的时候,告诉浏览器保存的键值对!浏览器可以拒绝保存Cookie. 2. 为什么要有cookie? HTTP请 ...

  6. hdu 3938 Portal (prim+离线)

    Problem - 3938 题意是要求出给定权值下,满足要求的点对的数目.所谓的要求是,给出两点,之间会有很多路径,这个点对的最小距离是众多路径中,最短的一条路径的长度,路径长度是路径上最长边的长度 ...

  7. DTCC 2019 | 深度解码阿里数据库实现 数据库内核——基于HLC的分布式事务实现深度剖析

    摘要:分布式事务是分布式数据库最难攻克的技术之一,分布式事务为分布式数据库提供一致性数据访问的支持,保证全局读写原子性和隔离性,提供一体化分布式数据库的用户体验.本文主要分享分布式数据库中的时钟解决方 ...

  8. 关于心跳ajax请求pending状态(被挂起),stalled时间过长的问题。涉及tcp连接异常。

    环境:景安快云服务器(听说很垃圾,但是公司买的,我也刚来),CentOS-6.8-x86_64,Apache,MySQL5.1,PHP5.3. 问题:现公司有一个php系统,需要重复向后台发送ajax ...

  9. Python 的经典入门书籍

    实python非常适合初学者入门,上手很容易.我就是完全通过网上资源学了python的.最大的是3点经验:1.找一本浅显易懂,例程比较好的教程,从头到尾看下去.不要看很多本,专注于一本.把里面的例程都 ...

  10. JavaScript跨域问题

    通过实现Ajax通信的主要限制,来源于跨域安全策略.默认情况下,XHR对象只能访问与包含它的页面位于同一个域中的资源.这种安全策略可以预防某些恶意行为.但是,实现合理的跨域请求对于开发某些浏览器应用程 ...