Nginx为什么可以做到高并发(一)


多线程让程序可以同时做多个工作,但是高并发和多线程没有必然联系,
并发数是同时进行的任务数,并行数是同时工作的资源数量(线程),
通过合理调度任务的不同阶段,让几个CPU可以支持上万个用户并发请求成为可能。
但是高并发的情况下,假如为每个任务创建一个进程或线程,
这个开销非常大,所以说高并发和多线程没有必然联系。

刚才说到通过合理调度任务的不同阶段可以实现高并发,那么怎么样算是合理呢?
IO有内存IO、网络IO和磁盘IO,但通常只讨论网络IO和磁盘IO。
用户进程空间<–>内核空间
内核空间<–>设备空间(磁盘、网络等)。
将IO分两阶段,以钓鱼举例:
1.等待数据准备好(等鱼上钩)(网络IO)
2.内核空间复制回用户进程缓冲区阶段(扯鱼上岸)(磁盘IO)

因为不知道鱼什么时候上勾,所以通常第一阶段比第二阶段更消耗我们的精力。
问题变成如何钓鱼更高效
有五种回答:阻塞IO、非阻塞IO、信号驱动IO、IO多路复用、异步IO。
在自动化程度上,依次递增。其中,前四个被称为同步IO。

所谓同步IO是指上钩或者上岸至少有一处得自己动手,难道鱼还会主动跳上岸不成?异步IO就是鱼主动跳上岸这个意思,因为这是个电动鱼竿,可以独立完成上钩和扯鱼上岸。

那NGINX是不是异步IO呢?网上资料普遍说是IO多路复用技术(epoll),也就是第四种,但也有网友说可以归为第五种,要弄清楚这个问题,先弄清楚IO多路复用如何区别于异步IO。
什么是IO复用?
IO复用解决的就是并发性问题,后端处理多个请求对应中间件就会产生多个IO流对应系统的读写。
那么对于IO流请求操作系统内核有并行处理和串行处理的概念,串行处理的方式是一个个处理,前面的阻塞后面的请求,显然串行处理很弱鸡。
这个时候我们必须考虑并行的方式完成整个IO流的请求来实现最大的并发和吞吐,于是用到IO复用技术,让一个Socket来作为复用完成整个IO流的请求。
什么是IO多路复用?
前面已经理解了复用,现在理解多路的含义,
多路是指一个进程能同时等待多个Socket,而这些Socket其中的任意一个进入读就绪状态,select()函数就可以返回。
注意:一个socket作为复用来完成整个io流的请求连接建立(accept),
但是处理socket请求(recv,send,close)则采用多线程。
什么是异步IO?
先回顾一下Ajax,Ajax最有特色的地方是回调函数,同理,异步IO是告知内核启动某个IO操作并复制到我们自己的缓冲区,内核回调通知我们坐享其成。

可知,有一点区别在于是否坐享其成。

那NGINX是不是异步IO(坐享其成)呢?
不是彻底的异步IO,更多像是IO多路复用。
其中异步表现在委托别人轮询,多路复用表现在一个worker服务多个request。
当一个worker接收到一个request,worker会处理到底,但不是全程管家式服务,当处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会傻等,他会注册事件委托upstream帮忙轮询这个request是否就绪。他就休息去了。此时,如果再有request 进来,如法炮制。
而一旦上游服务器返回了,就会触发这个事件,这时worker回来接手,这个request才接着往下走。worker既可以处理新的request,也可以接着处理旧的request。

         每个request的大部份时间都在网络传输中,实际上花费在server机器上的时间片不多。把多个IO请求丢到后台,以此来实现在一个进程里服务大量的并发IO请求。

总结:本文以高并发作为切入点,重点回答了NGINX属于那种IO模型,
    下一篇 NGINX为什么可以做到高并发 将展开介绍本文提到的几种IO模型以及NGINX在使用epoll上的细节。

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值