首页 > 解决方案 > Heroku PHP 立即消耗所有内存

问题描述

我有一个 Heroku 1X 测功机,它在重新启动时会立即消耗所有内存。

这是日志中的重启:

2020-05-18T16:57:54.119229+00:00 app[web.1]: Stopping php-fpm...
2020-05-18T16:57:54.119814+00:00 app[web.1]: Stopping httpd gracefully...
2020-05-18T16:57:54.121897+00:00 app[web.1]: Stopping httpd...
2020-05-18T16:57:54.131154+00:00 app[web.1]: Shutdown complete.
2020-05-18T16:57:54.194178+00:00 heroku[web.1]: Process exited with status 143
2020-05-18T16:57:57.194751+00:00 app[web.1]: Detected 536870912 Bytes of RAM
2020-05-18T16:57:57.231186+00:00 app[web.1]: PHP memory_limit is 4M Bytes
2020-05-18T16:57:57.245920+00:00 app[web.1]: Starting php-fpm with 128 workers...
2020-05-18T16:57:57.386605+00:00 app[web.1]: Starting httpd...
2020-05-18T16:57:58.220510+00:00 heroku[web.1]: State changed from starting to up

我的 procfile 只是:

web: vendor/bin/heroku-php-apache2

我的 .user.ini 是:

memory_limit = 4M

这些代码都没有设置为在后台运行,它只是一个处理请求的 API。然而,它会立即消耗最大内存并抛出 R14 错误,有 0 个请求进入。https://share.getcloudapp.com/GGukb5QZ

有人知道会发生什么吗?

标签: phpheroku

解决方案


这是您需要阅读的文档:https ://devcenter.heroku.com/articles/php-concurrency

你用你的评论回答了这个问题“我可以通过增加 memory_limit 来减少内存下限(这样它就不会在启动时占用所有内存)。”

TL;DR,Heroku 说:

  • 我有多少内存?(您有 512MB)
  • 每个 PHP 进程的最大内存量(您设置为 4MB)
  • 将两者分开并启动那么多工人(你得到 128)

这个计算忽略了运行 HTTP 和其他进程的开销。正如该页面所阐明的那样,“故意选择这些默认值以不留下任何“空间”……因为应用程序极不可能消耗其全部内存限制……这意味着默认情况下测功机略微超额订阅。”

通常,如果您将限制设置为 128MB = 4 个工作进程,这并不重要:

  • 每个 php 进程 128MB,但平均只使用 100MB(这是巨大的 :))
  • 每个 http 进程添加 1MB = 101MB
  • 乘以 4 = 404MB
  • 添加日志记录、日志轮换、SSH 和所有其他数百个进程的开销,比如说 40MB
  • 总计 = 404 + 40 = 444MB < 512MB。
  • 如果每个进程仅使用 3.5MB = 大量备用。
  • 耶!

但是,您有:

  • 每个 php 进程 4MB,平均仅使用 3.5MB(检查PHP 中的 memory-get-peak-usage
  • 每个 http 进程添加 1MB = 4.5MB
  • 乘以 128 = 576MB
  • 添加日志记录、日志轮换、SSH 和所有其他数百个进程的开销,比如说 40MB
  • 总计 = 576 + 40 = 616MB > 512MB。
  • Heroku 开始内存管理。

您需要找到合适的平衡点,例如设置为 8M = 64 个进程,就像您所做的那样。


注意:关于开销和 HTTP 进程的陈述是一种简化,仅用于说明目的。

配置 FPM 有点像噩梦,因为您可以运行多个池,每个池都有初始工作人员和备用工作人员。https://www.php.net/manual/en/install.fpm.configuration.php

Heroku 试图为您简化这一点。


推荐阅读