如何对Apache Web服务器进行性能优化

提供:ZStack云计算

系列教程

本教程为Django规模扩展系列三篇中的第二篇。

内容介绍

Apache是一套极为强大的Web服务器。为了简化初始设置,其提供多种预安装模块。如果大家希望快速实现项目上线并投入生产,其无疑是最为出色的备选方案。不过,随着站点规模的扩大,大家往往会面临更多性能问题。

DigitalOcean的最低配置Droplet,其内存容量为512 MB。如果大家实际选择的配置更低,或者希望能够在大型Droplet上充分发挥性能,则请遵循以下几个步骤。本示例使用Ubuntu 12.04版本,但核心思路亦适用于其它Linux发行版。

卸载不需要的模块

在Ubuntu与Debian系统当中,大家能够找到/etc/apache2/mods-enabled与/etc/apache2/mods-available/两个文件夹。其中mods-available文件夹列出了全部已经安装在特定服务器上的模块,而mods-enabled则为当前正处于活动状态的模块。

在我的VPS中,我的默认活动模块数量为17个,这显然超出了应用运行的实际需要。遗憾的是,我们很难弄清到底哪些属于必要模块,因为不同模块间可能存在依赖性。

这里我建议大家整理出一份全部当前活动模块的清单,以备日后恢复使用。接下来逐一禁用各模块并重启Apache以观察效果。

在Ubuntu与Debian当中,大家可以使用以下命令禁用模块:

sudo a2dismod autoindex

其中部分模块会占用大量资源,因此需要优先禁用:

  • PHP
  • SSL
  • Rewrite
  • Perl
  • Python
  • Rack / Ruby / Passenger

其中部分模块在默认情况下并未启动,因此我们可以在需要时再行启用。

先来看看“rewrite”,一般来讲此模块会与“alias”模块的作用基本一致。因此如果启用了alias,请记得禁用rewrite。Rewrite是资源需求最高的模块之一,但作用亦非常重要。

由“rewrite”转向“alias”其实比较复杂(具体参阅帮助文档)。不过即使大家无法彻底关闭rewrite,也可以将其中部分规则转换为alias。

在禁用一项模块并重载Apache配置后,大家可以检查apache error日志获取信息。在Ubuntu与Debian中,检查/var/log/apache2/error.log文件。

示例中的错误信息如下:

Syntax error on line 6 of /etc/apache2/sites-enabled/site1:
Invalid command 'DAVLockDB', perhaps misspelled or defined by a module not included in the server configuration
Action 'configtest' failed.

这意味着我刚刚禁用的模块必须处于活动状态。这里我们要重启该模块——dav_fs:

sudo a2enmod dav_fs

重启Apache继续进行错误验证。检验模块的过程可能比较耗时,请大家保持耐心。

将代码迁移至Apache之外

如果大家运行有PHP站点,那么各位很可能在使用著名的mod_php。而如果运行ruby站点,则最轻松的方案则为Passenger Phusion,即mod_rails或者mod_rack。

不过问题在于,作为解释器的C代码被嵌入至Apache当中,因此会在每个页面视图中占用内存。假设站点上的一个高人气页面带来30次HTTP请求,那么按比例来看其中一次请求动态页面、其它则请求静态资源。在这种情况下,我们显然没必要建立一套臃肿的Apache来服务那29次根本不涉及任何动态内容的请求。

由此带来的差异非常明显。使用mod_php会让每个Apache子进程带来超过100 MB的内存使用量!考虑到Apache服务器通常都运行着25个甚至更多进程,这一问题当然需要重视。

下面来看能够解决问题的相关工具:

  • PHP可使用php-fpm,其属于使用fastcgi协议的独立进程。
  • Python可使用uWSGI或者gnunicorn (更多细节信息请参阅此篇教程)。
  • Rails可使用Unicorn (更多细节请参阅此篇Unicorn教程)。

这种变更的缺点在于,我们很难以初始化方式完成调整。另外,php-fpm的说明文档也不够完善。

一般来讲,PHP、Python以及Ruby在启动时会生成一个特殊的服务器进程,而后是Apache,这意味着后者本身并不了解如何通过嵌入代码处理这些请求,而仅仅是将此类动态内容调用转发至后端进程。

不过调整的效果确实令人满意。在移除了mod_php后,我的Apache进程总体积由每个90到120 MB削减到了10 MB。这意味着我能够提供更多动态内容,且2个php后端进程的内存占用量仅各为60 MB。

限定Apac进程与子进程数量

大部分操作系统的默认Apache配置都不太适合小型服务器——其中往往包含25个甚至更多子进程。如果每个子进程使用120 MB内存,那么单单分配给Apache的内存总量就高达3 GB。

一名访问者的浏览器往往会一次性从网站处请求4个条目,因此7到8名用户同时访问即会令云服务器发生过载。

服务器通常会保留大量不必要的Apache进程,提供用户已经不再需要的内容,这自然严重影响到服务器用户的可用进程量以及系统内存剩余。

要解决这一难题,我们需要了解应用的实际内存需求量,而后明确还有多少内存余量,并尽可能多地将其分配给Apache。

例如,如果大家拥有3个负责处理动态内容的php-fpm进程,每个占用70 MB内存,而MySQL服务器则占用120 MB内存,那么该应用的内存需求总量则为330 MB。这意味着我们可以将150 MB内存分配给Apache。

Apache运行在服务器上时,能够提供top命令工具供我们使用。下面粘贴的是其中部分相关内容:

top -bn 1
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                    
[...]
15015 www-data  20   0  232m 9644 1900 S  0.0  1.6   0:00.02 apache2                    
15016 www-data  20   0  232m 9644 1900 S  0.0  1.6   0:00.01 apache2                    
15017 www-data  20   0  232m 9644 1900 S  0.0  1.6   0:00.02 apache2                    

请注意Apache子进程中的RES列及其值。例如,在我的已优化虚拟服务器上,该值为9644,这意味着其内存占用量不足10 MB。如果我将Apache的子进程数量限定为15,则其最大内存占用量不会超过150 MB。

编辑/etc/apache2/apache2.conf配置文件,找到mpm_prefork_module配置部分。找到MaxClients一行并将其设定为15,而后保存并重启Apache。

以下为Ubuntu中返回的结果:

<IfModule mpm_prefork_module>
StartServers          3
MinSpareServers       3
MaxSpareServers       5
MaxClients           30
MaxRequestsPerChild   0
</IfModule>

See the MaxClients line there? We need to change that value to a lower number.看到MaxClients一行了吧?我们需要将其值变更为更小的数字。

如果VPS过载,且最大客户数量达到上限,则更多请求将无法得到响应。这时,用户需要重载页面再次尝试。

这种方式虽然听起来不好,但请相信我,这种控制下的运行状态机制要远比永远敞开大门好得多。

在本示例中,我使用的Droplet拥有1 GB内存,4个php-fpm进程且能够同时响应950名并发用户。这意味着每天页面视图容量为4200万个,应该足够正常网站使用了。

考虑其它配置MPM

大多数Apache配置都会使用prefork mpm,其具备线程安全特性且适用于PHP及其它嵌入语言。

如果大家不想使用PHP或者Rails等外部模块,则可以考虑工作程序MPM,其速度表现要优于prefork。

要启用该模块,我们首先进行安装:

sudo apt-get install apache2-mpm-worker

显示信息如下:

The following packages will be REMOVED:
  apache2-mpm-prefork libapache2-mod-php5
The following NEW packages will be installed:
  apache2-mpm-worker
0 upgraded, 1 newly installed, 2 to remove and 2 not upgraded.
Need to get 2,284 B of archives.
After this operation, 8,718 kB disk space will be freed.
Do you want to continue [Y/n]? 

请注意,在Ubuntu上如果我们安装了mpm,其会同时卸载prefork mpm,且卸载mod_php以及其它不兼容的附加模块。

这里我们已经探讨了四种优化方案,相信大家能够借此利用小型Droplet承载起具有一定规模的网站体系。

我强烈建议大家在测试Droplet上进行上述步骤——而非生产服务器。DigitalOcean服务的最大优势就是,我们可以随时建立新的Droplet并进行变更测试,并在完成后将其关闭。这显然是一种风险低、成本少的理想VPS配置探索途径。

本文来源自DigitalOcean Community。英文原文:How To Optimize Apache Web Server Performance By Matthew Nuzum

翻译:diradw

你可能感兴趣的:(如何对Apache Web服务器进行性能优化)