前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
简介
Apache 是一个非常强大和功能丰富的 Web 服务器。为了尽可能地简化初始设置,它预装了许多模块,这使得它成为新项目的绝佳选择,当你需要快速提高生产力时。然而,随着你的网站规模的扩大,你可能会开始遇到性能问题。
最初吸引我的是 DigitalOcean 的低成本入门。最小和最便宜的 droplets 有 512MB 的 RAM,在当今大型框架的世界里似乎并不多。然而,如果你花点时间调整设置,你会惊讶地发现你可以用这样一个小型服务器做很多事情。
如果你在较小规模的 droplets 上运行 Apache,或者如果你想在更大的 droplets 上最大化性能,以下是一些你应该做的事情。我将在示例中使用 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
- Rewrite
- Perl
- Python
- Rack / 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
版权归原作者 白如意i 所有, 如有侵权,请联系我们删除。