如何优化 Apache Web 服务器性能

白如意i 2024-10-22 08:03:02 阅读 82

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。

简介


Apache 是一个非常强大和功能丰富的 Web 服务器。为了尽可能地简化初始设置,它预装了许多模块,这使得它成为新项目的绝佳选择,当你需要快速提高生产力时。然而,随着你的网站规模的扩大,你可能会开始遇到性能问题。

最初吸引我的是 DigitalOcean 的低成本入门。最小和最便宜的 droplets 有 512MB 的 RAM,在当今大型框架的世界里似乎并不多。然而,如果你花点时间调整设置,你会惊讶地发现你可以用这样一个小型服务器做很多事情。

如果你在较小规模的 droplets 上运行 Apache,或者如果你想在更大的 droplets 上最大化性能,以下是一些你应该做的事情。我将在示例中使用 Ubuntu 12.04,但我演示的原则也适用于其他版本的 Linux。

卸载不需要的模块


在基于 Ubuntu 和 Debian 的系统中,你会看到一个名为 <code>/etc/apache2/mods-enabled 的文件夹和一个名为 /etc/apache2/mods-available/ 的文件夹。mods-available 文件夹是特定服务器上安装的所有模块的列表,而 mods-enabled 是当前激活的模块。

在我的 VPS 上,默认情况下有 17 个模块是激活的。这太多了,而且大多数对我的应用程序并不需要。不幸的是,你可能无法准确确定你需要哪些模块,因为有些是其他模块的依赖项。

我建议你列出当前激活的所有模块,并保存以备将来参考,以防需要恢复。然后逐个禁用模块,并在每次更改后重新启动 Apache,以查看是否出现错误。

在 Ubuntu 和 Debian 中,你可以使用以下命令禁用模块(以 autoindex 为例):

sudo a2dismod autoindex

一些特别耗费资源的模块,如果你不需要的话,应该禁用,包括:

PHPSSLRewritePerlPythonRack / Ruby / Passenger

其中有几个模块默认情况下是未启用的,所以你可能没有启用它们,而在某些情况下,它们是启用的,因为你实际上需要它们。

关于 “rewrite” 的一个快速说明: 通常情况下,当 “alias” 模块同样适用时,“rewrite” 模块会被启用。如果你可以使用 alias 来替代 rewrite,那么就禁用 rewrite。Rewrite 是比较繁重的模块之一,但它也赋予了 Apache 一些非凡的功能。

从 “rewrite” 切换到 “alias” 是一个高级话题(有一些有用的文档)。然而,即使你无法完全关闭 rewrite,但如果你能够将一些 rewrite 规则转换为别名,你将获得一些优势。

在禁用一个模块并重新加载 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 可能导致每个 Apache 子进程使用超过 100MB 的 RAM!考虑到,默认情况下,你的 Apache 服务器可能有 25 个或更多进程在运行,你就会明白为什么这可能会成为一个问题。

以下是一些你可以使用的工具:

PHP 可以从 php-fpm 中受益,它是使用 fastcgi 协议的独立进程。

对于 Python,使用 uWSGI 或 gnunicorn(有关更多 Python 信息,请查看 DigitalOcean 上的这篇优秀文章)。

对于 Rails,使用 Unicorn(有关更多 Ruby 详情,请查看 DigitalOcean 上关于 Unicorn 的这篇文章)。

做出这种改变的一个缺点是,初始时更难让事情运行起来。在某些情况下,文档非常好。在其他情况下,咳咳 php-fpm 咳咳 文档很少。

通常情况下,会启动一个专门的服务器进程用于 PHP 或 Python 或 Ruby,然后 Apache,而不是通过嵌入的代码本能地知道如何处理这些请求,仅仅将对动态内容的调用转发到这个后端进程。

你会惊讶于这会带来多大的改变。在从我的虚拟服务器中移除 mod_php 后,我的 Apache 进程的大小从每个 90-120MB 减少到了不到 10MB。我能够仅使用两个仅使用了 60MB 的 php 后端进程来提供所有的动态内容。

限制 Apache 进程和子进程的数量


大多数操作系统的默认 Apache 配置并不适合较小的服务器–通常情况下会有 25 个或更多的子进程。如果每个 Apache 子进程使用 120MB 的 RAM,那么你的 VPS 就需要 3GB 的 RAM 来运行 Apache。

一个访问者的网页浏览器可能会同时请求网站上的 4 个项目,因此如果只有 7 或 8 个人同时尝试加载一个页面,你的云服务器就可能会过载。这会导致网页长时间处于加载状态,给人一种无法加载的感觉。

通常情况下,服务器会保持这些无效的 Apache 进程处于活动状态,试图在用户放弃加载页面后继续提供内容,这会减少可用于为用户提供服务的进程数量,同时减少系统可用的 RAM。这会导致一个通常被称为“恶性循环”的情况,最终给你和你网站的访问者带来不好的体验。

你应该做的是先弄清楚你的应用程序需要多少 RAM,然后计算剩下的有多少 RAM,并将大部分分配给 Apache。

举个例子,如果你有三个处理动态内容的 php-fpm 进程,每个进程最多可以使用 70MB 的 RAM,而你的 MySQL 服务器可能最多使用 120MB 的 RAM,那么应用程序总共需要 330MB 的 RAM。这样你就可以给 Apache 分配大约 150MB 的 RAM。

当 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 个子进程,那么它的 RAM 使用量应该最多为 150MB。

编辑你的云服务器的 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 更快。

为了启用 worker 模块,你必须安装它。

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。

我强烈建议你在测试 droplet 上尝试这些优化,而不是在生产服务器上进行。DigitalOcean 服务的美妙之处在于你可以随时启动一个新的 droplet 来测试这些更改,然后在完成后关闭它。按小时计费,这是一种低风险、低成本的方式,来找到你的 VPS 的完美配置。

作者:

Matthew Nuzum



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。