内存不足杀手导致引导失败

大家好,

我想通过运行 ./launcher rebuild app 来更新我的 Discourse。它之前运行正常,大约有一年了。我通常每 2-4 周进行一次更新,以确保系统处于最新状态。

我的系统是 Ubuntu 18.04.5 LTS:

***@***:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.5 LTS
Release:        18.04
Codename:       bionic

今天更新时出现了以下错误并停止:

FAILED
--------------------
Pups::ExecError: cd /var/www/discourse && su discourse -c 'bundle exec rake themes:update assets:precompile' failed with return #<Process::Status: pid 726 exit 1>
Location of failure: /pups/lib/pups/exec_command.rb:112:in `spawn'
exec failed with the params {"cd"=>"$home", "hook"=>"assets_precompile", "cmd"=>["su discourse -c 'bundle exec rake themes:update assets:precompile'"]}
db6d1b1dd685de69942a3df05c9cbd622860faaa286b042635878519d5b69b7b
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one.
./discourse-doctor may help diagnose the problem.

该消息之前的第一个错误是:

<--- JS stacktrace --->

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: 0xa04200 node::Abort() [node]
 2: 0x94e4e9 node::FatalError(char const*, char const*) [node]
 3: 0xb7978e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
 4: 0xb79b07 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
 5: 0xd34395  [node]
 6: 0xd46c01 v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [node]
 7: 0xd0c472 v8::internal::Factory::AllocateRaw(int, v8::internal::AllocationType, v8::internal::AllocationAlignment) [node]
 8: 0xd086c2 v8::internal::FactoryBase<v8::internal::Factory>::AllocateRawArray(int, v8::internal::AllocationType) [node]
 9: 0xd08774 v8::internal::FactoryBase<v8::internal::Factory>::NewFixedArrayWithFiller(v8::internal::Handle<v8::internal::Map>, int, v8::internal::Handle<v8::internal::Oddball>, v8::internal::AllocationType) [node]
10: 0xf4ef4b v8::internal::OrderedHashTable<v8::internal::OrderedHashSet, 1>::Allocate(v8::internal::Isolate*, int, v8::internal::AllocationType) [node]
11: 0xf4f0df v8::internal::OrderedHashTable<v8::internal::OrderedHashSet, 1>::Rehash(v8::internal::Isolate*, v8::internal::Handle<v8::internal::OrderedHashSet>, int) [node]
12: 0x103eb98 v8::internal::Runtime_SetGrow(int, unsigned long*, v8::internal::Isolate*) [node]
13: 0x1401219  [node]
Aborted (core dumped)
rake aborted!
Errno::ENOENT: No such file or directory @ rb_file_s_size - /var/www/discourse/public/assets/discourse/tests/test_helper-a9cbc4e1abdd1f2e9afced86d051cbd63c2e224dafe782533646a01592cc1f42.js
/var/www/discourse/lib/tasks/assets.rake:290:in `size'
/var/www/discourse/lib/tasks/assets.rake:290:in `block (4 levels) in <main>'
/var/www/discourse/lib/tasks/assets.rake:181:in `block in concurrent?'
/var/www/discourse/lib/tasks/assets.rake:281:in `block (3 levels) in <main>'
/var/www/discourse/lib/tasks/assets.rake:272:in `each'
/var/www/discourse/lib/tasks/assets.rake:272:in `block (2 levels) in <main>'
/var/www/discourse/lib/tasks/assets.rake:181:in `concurrent?'
/var/www/discourse/lib/tasks/assets.rake:269:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => assets:precompile
(See full trace by running task with --trace)
I, [2021-04-26T13:10:13.996101 #1]  INFO -- : Downloading MaxMindDB...
Compressing Javascript and Generating Source Maps

I, [2021-04-26T13:10:14.018697 #1]  INFO -- : Terminating async processes
I, [2021-04-26T13:10:14.020721 #1]  INFO -- : Sending INT to HOME=/var/lib/postgresql USER=postgres exec chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/13/bin/postmaster -D /etc/postgresql/13/main pid: 55
I, [2021-04-26T13:10:14.022854 #1]  INFO -- : Sending TERM to exec chpst -u redis -U redis /usr/bin/redis-server /etc/redis/redis.conf pid: 172
172:signal-handler (1619442614) Received SIGTERM scheduling shutdown...
2021-04-26 13:10:14.023 UTC [55] LOG:  received fast shutdown request
2021-04-26 13:10:14.030 UTC [55] LOG:  aborting any active transactions
2021-04-26 13:10:14.043 UTC [55] LOG:  background worker "logical replication launcher" (PID 64) exited with exit code 1
2021-04-26 13:10:14.045 UTC [59] LOG:  shutting down
2021-04-26 13:10:14.073 UTC [55] LOG:  database system is shut down
172:M 26 Apr 2021 13:10:14.122 # User requested shutdown...
172:M 26 Apr 2021 13:10:14.123 * Saving the final RDB snapshot before exiting.
172:M 26 Apr 2021 13:10:14.270 * DB saved on disk
172:M 26 Apr 2021 13:10:14.271 # Redis is now ready to exit, bye bye...

更新失败后,Discourse 无法运行。只有重启服务器后 Discourse 才能再次运行,但此时再次运行 rebuild app 时仍会出现相同的错误。

您能和我一起排查一下这个问题吗?

此致

您的服务器在引导过程中内存不足。您能分享一下 free -m 的输出吗?

1 个赞

@:~# free -m
total used free shared buff/cache available
Mem: 985 777 70 49 136 44
Swap: 2047 228 1819

嗯,我很好奇为什么重启后内存也会耗尽。自上次更新以来,我并没有安装任何额外的软件。

我遇到了同样的问题,nodejs 内存不足。
我使用了 export NODE_OPTIONS="--max_old_space_size=4096 --some_other_option",但没有效果。

在尝试重新构建时也出现了相同的堆栈跟踪。这是一个相对较新的安装,我仅用于开发和测试,所以我认为应该还有足够的空间?

操作系统: Ubuntu 20.04.1 LTS
free -m 输出:

root@discourse-test-environment:/var/discourse# free -m
              total        used        free      shared  buff/cache   available
Mem:            981         136         581           0         263         698
Swap:          2047         113        1934
1 个赞

这略低于 1GB 的最低要求。你可以尝试稍微增加交换空间,但我更建议增加内存。

如果你遇到这个错误,就需要更多内存(或者可能是交换空间,但内存更好)。

3 个赞

好的,但能否告知我们出现这种新行为的原因?该配置已稳定运行一年多。现在的 Discourse 与过去相比有何不同?

1 个赞

谢谢你的推荐。确实有点奇怪,我通常在使用 $5 的 Digital Ocean Droplet 时,默认的 2GB 交换文件就够用了。我会留意一下这是否会随着最新更新变得更常见。

不管怎样,我已经按照 这个链接 添加了一个更大的交换文件(4GB)。

但升级仍然失败了。也许增加内存是必须的。这有点出乎意料,因为目前该实例只有 1 个主题和 1 个用户。另外,我很好奇是否需要做某些设置让 Discourse 使用交换空间,还是说它默认就能访问?

这是我新的 free -m 输出:

              total        used        free      shared  buff/cache   available
Mem:            981         138         576           0         266         703
Swap:          6143         109        6034
1 个赞

没错,我也在使用 Digital Ocean 的 Droplet,配置为 1 个 vCPU 和 1GB vRAM :slight_smile:

1 个赞

我已将交换内存增加到 3GB,但问题仍未解决,错误信息相同。

1 个赞

我能够在仅使用 2.5GiB 内存加交换空间的情况下重建我的测试实例。不过,您的实例可能需要更多的资源。

您是否安装了任何插件?我怀疑其中某个插件在编译过程中导致了巨大的内存占用。

能否在不安装插件的情况下尝试重建,看看是否能解决问题?

感谢你的参与!

出于好奇,内存和交换空间的具体分配比例是多少?你计算的是两者中“可用”的空间,还是交换文件总大小加上实例的总内存?

哦,对了,我差点忘了提,我希望能安装 Discourse OpenID Connect 认证插件

目前还安装了 Data Explorer 插件


  • 再次尝试仅安装 Data Explorer 和 Docker Manager,但仍未成功,报错堆栈与之前分享的一致。
  • 再次尝试不安装任何插件(仅保留 Docker Manager),重建仍然失败。

我会继续查找原因,因为除了尝试添加 ConnectID 插件外,自最初安装以来我未进行其他任何更改。

我在 Trouble with `tests/test_helper`? - #2 遇到了一个可能相关的问题。

我尝试在不使用任何插件的情况下重新构建应用,但没有任何变化,错误依旧。

我不太明白这是怎么回事,但这看起来像是一个 bug。我正在尝试对这个站点进行引导。没有使用任何非标准插件。我只是将资源从一个存储桶移动到了另一个,一切正常。我正在进行最后一次重建,以便在环境变量中添加 DISCOURSE_S3_UPLOAD_BUCKET,这样它就不会显示在用户界面中。第一次失败后,我注释掉了那一行,并再次尝试使用三天前有效的相同配置。


Done compressing embed-application-9cef8308c816fc1d83137e63d6c556c6cc2b68fe2b6e5ce16cca6766ba2c0ae4.js : 0.17 secs

844614.350963717 Compressing: discourse/tests/test_helper-8590b31b8e73c4172aeea4a4a6bd1930ccbce2547a20d831a30d457ba092a631.js
terser '/var/www/discourse/public/assets/discourse/tests/_test_helper-8590b31b8e73c4172aeea4a4a6bd1930ccbce2547a20d831a30d457ba092a631.js' -m -c -o '/var/www/discourse/public/assets/discourse/tests/test_helper-8590b31b8e73c4172aeea4a4a6bd1930ccbce2547a20d831a30d457ba092a631.js' --source-map "base='/var/www/discourse/public/assets/discourse/tests',root='/assets/discourse/tests',url='https://CORRECT_CDN_ADDRESS.b-cdn.net/assets/discourse/tests/test_helper-8590b31b8e73c4172aeea4a4a6bd1930ccbce2547a20d831a30d457ba092a631.js.map'"
Killed
rake aborted!
Errno::ENOENT: No such file or directory @ rb_file_s_size - /var/www/discourse/public/assets/discourse/tests/test_helper-8590b31b8e73c4172aeea4a4a6bd1930ccbce2547a20d831a30d457ba092a631.js
/var/www/discourse/lib/tasks/assets.rake:290:in `size'
/var/www/discourse/lib/tasks/assets.rake:290:in `block (4 levels) in <main>'
/var/www/discourse/lib/tasks/assets.rake:181:in `block in concurrent?'
/var/www/discourse/lib/tasks/assets.rake:281:in `block (3 levels) in <main>'
/var/www/discourse/lib/tasks/assets.rake:272:in `each'
/var/www/discourse/lib/tasks/assets.rake:272:in `block (2 levels) in <main>'
/var/www/discourse/lib/tasks/assets.rake:181:in `concurrent?'
/var/www/discourse/lib/tasks/assets.rake:269:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => assets:precompile
(See full trace by running task with --trace)
I, [2021-04-26T18:38:36.072881 #1]  INFO -- : Updating Discourse Loading Slider...
Downloading MaxMindDB...
Compressing Javascript and Generating Source Maps

我怀疑是否是 CDN URL 出了问题,但上面所有行都包含了该 URL 并且运行正常。

这是否意味着他们的主题中存在有问题的 CSS?如果是的话,那可真糟糕。他们的主题中只包含了一些 CSS,此外还有这些组件:https://github.com/discourse/DiscoTOC.githttps://github.com/davidtaylorhq/discourse-loading-slider.git

这是最小规格的 Droplet 吗?看起来该文件对 Terser 来说压缩难度较大,会导致严重的内存压力。

哦。这出乎意料地小。我想这是你们几年前搭建的一个站点(当时你们还在自己的基础设施之外运营站点)。

root@community:/var/discourse# free -h
              total        used        free      shared  buff/cache   available
Mem:           1.9G        1.2G        101M        259M        655M        354M
Swap:          2.0G        1.2G        773M

啊,好的。这是一台 2GB 的 DigitalOcean 实例(droplet),我可以访问他们的控制面板。我会告诉他们我们需要升级到 4GB,并将他们迁移到 AMD 架构。

编辑:但如果这只是为了压缩那个文件,2GB 的实例应该就够了吧?

这个测试辅助文件对压缩的压力很大。

  • UglifyJS 压缩它需要占用 1.5GB 内存。
  • Terser 占用略高于 1GB,耗时 40 秒。相比之下,同一台服务器处理 Ember+jQuery 仅需 8 秒 :scream:

@eviltrout 我们真的需要在生产环境中保留这个文件吗?

哦,看起来它来自 @Osama 的这次更改:

-rw-r--r-- 1 discourse discourse  14M Apr 26 19:13 _test_helper-f4c4b5bf0657eab910d85b9a65b4bddbbbe2ce2ba603b17fe11b3d633d324e34.js
-rw-r--r-- 1 discourse discourse 6.6M Apr 26 19:14 test_helper-f4c4b5bf0657eab910d85b9a65b4bddbbbe2ce2ba603b17fe11b3d633d324e34.js
-rw-r--r-- 1 discourse discourse 1.1M Apr 26 19:14 test_helper-f4c4b5bf0657eab910d85b9a65b4bddbbbe2ce2ba603b17fe11b3d633d324e34.js.br
-rw-r--r-- 1 discourse discourse 1.5M Apr 26 19:14 test_helper-f4c4b5bf0657eab910d85b9a65b4bddbbbe2ce2ba603b17fe11b3d633d324e34.js.gz
-rw-r--r-- 1 discourse discourse 5.7M Apr 26 19:14 test_helper-f4c4b5bf0657eab910d85b9a65b4bddbbbe2ce2ba603b17fe11b3d633d324e34.js.map
8 个赞

再补充一个数据点——在移除了两个主题组件后,我仍然遇到重建失败的问题。目前仅使用默认的 Light 主题。

另外,这个输出来自哪里?我也想在自己的环境中进行一些验证和调试。这是否类似于 ./launcher rebuild app 的某个详细输出选项?

要彻底修复这个问题还需要一点时间,所以我暂时先回滚该更改。

9 个赞