apache和nginx那点事儿--阻塞和异步
Posted nginx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了apache和nginx那点事儿--阻塞和异步相关的知识,希望对你有一定的参考价值。
先明白的事儿:当一个程序在执行的时候,一般会创建一个进程,也可以有多个进程。一个进程至少会创建一个线程,多个线程共享一个程序进程的内存。程序的运行最终是靠线程来完成操作的。线程的数量跟CPU核数有关,一个核最多能发出两个线程。线程的操作主要分为:一:给CPU进行程序命令的执行。二:IO的操作(读取或输出数据)或者请求网络数据。
什么是阻塞:就是线程在执行IO操作获取数据时,这个IO可能会需要一定的时间才能等到数据返回,然后才能接着执行下面的命令。那么,此时,这个线程的等待状态我们就把它称为阻塞。没有充分利用起cpu的资源。
什么是非阻塞:还是这个线程在进行 IO操作时,无需等待数据的返回,可以接着往下执行代码命令。cpu资源一直在充分利用。
但是总要知道数据什么时候返回吧,常见的两个解决方案:
第一:如果程序是单线程的情况下,在接着执行下面的代码过程中,需要额外不断的轮询查看这个IO请求的数据是否返回。
第二:使用多线程,一个进程继续等待数据返回,另一个线程继续操作执行下面的代码。cpu资源一直在充分利用。
什么是同步和异步:同步指的当线程进行IO操作请求数据时,是你主动"关心"数据的返回。异步是当前线程无需主动关心数据是否返回,当数据返回时,会有相关的事件通知你。
由此可见:阻塞并不等于同步,非阻塞也不等于异步。阻塞不阻塞的区别点在于:线程当遇到IO操作,需要等待IO返回数据时,是否能继续往下执行代码。而同步与异步的区别点在于:IO要返回的数据是需要线程主动等待,还是被动的等待数据处理完之后主动通知你。
最好的理想方案就是:异步非阻塞。而nginx就使用的非阻塞+异步。apache使用的是同步阻塞。这也就是为什么nginx能比apache处理更多的请求更高的并发的原因。
apache与nginx的工作原理:
假如下面是类似apache和nginx的伪代码:
listen //监听端口
while(true){
$conn = accept() //一直循环接收连接
$read_content = read(conn)//读取请求的文件
$esponse = process(conn) # 执行业务逻辑
echo $espnse //返回客户端内容
}
apache:
每一个连接,apache就会创建一个进程,每个进程内单线程,apache最多能创建256个进程。对于一个负载相对较高的网站来说,256的进程,也就是256个线程,因为线程处理请求时,是同步阻塞模式,接收请求之后,会一直等待该请求读取程序文件(IO)(同步),执行业务逻辑,返回客户端,所有操作完成之后才能处理下一个请求(阻塞)如果服务器已经达到256的极限,那么接下去的访问就需要排队这也就是为什么某些服务器负载不高的原因了。
nginx:
nginx接收一个请求后,不会等待这个请求的文件读取操作完成之后才接收下一个请求,它不会等待这个请求的后续的处理结果。而是会马上循环处理下一个请求(不阻塞)。请求的程序文件执行完成之后,会主动通知该线程,不用你主动去等待或者轮询查看(异步)。最后返回给客户端。这样做,每个请求过来就不需要等待很长的时间排队,而是马上就能接收,开始进行处理了。等处理完成之后,会主动通知回调这个线程进行数据返回。
技术文章推荐:
以上是关于apache和nginx那点事儿--阻塞和异步的主要内容,如果未能解决你的问题,请参考以下文章
nginx那点事儿——nginx中关于rootalias及localtionproxy_pass后面是否有/的区别