• Nginx的事件处理机制


    Nginx的事件处理机制:
    对于一个主要的webserver来说,事件通常有三种类型,网络事件、信号、定时器。

     
    首先看一个请求的基本过程:建立连接---接收数据---发送数据 。
    再次看系统底层的操作 :上述过程(建立连接---接收数据---发送数据)在系统底层就是读写事件。
    1)假设採用堵塞调用的方式,当读写事件没有准备好时。必定不能够进行读写事件。那么久仅仅好等待,等事件准备好了,才干进行读写事件。那么请求就会被耽搁 。堵塞调用会进入内核等待,cpu就会让出去给别人用了,对单线程的worker来说,显然不合适。当网络事件越多时。大家都在等待呢,cpu空暇下来没人用,cpu利用率自然上不去了,更别谈高并发了 。


    2)既然没有准备好堵塞调用不行,那么採用非堵塞方式。非堵塞就是,事件,立即返回EAGAIN。告诉你,事件还没准备好呢,你慌什么,过会再来吧。

    好吧。你过一会。再来检查一下事件,直到事件准备好了为止,在这期间,你就能够先去做其他事情。然后再来看看事件好了没。尽管不堵塞了。但你得不时地过来检查一下事件的状态,你能够做很多其他的事情了,但带来的开销也是不小的 
    小结:非堵塞通过不断检查事件的状态来推断是否进行读写操作。这样带来的开销非常大。

     
    3)因此才有了异步非堵塞的事件处理机制。详细到系统调用就是像select/poll/epoll/kqueue这种系统调用。他们提供了一种机制。让你能够同一时候监控多个事件。调用他们是堵塞的,但能够设置超时时间,在超时时间之内,假设有事件准备好了,就返回。这种机制攻克了我们上面两个问题。

     
    以epoll为例:当事件没有准备好时,就放入epoll(队列)里面。假设有事件准备好了,那么就去处理。假设事件返回的是EAGAIN,那么继续将其放入epoll里面。从而,仅仅要有事件准备好了,我们就去处理她,仅仅有当全部时间都没有准备好时。才在epoll里面等着。这样。我们就能够并发处理大量的并发了,当然,这里的并发请求。是指未处理完的请求,线程仅仅有一个,所以同一时候能处理的请求当然仅仅有一个了,仅仅是在请求间进行不断地切换而已,切换也是由于异步事件未准备好,而主动让出的。

    这里的切换是没有不论什么代价。你能够理解为循环处理多个准备好的事件,其实就是这种。

     
    4)与多线程的比較:
    与多线程相比,这种事件处理方式是有非常大的优势的。不须要创建线程,每一个请求占用的内存也非常少,没有上下文切换,事件处理非常的轻量级。

    并发数再多也不会导致无谓的资源浪费(上下文切换)。


    小结:通过异步非堵塞的事件处理机制。Nginx实现由进程循环处理多个准备好的事件,从而实现高并发和轻量级。 

  • 相关阅读:
    eclipse中的任务标记(TODO、FIXME、XXX)
    编码规范参考
    MVC,MVP 和 MVVM
    Android的两种事件处理机制
    在Eclipse中自定义类似syso的快捷代码模板
    Android
    eclipse使用tips-Toggle Mark Occurrences 颜色更改
    从 Eclipse 迁移至 Android Studio
    Java的位运算符详解实例——与(&)、非(~)、或(|)、异或(^)
    [POJ 2976]Dropping tests(0-1分数规划)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5333027.html
Copyright © 2020-2023  润新知