文章目录
一、nginx VS apache
1、epoll VS select
这里拿 Nginx 和 曾经的 web服务明星 Apache 对比下,两者性能差别的主要原因在于网络IO模型选择不同:
apache 使用了 select 模型:
用一个线程去遍历轮询每一个连接,然后得到需要处理的连接,并对这些连接进行处理。
而 nginx 使用了epoll 模型:
认为每个连接都有可能活跃需要处理,
通过事件触发,将要处理的需求放入队列中,
然后只对队列中的少量连接进行处理,
而不需要遍历轮询所有连接。
遍历轮询挑选处理 VS 直接处理,这个效率差距,就可想而知了。
在内核中的 select 实现中,它是采用轮询来处理的,轮询的 fd 数目越多,自然耗时越多。
在 linux/posix_types.h
头文件声明:
#define __FD_SETSIZE 1024
这表示 select 最多同时监听 1024 个 fd,如果要扩大这个数目,需要修改这个头文件并重编内核。
相比于 select,epoll 则只会对 “活跃” 的 socket 进行操作,
这体现在内核实现中,
就是 epoll 是根据每个 fd 上面的 callback 函数实现的,
而只有 “活跃” 的 socket 才会主动的去调用 callback ,其他 idle 状态 socket 则不会。
所以 epoll 不会随着监听 fd 数目的增长而降低效率。
但是,要注意这里所讨论的性能差异,有个前提条件是 “并不是所有的连接都活跃”,
如果在所有的 socket 都是活跃的场景,那 epoll 就不一定比 select 高效了!
2、多进程异步非阻塞
这里再从多进程角度,描述一下 Epoll 这种 IO 多路复用技术。
nginx 采用一个 master 进程,多个 woker 进程的模式。
master进程:
主要负责收集、分发请求。
每当一个请求过来时,master 就拉起一个 worker 进程负责处理这个请求。
同时 master 进程也负责监控 woker 的状态,保证高可靠性;
woker进程:
一般设置为跟 cpu 核心数一致;
grep processor /proc/cpuinfo | wc -l
nginx 的 woker 进程在同一时间可以处理的请求数只受内存限制,可以处理多个请求。
每来一个 request,会有一个worker进程去处理;
但不是全程都处理,当处理到可能发生阻塞的地方的时候(比如向其他服务器转发request,并等待请求返回),
那么,worker 就会在发完请求后,注册一个事件: “如果 upstream 返回了通知我,我再接着干”,于是他就去休息了。
此时