转:nginx高并发原理初探

转载:https://segmentfault.com/a/1190000007614502  《nginx、swoole高并发原理初探》

写的非常好,原理分析的简单通俗易懂。以下只是部分摘录。

 

(通过上面的分析,)我们可以得知:

同步与异步,重点在于消息通知的方式;

阻塞与非阻塞,重点在于等消息时候的行为。

所以,就有了下面4种组合方式

  • 同步阻塞:小明在柜台干等着拿奶茶;

  • 同步非阻塞:小明在柜台边刷微博边等着拿奶茶;

  • 异步阻塞:小明拿着小票啥都不干,一直等着店员通知他拿奶茶;

  • 异步非阻塞:小明拿着小票,刷着微博,等着店员通知他拿奶茶。

1、Apache面对高并发,为什么很无力?

Apache处理一个请求是同步阻塞的模式。

  • 1个客户端占用1个进程,那么,进程数量有多少,并发处理能力就有多少,但操作系统可以创建的进程数量是有限的。

  • 多进程就会有进程间的切换问题,而进程间的切换调度势必会造成CPU的额外消耗。当进程数量达到成千上万的时候,进程间的切换就占了CPU大部分的时间片,而真正进程的执行反而占了CPU的一小部分,这就得不偿失了。

  • Apache是同步阻塞的多进程模式,面对高并发等一些场景,是很苍白的。

2、Nginx何以问鼎高并发?

①、I/O复用是神马?

最初级的I/O复用

所谓的I/O复用,就是多个I/O可以复用一个进程

采用非阻塞的模式,当一个连接过来时,我们不阻塞住,这样一个进程可以同时处理多个连接了。

升级版的I/O复用

上面虽然实现了基础版的I/O复用,但是效率太低了。于是伟大的程序猿们日思夜想的去解决这个问题...终于!

我们能不能引入一个代理,这个代理可以同时观察许多I/O流事件呢?

当没有I/O事件的时候,这个进程处于阻塞状态;当有I/O事件的时候,这个代理就去通知进程醒来?

于是,早期的程序猿们发明了两个代理---select、poll。

select、poll代理的原理是这样的:

当连接有I/O流事件产生的时候,就会去唤醒进程去处理。

但是进程并不知道是哪个连接产生的I/O流事件,于是进程就挨个去问:“请问是你有事要处理吗?”......问了99999遍,哦,原来是第100000个进程有事要处理。那么,前面这99999次就白问了,白白浪费宝贵的CPU时间片了!痛哉,惜哉...

注:select与poll原理是一样的,只不过select只能观察1024个连接,poll可以观察无限个连接。

上面看了,select、poll因为不知道哪个连接有I/O流事件要处理,性能也挺不好的。

那么,如果发明一个代理,每次能够知道哪个连接有了I/O流事件,不就可以避免无意义的空转了吗?

于是,超级无敌、闪闪发光的epoll被伟大的程序员发明出来了。

epoll代理的原理是这样的:

当连接有I/O流事件产生的时候,epoll就会去告诉进程哪个连接有I/O流事件产生,然后进程就去处理这个进程。

如此,多高效!

②、基于epoll的Nginx

有了epoll,理论上1个进程就可以无限数量的连接,而且无需轮询,真正解决了c10k的问题。

Nginx是基于epoll的,异步非阻塞的服务器程序。自然,Nginx能够轻松处理百万级的并发连接,也就无可厚非了。

 

posted on 2020-05-08 09:50  orange-C  阅读(239)  评论(0编辑  收藏  举报

导航