一般来说Apache有两种常用工作模式prefork和worker;
要查看当前服务器的工作模式,请用命令 apache2 -l
$ apache2 -l
Compiled in modules:
core.c
mod_log_config.c
mod_logio.c
prefork.c
http_core.c
mod_so.c
可以看到prefork.c 说明现在在用prefork模式。
关于两种模式的区别,根据官方文档:
- The
workerMPM uses multiple child processes with many threads each. Each thread handles one connection at a time. Worker generally is a good choice for high-traffic servers because it has a smaller memory footprint than the prefork MPM. - The
preforkMPM uses multiple child processes with one thread each. Each process handles one connection at a time. On many systems, prefork is comparable in speed to worker, but it uses more memory. Prefork’s threadless design has advantages over worker in some situations: it can be used with non-thread-safe third-party modules, and it is easier to debug on platforms with poor thread debugging support.
可以看到,这些主要和进程和线程有关,对于内存有限逻辑简单,不太考虑线程安全的网站,worker模式显然更加适合。
复习下进程和线程的主要区别和联系:
进程与线程区别与联系
- 划分尺度:线程更小,所以多线程程序并发性更高;
- 资源分配:进程是资源分配的基本单位,同一进程内多个线程共享其资源;
- 地址空间:进程拥有独立的地址空间,同一进程内多个线程共享其资源;
- 处理器调度:线程是处理器调度的基本单位;
- 执行:每个线程都有一个程序运行的入口,顺序执行序列和程序的出口,但线程不能单独执行,必须组成进程,一个进程至少有一个主线程。简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
worker模式是介于纯进程的prefork和纯线程的event模式直接的方式,在稳定性和资源上有一个取舍。
prefork配置解释
一个典型的prefork配置和解释如下
<IfModule prefork.c>
StartServers 20 # 启动服务数,对应启动进程数
MinSpareServers 50 # 最小空闲服务(提高响应能力),当前进程数 > 最小空闲服务 + 工作进程
MaxSpareServers 100 # 最大空闲服务(合理释放资源),当前进程数 < 最大空闲服务 + 工作进程
MaxClients 200 # 最大客户端,对应最大进程数
MaxRequestsPerChild 20000 # 每个服务最多处理的请求数量,设定一个有限值可以避免内存泄漏,但会消耗进程创建和销毁的资源
</IfModule>
prefork是用起来最方便的设置,apache的默认设置也是如此。
但该模式最内存资源消耗巨大。举例来说:
一般情况下,一个PHP网站中,每个server需要30M左右内存。
按照前文的配置,最多将占用6G左右的内存。
如果资源不足,就会引发频繁的page fault,大量的SWAP,系统产生大量IO,导致宕机。
所以合理的调整参数,满足网站并发要求和资源限制,在小内存(1G),prefork模式几乎是不可能做到的。
worker配置解释
<IfModule worker.c>
StartServers 15 # 启动的服务,对应进程
ServerLimit 15 # 最大服务限制 应满足 ServerLimit > MaxClients / ThreadsPerChild
MaxClients 256 # 最大客户端数量
ThreadLimit 256 # 最大线程数量
MinSpareThreads 30 # 最小空闲线程(提高响应能力),当前线程数 > 最小空闲服务 + 工作线程
MaxSpareThreads 305 # 最大空闲线程(合理释放资源),当前线程数 < 最大空闲服务 + 工作线程
ThreadsPerChild 255 # 每个子进程对应对线程数
MaxRequestsPerChild 0 # 每个进程处理的最大请求数量,达到即销毁新建进程
</IfModule>
类似的,我们也主要关注其并发响应能力和资源占用情况。
上面的配置可以支持256的并发,内存占用约大于 15 * 30M = 450M 左右,算上线程的开销,大致小于500M。
其他建议
并发和性能与很多东西相关,不是简单计算能够解决的。
这里的配置主要是避免系统瓶颈,同时保护服务器不要超过应用能力。
实际情况中,和磁盘性能,网络,CPU等都有关系,建议在对硬件的充分理解上,结合性能测试工具不断调优。Linux WEB Perfomance Tunning Toolbox
After the day