参考:《Netty权威指南》(李版)1.1.2
其实我并不关心Puma是怎么安排进程/线程的,上文只是验证了RoR框架是支持多进程/多线程部署的。
现在我们着重研究下Passenger + Nginx部署RoR的网络IO模型和进程/线程安排形况。
为了更好地理解,我们通过Passenger + Apache的对比来验证。
先看看理论方面
网络IO模型
Nginx:epoll,IO复用
* 实际上这种说法不准确,Nginx的实现依赖的是Linux2.6以上内核的epoll或是BSD内核的kqueue
Apache:select,IO复用
既然都是IO复用模型,那这里就要简要对比一下epoll和select
1、支持单进程打开的FD(socket文件描述符)数量
select最大的缺陷就是单个进程打开的FD数量严重受限。这个数量由宏FD_SETSIZE设置,默认是1024,这就意味着通常情况下单进程select监视的socket将不超过1024个。而想修改这个宏必须重新编译内核,并且修改之后会带来网络效率的下降。
Apache选择的方案是采用多进程,但是进程维护是需要代价的,而且进程间通信也有代价。
epoll则没有这个限制,epoll支持的FD数量是操作系统的最大句柄数(可以通过cat /proc/sys/fs/file-max来查看)。这个值跟系统内存关系较大,1GB内存的机器上这个值大约是10万。
2、IO效率与FD数量的关系
select/poll还有一个缺陷就是当被监视的socket很多的时候,由于大部分情况下只有少数socket处于活跃状态,但是select/poll的每次调用都会对全部的socket进行线性扫描,这样会导致IO效率呈线性下降。
对于epoll来说,由于只有活跃的socket才会主动调用callback函数,所以epoll只会对活跃的socket进行操作。从这点上来说epoll实现的是一种伪AIO(伪异步IO)。
3、内核与用户空间的消息传递
无论哪种IO,最终都需要将内核数据拷贝到用户空间。epoll是通过内核和用户间mmap同一块内存来实现的,所以效率更高。
这就意味着Nginx比Apache拥有更加出色的并发能力,Nginx采用epoll是其拥有高并发能力的根本原因。
进程/线程
Nginx:异步多进程,每个进程同时处理多个(数万个)连接请求
Apache:同步多进程,每个进程处理一个连接请求
多核CPU支持
Nginx:支持
Apache:不支持