如何优化ApacheWeb服务器性能
状态: 已弃用
本文介绍了不再受支持的 Ubuntu 版本。 如果您当前正在运行运行 Ubuntu 12.04 的服务器,我们强烈建议您升级或迁移到受支持的 Ubuntu 版本:
原因: Ubuntu 12.04 已于 2017 年 4 月 28 日终止生命周期 (EOL) and no longer receives security patches or updates. This guide is no longer maintained.
请参阅: 本指南可能仍可用作参考,但可能不适用于其他 Ubuntu 版本。 如果可用,我们强烈建议使用为您正在使用的 Ubuntu 版本编写的指南。 您可以使用页面顶部的搜索功能来查找更新的版本。
介绍
Apache 是一个非常强大且功能强大的 Web 服务器。 为了使初始设置尽可能简单,它预装了许多模块。 当您需要快速提高工作效率时,这使其成为新项目的绝佳选择。 但是,随着站点的增长,您可能会开始遇到性能问题。
DigitalOcean 首先吸引我的是它的低成本入门。 最小和最便宜的 Droplet 有 512MB 的 RAM,这在当今的大型框架世界中似乎并不多。 但是,如果您花一点时间来调整设置,您会惊讶于使用这样的小型服务器可以做什么。
如果您在较小尺寸的液滴上运行 Apache,或者如果您想在较大液滴上最大限度地提高性能,那么您应该做一些事情。 我将在示例中使用 Ubuntu 12.04,但我展示的原则也适用于其他版本的 Linux。
卸载不需要的模块
在基于 Ubuntu 和 Debian 的系统中,您会看到一个名为 /etc/apache2/mods-enabled
的文件夹和一个名为 /etc/apache2/mods-available/
的文件夹。 mods-available 文件夹是安装在特定服务器上的所有模块的列表,而 mods-enabled 是当前处于活动状态的模块。
在我的 VPS 上,默认情况下我有 17 个模块处于活动状态。 这太多了,我的应用程序不需要大多数。 不幸的是,您需要的模块可能不是很清楚,因为有些是其他模块的依赖项。
我建议做的是列出所有当前活动的模块并将其保存以备将来参考,以防您需要恢复。 然后只需逐个禁用模块并在每次更改后重新启动 Apache 以查看是否发生错误。
在 Ubuntu 和 Debian 上,您可以使用以下命令禁用模块(以 autoindex 为例):
sudo a2dismod autoindex
一些特别需要资源的模块,如果你不需要它们,你应该禁用它们:
- PHP
- SSL
- 改写
- Perl
- Python
- 机架 / 红宝石 / 乘客
其中一些模块默认情况下未启用,因此您可能没有启用它们,并且在某些情况下,它们被启用是因为您确实需要它们。
关于“rewrite”的快速说明: 通常,当“alias”模块实际上同样可以正常工作时,会启用此模块。 如果您可以使用别名,请禁用重写。 重写是更繁重的模块之一,但它也赋予了 Apache 一些非凡的能力。
从“重写”切换到“别名”是一个高级主题(有一些 有用的文档)但是,即使您不能完全关闭重写,但您可以将一些重写规则转换为别名,您将获得优势。
禁用模块并重新加载 Apache 配置后,您可以检查 apache 错误日志中的消息。 在 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 请求,其中一个将用于动态页面,另外 29 个可能用于静态资源,如图像、css 和 javascript。 为什么要为那些不提供任何动态内容的 29 个请求使用臃肿的 Apache?
差异可能是巨大的。 启用 mod_php 可能会导致它使用超过 100MB 的 RAM 使用量 每个 Apache 子进程 ! 考虑到默认情况下,您的 Apache 服务器可能有 25 个或更多进程正在运行,您可以了解为什么这会成为问题。
以下是一些您可以用来执行此操作的工具:
- PHP 可以受益于 php-fpm,它是一个使用 fastcgi 协议的独立进程。
- 对于 Python,请使用 uWSGI 或 gnunicorn(有关 Python 的更多信息,请查看 在 DigitalOcean 上的这篇精彩文章)。
- 对于 Rails,请使用 Unicorn(有关 Ruby 的更多详细信息,请参阅 this article on DigitalOcean,涵盖 Unicorn)。
进行此更改的一个缺点是,最初很难让事情正常进行。 在某些情况下,文档非常好。 在其他情况下, 咳嗽 php-fpm 咳嗽 文档很少。
通常情况是,启动一个针对 PHP 或 Python 或 Ruby 的特殊服务器进程,然后 Apache 并没有本能地知道如何通过嵌入式代码处理这些请求,而只是将动态内容的调用转发到这个后端进程。
你会惊讶于这有多大的不同。 从我的虚拟服务器中删除 mod_php 后,我的 Apache 进程的大小从 90-120MB each 变为不到 10MB。 我能够只用两个 php 后端进程来提供我所有的动态内容,每个进程只使用 60MB。
限制 Apache 进程和子进程的数量
大多数操作系统的默认 Apache 配置不太适合较小的服务器 - 25 个或更多子进程很常见。 如果您的每个 Apache 子进程使用 120MB 的 RAM,那么您的 VPS 仅用于 Apache 就需要 3GB。
一个访问者的网络浏览器可能一次从网站请求 4 个项目,因此只有 7 或 8 个人同时尝试加载一个页面,您的云服务器可能会过载。 这会导致网页在看似永恒的情况下一直处于不断加载状态。
通常情况下,服务器会保持这些死掉的 Apache 进程处于活动状态,在用户放弃很久之后尝试提供内容,这会减少可用于为用户提供服务的进程数量并减少可用的系统 RAM 量。 这会导致通常所说的 螺旋式下降 ,最终导致您和您网站的访问者的体验不佳。
你应该做的是计算出你的应用程序需要多少 RAM,然后计算出剩余多少,并将其中的大部分分配给 Apache。
例如,如果您有三个处理动态内容的 php-fpm 进程,每个进程最多可以使用 70MB 的 RAM,而您的 MySQL 服务器可能使用最多 120MB 的 RAM,那么应用程序总共使用了 330MB。 这允许您为 Apache 分配大约 150MB。
当 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 列,并记下它的 RES 值。 例如,在我的经过很好优化的虚拟服务器上,该值为 9,644,这意味着它使用的 RAM 不足 10MB。 如果我将 Apache 限制为最多 15 个子进程,那么它应该最大为大约 150MB 的 RAM。
编辑云服务器的 apache 配置文件,在 Ubuntu 和 Debian 上是 /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>
看到那里的 MaxClients 行了吗? 我们需要将该值更改为较低的数字。
如果您的 VPS 过载,并达到它可以一次服务的最大客户端数量,它将为这些用户提供服务,而其他用户将很快失败。 然后他们可以重新加载页面,并可能在第二次尝试中取得更大的成功。
这听起来很糟糕,但请相信我,让这些连接快速关闭但让服务器处于健康状态而不是永远保持打开状态要好得多。 令人惊讶的是,与拥有更多无法处理的子进程的服务器相比,您可以从具有较少子进程但响应速度更快的服务器获得更好的性能。
举个例子,我管理的一个 Wordpress 网站托管在一个 1GB 的 droplet 上,使用 4 个 php-fpm 进程,并且能够同时为超过 950 个用户提供服务。 如果这个网站变得足够流行,这意味着每天大约 4200 万页面浏览量的峰值容量!
考虑备用 MPM 配置
大多数 Apache 配置在历史上都使用 prefork mpm,它是线程安全的,因此适用于 PHP 和其他嵌入式语言。
如果您摆脱了外部模块,例如 PHP 或 Rails,那么您可以考虑使用 worker 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 上,如果您安装 worker mpm,它将卸载 prefork mpm 和 ,它将卸载 mod_php 和其他不兼容的附加模块。
在这里,我们讨论了您可以对 Apache 进行的四项优化,即使您有一个小液滴,它们也会大大提高您的应用程序性能。
我强烈建议在测试 droplet 而不是你的生产服务器上尝试这个。 DigitalOcean 服务的美妙之处在于,您可以在测试更改所需的时间内启动一个新的 droplet,并在完成后将其关闭。 通过按小时计费,这是一种为您的 VPS 找到完美配置的低风险、低成本方式。