Nginx 究竟如何处理事件?
在了解了网络事件以及事件分发、收集器以后,让我们来了解 Nginx 是怎么样处理事件的!
Nginx 事件循环
当 Nginx 刚刚启动时,在等待事件部分,也就是打开了 80 或 443 端口,这个时候在等待新的事件进来,比如新的客户端连上了 Nginx 向我们发起了连接,此步往往对应 epoll 的 epoll wait 方法,这个时候的 Nginx 其实是处于 sleep 这样一个进程状态的。当操作系统收到了一个建立 TCP 连接的握手报文时并且处理完握手流程以后,操作系统就会通知 epoll wait 这个阻塞方法,告诉它可以往下走了,同时唤醒 Nginx worker 进程。
接着往下走之后,会去找操作系统索要要事件,操作系统会把他准备好的事件,放在事件队列中,从这个事件队列中可以获取到需要处理的事件。比如建立连接或者收到一个 TCP 请求报文。
取出以后就会进行循环处理事件,如上就是处理事件的一个循环:当发现队列中不为空,就把事件取出来开始处理事件;在处理事件的过程中,可能又生成新的事件,比如说发现一个连接新建立了,可能要添加一个超时时间,比如默认的 60 秒,也就是说 60 秒之内如果浏览器不向 Nginx 发送请求的话,Nginx 就会把这个连接关掉;又比如说当 Nginx 发现已经收完了完整的 HTTP 请求以后,可以生成 HTTP 响应了,那么这个生成响应是需要 Nginx 可以向操作系统的写缓存中心里面去把响应写进去,要求操作系统尽快的把这样一段响应内容发到浏览器上,也就是说可能在处理过程中可能会产生新的事件,就是循环处理事件部分指向的事件队列部分,等待下一次来处理。
如果所有的事件都处理完成以后呢,又会返回到等待事件部分。
在学习了 Nginx 事件循环后,我们再去理解有时候使用一些第三方模块,这些第三方模块可能会做大量的 CPU 运算,这样的计算任务会导致处理一个事件的时间非常的长;在上面的一个流程图中,可以看到会导致队列中的大量事件会长时间得不到处理,从而引发恶性循环,也就是他们的超时时间可能到了;大量的 CPU、Nginx 的任务都消耗在处理连接不正常的断开,所以 Nginx 不能容忍有些第三方模块长时间的消耗大量的 CPU 进行计算任务就是这样一个原因。我们可以看到像 GZIP 这样的模块,他们都不会在一次使用大量的 CPU 而是分段使用,这些都与 Nginx 的事件循环有关的。
总结
本篇文章主要讲解了 Nginx 是如何处理事件的以及 Nginx 事件循环的流程是怎么样的,为下一步讲解 Nginx 事件循环流程中是如何从操作系统中获取等待处理的事件做铺垫,并且通过事件循环了解到为什么 Nginx 不期望第三方模块中出现大量 CPU 的计算任务。
完
●浅析 Nginx 网络事件
●一篇文章带你了解 ZooKeeper 架构
●ZooKeeper 入门看这篇就够了
●你真的了解 volatile 关键字吗?
●Java中Set集合是如何实现添加元素保证不重复的?
●一条SQL查询语句是如何执行的?
武培轩
有帮助?在看,转发走一波
喜欢作者
- Nginx 究竟如何处理事件?
- Nginx 究竟如何处理事件?
- Nginx 究竟如何处理事件?
- Nginx 究竟如何处理事件?
- 文章6:Nginx中的Epoll事件处理机制
- 如何取得某个菜单所绑定的所有事件处理程序
- Nginx 之三:nginx服务器模块、web请求处理机制及事件驱动模型、进程功能和进程间通信
- 如何正确地在React中处理事件
- Nginx 是如何处理 HTTP 头部的?
- Nginx源码结构及如何处理请求
- JQuery中如何处理键盘事件
- nginx如何统一处理监听套接字
- VC中如何处理CEDIT的KEYDOWN事件
- delphi如何在form显示出来后处理指定的事件(例如自动登录)
- Nginx的事件处理机制
- Android 组件学习【启发】 如何处理好多个组件的多个事件 收藏
- 下面的示例演示如何使用传递到事件处理方法的 GridViewCommandEventArgs 对象确定引发事件的按钮的命令名。
- 如何获得对窗体移动事件的处理的一个方法
- 如何使keyup事件延迟处理
- 从某汉理工某攀老师事件谈如何“孤立处理”和保护自己