84669 人学习
152542 人学习
20005 人学习
5487 人学习
7821 人学习
359900 人学习
3350 人学习
180660 人学习
48569 人学习
18603 人学习
40936 人学习
1549 人学习
1183 人学习
32909 人学习
我记得《unix网络编程》,一共提到五种io模型:
阻塞IO模型 非阻塞IO模型 IO复用模型 信号驱动IO 异步IO模型
可是为什么我见过的web服务器,要么是用阻塞io+线程(比如apache),要么是多路复用(比如epoll),但在我看来后两种io才是最完美的解决方式,可是为什么web服务器没有使用呢?
是因为发送信号,这个操作太浪费了?所以对于web服务器这种要接受大量请求的,每一个io都发送信号代价太大?还是因为别的?
业精于勤,荒于嬉;行成于思,毁于随。
epoll 是 linux 2.6 以后才出现的,所以,Nginx 使用了 epoll 模型。所以,Nginx 处理静态文件或者做反代很强行,因为主要是 IO 操作。
epoll 是 select/poll 的增强版,就是基于事件通知的。
Apache、Tomcat,他们虽然也是 Web 服务器,但是也承担应用服务器的角色,之所以称他们为应用服务器,是因为他们真的要跑具体的业务应用,如科学计算、图形图像、数据库读写等。它们很可能是 CPU 密集型的服务,事件驱动并不合适。
鱼与熊掌不可兼得。事件驱动适合于 IO 密集型服务,多进程或线程适合于 CPU 密集型服务。
再者,根据 TCP、HTTP 协议的特点,大部分服务器都会保留 time_wait 的持久链接。Web 服务器主要是用来处理 HTTP 协议的请求。
没有最完美的,只有更适合的
node是异步io吧 而且确实性能很好
Nginx就是一个异步IO的实现啊, 他有一个大的eventloop所以不允许有任何阻塞的进程 不然会阻塞所有, 在开发一个nginx模块的时候尤其要注意这一点, 这也带来了一些问题 比如全异步的IO会导致程序不宜读,所以后期维护上可能会带来问题 这个时候Lua来了~~
我来说下为什么不使用同步非阻塞模型。
由于socket是非阻塞的方式,因此用户线程发起IO请求时立即返回。但并没有读取到任何数据,用户线程需要不断地发起IO请求,知道数据到达后,才真正读取到数据,继续执行。
用户线程使用同步非阻塞IO模型的伪代码描述为:
{ while(read(socketfd, buffer) != SUCCESS) ... process(buffer); }
即用户需要不断地调用read,尝试读取socket中的数据,直到读取成功后,才继续处理接收的数据。整个IO请求过程中,虽然用户线程每次发起IO请求后可以立即返回,但是为了等到数据,仍需要不断轮询、重复请求,消耗了大量的CPU的资源。所以一般很少用这种模型。
为什么不使用异步IO模型?1)异步要通过大量的callback,hook函数实现,调试,维护,可读性都是一个很大的挑战,现在还没有很好的工具集来支持异步编程。2)阻塞io+线程和多路复用已经比较好的解决了高并发问题,成本也不高。3)异步IO不一定真的异步,比如POSIX AIO(glibc AIO),性能也不好。详见异步IO应用
epoll 是 linux 2.6 以后才出现的,所以,Nginx 使用了 epoll 模型。所以,Nginx 处理静态文件或者做反代很强行,因为主要是 IO 操作。
epoll 是 select/poll 的增强版,就是基于事件通知的。
Apache、Tomcat,他们虽然也是 Web 服务器,但是也承担应用服务器的角色,之所以称他们为应用服务器,是因为他们真的要跑具体的业务应用,如科学计算、图形图像、数据库读写等。它们很可能是 CPU 密集型的服务,事件驱动并不合适。
鱼与熊掌不可兼得。事件驱动适合于 IO 密集型服务,多进程或线程适合于 CPU 密集型服务。
再者,根据 TCP、HTTP 协议的特点,大部分服务器都会保留 time_wait 的持久链接。Web 服务器主要是用来处理 HTTP 协议的请求。
没有最完美的,只有更适合的
node是异步io吧
而且确实性能很好
Nginx就是一个异步IO的实现啊, 他有一个大的eventloop所以不允许有任何阻塞的进程 不然会阻塞所有, 在开发一个nginx模块的时候尤其要注意这一点, 这也带来了一些问题 比如全异步的IO会导致程序不宜读,所以后期维护上可能会带来问题 这个时候Lua来了~~
我来说下为什么不使用同步非阻塞模型。
由于socket是非阻塞的方式,因此用户线程发起IO请求时立即返回。但并没有读取到任何数据,用户线程需要不断地发起IO请求,知道数据到达后,才真正读取到数据,继续执行。
用户线程使用同步非阻塞IO模型的伪代码描述为:
即用户需要不断地调用read,尝试读取socket中的数据,直到读取成功后,才继续处理接收的数据。整个IO请求过程中,虽然用户线程每次发起IO请求后可以立即返回,但是为了等到数据,仍需要不断轮询、重复请求,消耗了大量的CPU的资源。所以一般很少用这种模型。
为什么不使用异步IO模型?
1)异步要通过大量的callback,hook函数实现,调试,维护,可读性都是一个很大的挑战,现在还没有很好的工具集来支持异步编程。
2)阻塞io+线程和多路复用已经比较好的解决了高并发问题,成本也不高。
3)异步IO不一定真的异步,比如POSIX AIO(glibc AIO),性能也不好。详见异步IO应用