Apache 是一个非常成熟的Web服务器,工作模式也在不断优化

现在 Apache 已经有了 3 个核心工作模式,看下他们各自的工作方式是什么样的

(1)prefork MPM,多进程工作模式

先生成主进程,完成基础的初始化工作,然后,通过fork预先产生一批的子进程(子进程会复制父进程的内存空间,不需要再做基础的初始化工作),然后等待服务

之所以预先生成,是为了减少频繁创建和销毁进程的开销

多进程的好处,是进程之间的内存数据不会相互干扰,同时,某个进程异常终止也不会影响其他进程。但是,就内存而言,每个子进程占用了很多的内存,因为子进程的内存数据是复制父进程的

存在大量的“重复数据”被放在内存中。最终,导致我们能够生成的子进程最大数量是很有限

在面对高并发时,因为有不少Keep-alive的长连接,将这些子进程“霸占”住,很可能导致可用子进程耗尽。因此,prefork并不太适合高并发场景

(2)worker MPM,多进程和多线程的混合模式

使用了多进程和多线程的混合模式,它也预先fork了几个子进程(数量很少),然后每个子进程创建一些线程

每个请求过来,会被分配到1个线程来服务,线程共享父进程的内存空间,因此,内存的占用会减少一些,在高并发的场景下,比起prefork更省内存

但是,它并没有解决Keep-alive的长连接“霸占”线程的问题,只是对象变成了比较轻量的线程。

使用进程和线程混合模式,是因为要考虑稳定性,如果一个线程挂了,会导致同一个进程下其他子线程都挂了,如果全部采用多线程,某个线程挂掉,就会影响整个Apache服务

线程共享父进程的内存空间,减少了内存的占用,却又引起了新的问题,就是“线程安全”,多个线程修改共享资源导致的“竞争行为”,因此,一定程度上增加Web服务的不稳定性

(3)event MPM,多进程和多线程的混合模式,引入Epoll

比较新的模式,2.4以后已经是稳定可用的模式,它和worker模式很像,最大的区别在于,它解决了keep-alive场景下,长期被占用的线程的资源浪费问题

event MPM中,会有一个专门的线程来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放,它 减少了“占据”连接而又不使用的资源浪费,增强了高并发场景下的请求处理能力。因为减少了“闲等”的线程,线程的数量减少,同等场景下,内存占用会下降一 些。

Apache的三种模式中在真实应用场景中,event MPM是最节约内存的

余下全文(1/3)
分享这篇文章:

请关注我们:

发表评论

电子邮件地址不会被公开。 必填项已用*标注