我目前正在使用 Joyent Accelerator 来托管我的 web 应用程序,它运行良好,但是我需要降低成本,所以我正在降级我当前的计划,这会带来一些新的内存限制(256M rss,512M 交换)。昨天我并没有超过他们,但是今天重新启动 Apache 几次后,我现在是 411M rss,721M swap (prstat -Z -s cpu)。
在服务器故障中搜索只为我提供了很多方法和特定工具来监视服务器,但没有关于如何减少/优化它的内存使用的建议。我也看过这个问题,但我认为这对这种特殊(或者我可以说是通用的?)情况没有好处。
服务器在共享 CPU 上运行 Solaris,我使用的是 Apache + MySQL + PHP 堆栈。
我很想知道可以采取哪些步骤来解决这个问题并解决问题。然而,我也没有时间在当前结束之前降低我的记忆足迹和降级计划,所以任何可以创造奇迹和拯救一天的东西也是受欢迎的 :)
谢谢大家的回答!按照您的建议,我已经能够将内存使用量减少到 195M SWAP 和 108M RSS,而无需接触我的代码(我肯定会很快对其进行优化,但这应该是让我快速摆脱麻烦的解决方案)。
这是我做的事情的清单:
摆脱了 VirtualHost 条目中使用的通配符。我使用服务器的真实 IP 而不是 *:80 和 *:443。
更改了 Apache 的 prefork MPM。这些是我最终使用的值:
这些绝不是神奇的数字。我花了一些时间尝试不同的值和组合,然后根据我的服务器的实际使用情况对它们进行测试,每个人都应该在他们的环境中做同样的事情。作为记录,我的服务器每月接收近 200 万 pvs,以固定速率提供动态页面和资产 - 没有挖掘效应。同样,其目的是减少内存占用,而不是提高性能或 HA。
参考:
关闭 Apache 的 KeepAlive。通过设置
KeepAliveTimeout
为较低的值(在我的情况下为 2),我可以预期更少的服务器进程只等待与可能不再请求任何内容的空闲客户端的连接。参考:http ://httpd.apache.org/docs/2.0/mod/core.html#keepalivetimeout
删除了 MySQL 未使用的模块。我添加
skip-innodb
到 MySQL 的 my.cnf。大量减少内存消耗。还有一些我个人无法做到的非常好的建议:
我发现这篇关于 Apache 和 MySQL 的低内存配置的文章
在布置低内存配置所需的配置更改时非常有用。我根据自己的情况调整了它们,但它们应该为您提供找到最适合您的环境所需的工具
您将需要限制正在运行的 apache 服务器进程的数量,并且尽可能接近限制,您将无法处理非常高峰的流量。拥有一个在正常使用情况下最大化的网络服务器通常是一个坏主意(tm),因为网络流量在大多数情况下都很好而且很低,直到你被点刺或挖掘或火球或其他任何事情。
主要问题是在任何一点运行的 apache 进程的数量——假设这里是 prefork,因为我只部署了 PHP 应用程序,而 PHP 不是线程安全的。我没有测量工人 MPM 尺寸的经验。有些项目在共享内存中,有些项目在每个进程的内存中。
您可以通过省去不需要的共享模块来减少总内存占用。基本上,Apache 是由大多数主机配置的,可以在阳光下做几乎所有事情。如果您没有使用 mod_userdir,则将其从您的 apache 配置中注释掉。请注意您删除了多少,因为您可能需要的某些东西或它们的依赖关系并不直观!所有模块都应记录在 apache.org 网站上。每个进程的占用空间更难变小;如今,大多数 apache 配置只附带四个基本模块。除了这四个模块之外,大部分内存使用来自泄漏或应用程序 RAM 没有有效地进行垃圾收集,这就是为什么您可能想要设置请求数量的原因每个进程处理的低。
您确实希望将内存使用量保留在 RAM 本身中,而不是进行交换。交换意味着 I/O。I/O 很慢,并且会在等待某些东西从交换中洗牌时阻塞进程阻塞,从而使您的 CPU 使用率飙升。
对于 apache,请删除您不使用的模块,因为它们只是使用额外的内存。对于 MySQL,如果不使用 innodb/bbdb,请删除它们,并删除不需要的 PHP 模块。
接下来你应该根据一个进程的大小和你想给 apache 的内存量来配置 apache MaxClients。MySQL 上的最大连接数也是如此(我推荐优秀的MySQL Tuning Primer Script。
如果您可以控制您的 PHP 应用程序,请确保它不会使用太多内存(例如在变量中,尤其是静态变量中)。
如果想更进一步,可以将 apache+mod_php 替换为 nginx+fcgi 设置,这样可能会导致内存进一步减少。
最后一件事 - 您真的不想在 Web 服务器上进行交换。只是一点点,删除不需要的东西,但在网络服务器上定期交换将导致网站无响应。
既然你已经达到了目标,这里有一些额外的:
由于您删除了所有不必要的 php 模块,因此您可以对 apache 进行相同的操作。默认情况下(取决于您的安装)apache 加载了很多额外的模块,其中大多数对于日常使用来说并不是真正需要的。例如,有一堆总是加载的身份验证模块。除非您尝试限制带宽使用,否则通常不需要放气。自动索引和状态也值得怀疑。
还有一个就是可以在php.ini中限制php可用的内存量:memory_limit=xxxM
您当然可以限制 apache 可以分叉的进程数量,但这只能作为对内存使用的 sudo 硬限制。从较低级别的角度来看,您可以使用plimit来限制进程可用的资源。我相信将此应用于继承的父进程和子进程。
但是,从 Web 服务器配置的角度来看,它可以归结为您的代码如何真正运行!但请记住,像使用 .htaccess 文件这样的小事情比使用中央 apache 配置文件使用更多资源(因为每次请求进入时都会读取它们,从而导致更大的开销),这在大型网站中很重要。
随着时间的推移,可能有助于内存增长的一件事是将 httpd keepalive 设置得较低,但我会仔细测试,以防您的应用程序需要更长寿命的进程。
我没有使用 Solaris 的经验,但你能做的最好的事情就是不要使用 Apache/mod_php。