Apache崩溃:无法分配内存

8

最近两天我的Ubuntu服务器总是在同一个时间点变得不可用。在崩溃期间,我甚至无法通过SSH登录。

这台Ubuntu服务器是部署在Amazon AWS t2.micro实例上的,配备了1GB内存,运行Ubuntu 16.04操作系统。下面是Apache错误日志:

[Wed Aug 30 18:02:23.710072 2017] [autoindex:error] [pid 7505] [client 60.191.38.77:57957] AH01276: Cannot serve directory /var/www/html/: No matching DirectoryIndex (index.html,index.cgi,$
[Wed Aug 30 18:02:23.710126 2017] [:error] [pid 7505] [client 60.xx.xx.xx:57957] script '/var/www/html/404.php' not found or unable to stat
[Wed Aug 30 19:11:54.375001 2017] [autoindex:error] [pid 11307] [client 45.55.21.189:52050] AH01276: Cannot serve directory /var/www/html/: No matching DirectoryIndex (index.html,index.cgi$
[Wed Aug 30 19:11:54.376134 2017] [:error] [pid 11307] [client 45.xx.xx.xx:52050] script '/var/www/html/404.php' not found or unable to stat

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory
[crit] Memory allocation failed, aborting process.
[crit] Memory allocation failed, aborting process.
[Wed Aug 30 20:50:00.570286 2017] [core:notice] [pid 31139] AH00051: child pid 17670 exit signal Aborted (6), possible coredump in /etc/apache2
[crit] Memory allocation failed, aborting process.
[crit] Memory allocation failed, aborting process.
[crit] Memory allocation failed, aborting process.
[crit] Memory allocation failed, aborting process.
[crit] Memory allocation failed, aborting process.
[Wed Aug 30 21:03:27.234926 2017] [core:notice] [pid 31139] AH00051: child pid 18507 exit signal Aborted (6), possible coredump in /etc/apache2
[Wed Aug 30 21:03:27.354905 2017] [core:notice] [pid 31139] AH00051: child pid 18511 exit signal Aborted (6), possible coredump in /etc/apache2
[Wed Aug 30 21:03:27.354927 2017] [core:notice] [pid 31139] AH00051: child pid 18512 exit signal Aborted (6), possible coredump in /etc/apache2
[Wed Aug 30 21:03:42.865027 2017] [core:notice] [pid 31139] AH00051: child pid 18506 exit signal Aborted (6), possible coredump in /etc/apache2
[Wed Aug 30 21:03:46.984235 2017] [core:notice] [pid 31139] AH00051: child pid 18529 exit signal Aborted (6), possible coredump in /etc/apache2
[crit] Memory allocation failed, aborting process.
[crit] Memory allocation failed, aborting process.
[crit] Memory allocation failed, aborting process.
[crit] Memory allocation failed, aborting process.
[Wed Aug 30 21:14:50.194072 2017] [core:notice] [pid 31139] AH00051: child pid 18605 exit signal Segmentation fault (11), possible coredump in /etc/apache2
[Wed Aug 30 21:14:50.482541 2017] [core:notice] [pid 31139] AH00051: child pid 18618 exit signal Aborted (6), possible coredump in /etc/apache2
[Thu Aug 31 07:09:50.271441 2017] [mpm_prefork:notice] [pid 1321] AH00163: Apache/2.4.18 (Ubuntu) configured -- resuming normal operations
[Thu Aug 31 07:09:50.274044 2017] [core:notice] [pid 1321] AH00094: Command line: '/usr/sbin/apache2'

根据AWS上的日志和流量监控,服务器大约在Wed Aug 30 19:11:54左右变得无法访问。

我对Apache如何管理内存和并发连接的工作原理知之甚少。我网站的流量很低。 我可能弄错了什么配置文件吗? 另外,memory_limit-1,按照PHP文档没有限制。 或者我该怎么查找问题的原因,我正在考虑将服务器文件迁移到AWS Beanstalk实例(部署和扩展辅助工具,据我所知)以获得一个全新的开始。

有没有方法可以知道可能导致崩溃的脚本。我有太多的脚本,都运行在laravel PHP框架上,加上第三方脚本会使得很难确定哪个是嫌疑人。

我会非常感激能够解释错误日志的答案,即:

  • 一个脚本做了这个...

  • Apache似乎做了这个...

  • 然后Ubuntu做了这个...

  • 导致了这个...


1
"memory_limit是-1" ...你到底为什么这样做?这个设置是专门为了防止这种问题而存在的,如果你有编写不良脚本的情况。 - arkascha
所以你需要回答的真正问题是:为什么你的php脚本使用了这么多的内存?为了让我们能够帮助你,这肯定意味着你需要描述你正在使用的代码。因此,请添加网站目的的草图以及如何实现它。在你怀疑内存被占用的相关代码部分中添加信息。请使用下面的“编辑”链接将该信息添加到问题中。谢谢! - arkascha
1
那个限制会“杀死”一个失控的脚本。这保护了http服务器本身,以防您将恶意脚本推入其中导致其无响应甚至崩溃系统。设置的限制取决于脚本的目的,显然。对于文本(标记)生成和表单处理,默认值足够小而好。对于图像处理,您可能需要更多。但是通常,这些问题源于脚本尝试将长列表的副本加载到内存中进行处理,而不是遵循顺序处理策略,后者可以很好地扩展。 - arkascha
我现在明白了,我已经将限制设置为一种形式,以防止生产服务器上出现错误/崩溃,同时我仍在本地进行调查。 - Bob Kimani
1
当然,你的脚本存在一些问题。通常这种问题出现在人们查询数据库并尝试一次性获取所有结果条目而不是逐个处理它们时。或者类似的情况。因此,在内存中会同时实例化长列表的元素的副本,而不是一个接一个地释放每个元素之间的内存。 - arkascha
显示剩余3条评论
1个回答

12

借鉴@arkascha在评论中所说,这次崩溃是由于某个脚本使用了大量内存且优化不良所致。

  1. 根据你的运行情况,将php脚本内存限制设为合理值。
  2. 拥有Swap文件非常重要,我没有它,导致在处理内存密集型任务时整个系统崩溃。(在我的情况下,Apache利用了所有可用的1GB内存,直接导致系统崩溃)。 (交换文件基本上是硬盘上的一个文件,用于为已从处理器内存转移的程序提供空间。 相当于额外的RAM,但速度较慢。)
  3. 找到问题的根源(我还没有找到一种技术或工具来概述php的内存使用情况,但我认为有一些可用的方法)。另一种方法是查找具有长查询(多个连接等)的脚本,这通常是问题的原因。
  4. 可能很明显,但也可能不那么明显,为服务器增加更多的RAM。您的Web应用程序可能需要比您当前拥有的更多的内存。
  5. 缓存数据,有很多技术可供选择。基本上,它涉及在不真正需要动态加载的情况下加载静态数据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接