![如何减少 Unix Web 服务器上的内存使用量](https://linux22.com/image/484610/%E5%A6%82%E4%BD%95%E5%87%8F%E5%B0%91%20Unix%20Web%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84%E5%86%85%E5%AD%98%E4%BD%BF%E7%94%A8%E9%87%8F.png)
我目前正在使用 Joyent Accelerator 来托管我的 Web 应用程序,它运行良好,但是我需要降低成本,因此我降级了当前的计划,并施加了一些新的内存限制(256M rss,512M swap)。昨天我并没有超出太多,但今天重启 Apache 几次后,我现在的 rss 为 411M,交换为 721M(prstat -Z -s cpu)。
在 Server Fault 中搜索只会给我提供很多监控服务器的方法和特定工具,但没有关于如何减少/优化内存使用的建议。我还看到了这个问题,但我不认为它适合这种特殊的(或者我可以说是一般的?)情况。
该服务器在共享 CPU 上运行 Solaris,我使用 Apache + MySQL + PHP 堆栈。
我很想知道可以采取哪些步骤来排除故障并解决问题。但是,在当前计划结束之前,我也没有时间降低内存占用并降级计划,所以任何可以创造奇迹并挽救局面的事情也都欢迎 :)
答案1
感谢大家的回答!按照您的建议,我已经能够将内存使用量减少到 195M SWAP 和 108M RSS,而无需触及我的代码(我很快就会对其进行优化,但这应该是一个让我快速摆脱困境的解决方案)。
以下是我所做的事情的清单:
摆脱了 VirtualHost 条目中使用的通配符。我没有使用 *:80 和 *:443,而是使用了我服务器的真实 IP。
更改了 Apache 的 prefork MPM。这些是我最终使用的值:
启动服务器 1 最小备用服务器数 1 最大备用服务器数 5 服务器限制 16 最大客户数 16 每个孩子的最大请求数 0 ListenBacklog 100
这些绝不是神奇的数字。我花了一些时间尝试不同的值和组合,然后根据我的服务器的实际使用情况对其进行测试,每个人都应该在他们的环境中做同样的事情。据记录,我的服务器每月接收近 200 万次 pv,以正常速率提供动态页面和资产 - 没有 digg 效果。再次强调,目的是减少内存占用,而不是提高性能或 HA。
参考:
- http://httpd.apache.org/docs/2.0/misc/perf-tuning.html
- http://httpd.apache.org/docs/2.2/mod/mpm_common.html
调低了 Apache 的 KeepAlive。通过设置KeepAliveTimeout
为较低的值(在我的情况下为 2),我可以预期更少的服务器进程只是等待可能不会请求更多内容的空闲客户端的连接。
参考:http://httpd.apache.org/docs/2.0/mod/core.html#keepalivetimeout
删除了 MySQL 未使用的模块。我将其添加skip-innodb
到 MySQL 的 my.cnf。大量减少内存消耗。
还有一些非常好的建议,我个人无法做到:
- 删除您不需要的 PHP 模块。我的服务器上的 PHP 已经编译了大多数模块,我可能会在其他 VPS 上尝试我自己的最小 PHP。
- 切换到带有 php-fastcgi 的 nginx。这是另一个很好的建议,我很快就会尝试,但现在我不能冒停机的风险。
答案2
我发现这篇关于 Apache 和 MySQL 低内存配置的文章
在规划低内存配置所需的配置更改时非常有用。我根据自己的情况对其进行了调整,但它们应该可以为您提供所需的工具,以找到最适合您的环境的工具
答案3
您需要限制正在运行的 Apache 服务器进程数,如果接近极限,您将无法处理太多的峰值流量。在正常使用情况下,拥有一个最大容量的 Web 服务器通常是一个坏主意 (tm),因为 Web 流量在大多数情况下都很低,直到您遇到 slashdotted、digged 或 fireballed 等情况。
主要问题是任何时刻运行的 Apache 进程数——这里假设是 prefork,因为我只部署了 PHP 应用程序,而 PHP 不是线程安全的。我没有确定工作器 MPM 大小的经验。有些项目位于共享内存中,有些项目位于每个进程的内存中。
您可以通过删除不需要的共享模块来减少总内存占用。基本上,Apache 在大多数主机上都配置为可以做几乎所有的事情。如果您不使用 mod_userdir,请将其从 apache 配置中注释掉。只是要小心删除多少,因为您可能需要的某些东西或它们的依赖关系并不直观!所有模块都应在 apache.org 网站上记录。每个进程的占用空间更难减小;如今大多数 apache 配置仅附带编译的四个基本模块。除了这四个模块之外,大多数内存使用量来自泄漏或未有效垃圾收集的应用程序 RAM,这就是为什么您可能希望将每个进程处理的请求数设置为较低。
你真的希望将内存使用量保留在 RAM 本身中,而不是进入交换区。交换意味着 I/O。I/O 速度很慢,并且会导致 CPU 使用率飙升,因为进程在等待某些内容从交换区移出时会阻塞。
答案4
由于您已经达到了目标,这里还有一些额外的内容:
由于您删除了所有不必要的 php 模块,因此您可以对 apache 执行相同的操作。默认情况下(取决于安装),apache 会加载大量额外模块,其中大多数对于日常使用来说并不是真正需要的。例如,有许多身份验证模块始终会加载。除非您尝试限制带宽使用量,否则通常不需要 deflate。Autoindex 和状态转储也值得怀疑。
还有一个是,你可以在php.ini中限制php可用的内存量:memory_limit = xxxM