我有一个 VPS,内存为 768 MB,处理器为 1.13 GHZ。我运行一个 php/mysql 约会网站,性能非常好,服务器负载通常很低。
有时我会在 Facebook 上投放广告,在高峰时段,我可以在几秒钟内获得 100-150 次点击 - 这会导致服务器内存耗尽:
无法分配内存:无法创建子进程:/opt/suphp/sbin/suphp ....
并且所有用户都会收到错误 500 页面。
我只是想知道这是否听起来合理 - 对我来说 100-150 似乎不是一个会导致 apache 内存耗尽的数字。
非常感谢任何有关如何诊断该问题的建议/推荐。
答案1
优化内存占用通常通过减少(和限制)这些因素来实现:
- 同时运行的 Apache 进程数(我建议切换到 prefork MPM,它在内存有限的环境中更易于控制)
- 从 mod_php 或 php_cgi 移至 fastcgi,mod_cfgid 工作正常。通过 FcgidMaxProcesses 减少允许生成的 php 进程数并删除长时间超时(请参阅http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html)
- 服务器“线程性”,特别是通过减少不必要的长超时((断开)连接超时、保持活动……)
如果负载真的很重,您还应该研究请求处理的速度(更快的加载速度可以提高一个请求所需的内存总大小*时间)
- 优化您的网站代码(改进 PHP 代码,使其更快和/或更节省内存)
- 优化 PHP 执行(xcache 可以将速度提高几倍)
- 缓存整个请求也能产生奇效,请参阅 mod_cache
也许,如果您的网站根本不占用任何 CPU,并且您需要一些极端的 Req/S,请尝试一些不同的 Web 服务器(如 nginx 或 lighttpd),它们在这种情况下表现更好。
答案2
处理突增的流量非常困难。替代方案包括:更轻量的 HTTP 服务器(lighttpd、nginx 等);更多物理 RAM;负载平衡器和附加主机,这具有更高的可用性;将应用程序代码卸载到与 HTTP 服务器不同的系统,通常通过 FastCGI;通过 EC2 等云服务动态配置计算资源以满足负载;或者我忘记或没有想到的大量其他想法。关于这方面有很多很棒的资源;高可扩展性例如,博客涵盖了这方面的很多内容。希望这能有所帮助!
答案3
Apache 的每个实例内存要求约为 10MB,但具体数量取决于您的配置。因此,如果您想使用 Apache 处理 100 个并发连接,则至少需要 1GB 的 RAM,外加系统、MySQL 和您正在运行的其他程序所需的内存。
如果您想停止“错误”情况,您可以将MaxClients
Apache 配置参数调整到适当的水平。要获得每个 Apache 实例的内存估计值,请查看top
输出并减去所有 httpd 命令的 RES 和 SHR 列。确保减去 MySQL 和系统其余部分所需的内存。请注意,您最终可能会得到此机器上相对较低的 MaxClients 数字(30-50)。
其他答案很好地总结了您可以采取哪些措施来提高可以处理的并发请求数量。请注意,在如此低端的系统上,安装 Apache/PHP/MySQL 以及 lighttpd/nginx/memcached/caching 可能很困难,但并非不可能。难易程度取决于您的应用程序和目标性能。考虑升级到更大的服务器...您会发现让所有东西都适合 2GB 或 4GB 要容易得多。
答案4
首先要做的是整理您当前的系统。开箱即用的 apache 通常配置了许多您可能不需要的扩展(特别是 auth 和代理,如果您使用 SSL,也一样,但很少,那么请考虑删除 mod_ssl 并运行 stunnel)。请启用 mod_deflate。查看系统上运行的所有其他东西 - 关闭(并禁用)您不需要的任何服务。
接下来,通过 CGI 在专用机器上运行 suphp 通常是一个非常愚蠢的想法 - 使用 mod_php 或 fastCGI。
通过提高系统运行速度,您不仅可以为客户提供更好的服务,还可以减少内存占用。所以……
如果您还没有 PHP 操作码缓存,请安装一个。
开始深入研究系统的性能 - 更改您的 httpd 配置以开始记录 %D,并查看 URL 频率和 %D 的乘积,以确定哪些 URL 导致了最多问题。
降低 MySQL 中慢查询日志的阈值 - 使用这个解析器或类似地分析数据(请注意,您应该再次根据频率和运行时间的乘积来确定优先级)。
添加自动前置以启用 gz 输出缓冲区压缩。
开始记录正在运行的 httpd 进程数,并将其与“空闲”中可用的较少缓存/缓冲区进行比较 - 整理数据并绘制图表以计算出您可以合理运行的 httpd 进程数 - 然后更改 httpd.conf 以强制执行此限制。请注意,磁盘 I/O 是现象上很慢——所以你需要大量的内存用于缓存。
开始查看您的服务器是否提供了带有内容的良好缓存信息 - 或者客户端和代理是否必须不断回来获取未发生改变的内容(mod_expires,mod_headers)
但有时你确实需要更多硬件。我建议考虑第二台服务器,而不是仅仅升级你已有的服务器 - 添加循环 DNS 很简单 - 而且你还可以获得更好的可用性(一旦你弄清楚了如何处理数据库复制)。