第二十九讲:Nginx的请求切换

  前面我们谈到了nginx怎么使用epoll运行自己的事件驱动框架的,那么这样的一个事件驱动框架到底会给我们带来怎样的一个好处尼?

  我们来看下在请求切换的这样一个场景中,这种事件驱动框架给我们带来的争议;

  在下面的这张图中,实际上有三个请求,蓝色的,绿色的还有橘黄色的;

  

 

 

  每一个请求如果是一个HTTP请求的话,我们把它简化为三部分,比如说第一部分我们收到HTTP请求的header 那么收完header以后,我大致就知道我该交给上游的哪一台服务器去处理,应用一些负载均衡算法,那么接下来我可能会向上游服务器建立连接,或者说我本地处理的时候,我接下来会判断这个header中有没有Content-Length指明它可有body,如果含有body的情况下尼?我接下来会读下一个读事件,去处理完它所有的HTTPbody;那么处理完HTTPbody以后尼,我们可能还会向它发送一个HTTP响应,那么在这样的一个过程中尼,它实际上可能表现为三个事件,那么传统的服务尼,比如说Apache和Tomcat它们在处理的时候尼,是每一个进程,同一时间只处理一个请求,比如说process1在处理request1的时候,当request1目前网络事件不满足的情况下,就会切换到process2,就会处理process2上面的request2,而request2可能很快又不满足了,比如写一个响应的时候,发现缓存区都已经满了,也就是说网络中已经用拥塞了,所以说我们的滑动窗口已经没法向前滑动,以至于我们调write方法我们没有办法写入我们需要写入的这样一个字节,当write方法是非阻塞的时候,这个时候我们阻塞类的写方法尼,一定又会导致我们所在的进程又发生一次切换,现在切换到process3,操作系统选择了process3;因为process3上的 request3处于一个满足的状态;我们可以继续往下执行,在执行的过程中尼,process3可能用完了它的时间片,process3又被操作系统切换;又切换到process1;

  如此往复下去;这里会有一个很大的问题,就是我们绿色的箭头在我们当前的CPU的频率下它所消耗的时间大概是5微妙,这个5微妙虽然很小,如果我们并发的连接数和并发的进程开始增加的时候,它不是一个线性增加,而是一个指数增加;所以当我们并发连接非常多的情况下,这个进程间的消耗是非常客观的,以至于消耗了绝大部分的计算能力,所以这种传统的WEB服务它在依赖操作系统的进程调度的方法去实现它的并发连接数,而操作系统的进程调度仅仅适用于很少量的数百 上千这样的进程间做切换;这样的低并发还能接收;再多 几万 几十万的情况下,就无法容忍了;

  那么nginx是怎么处理的尼?

  当蓝色的请求,处理事件不满足的情况下,它在用户态直接就切换到了绿色请求,这样尼,我们就没有了中间进程间切换的一个成本,因为网络事件不满足,除非是我们nginx的worker进程所使用的时间片已经到了,而时间片的长度尼一般是5毫秒到800毫秒;所以我们在nginx的worker的配置上往往会把它的优先级加到最高,比如说我们通常会加到负的19,这样我们的静态优先级提高的比较高的的时候,往往操作系统给我们分的时间片是比较大的;这样我们的nginx才能比较好的在用户态完成请求的切换;使得CPU少做无用功

  现在我们了解了请求切换能够使nginx的性能更高,接下来我们看一看从我们写一段openresty LUA代码或者我们nginx在编程实现中怎样利用这样一个特性来达到非常高的性能的;

  

  

  

posted @ 2020-03-09 15:33  痞子胥  阅读(538)  评论(0编辑  收藏  举报