Docker 容器死亡并给出:-bash:fork:retry:资源暂时不可用

Docker 容器死亡并给出:-bash:fork:retry:资源暂时不可用

不确定是否应该在这里或其他社区询问(即超级用户或 Unix&Linux)但暂时会留在这里。

我有一个使用 Selenium 并由 PM2 运行时管理的 dockerised NodeJS 应用程序。该应用程序在 DO 框上运行,1GB记忆 &25 GB磁盘。该应用程序只是使用 Selenium WebDriver 每隔 2 分钟定期从网站抓取数据。不久前我遇到了这个问题,如果我通过 SSH 进入该框,任何命令都会返回:

-bash:fork:重试:资源暂时不可用

设置一个新的 DO 框并进行监控以测量内存使用情况。我的使用量正在逐渐增加,所以我以为是某个地方发生了内存泄漏。试图找到它,但找不到(仍在搜索中)。我看到 PM2 有一个选项如果内存使用量达到一定程度,则重新启动应用程序。作为预防措施,我将其设置为800M (80%)。 我的ecosystem.config.js

module.exports = {
    apps: [
        {
            name: 'scraper',
            script: './index.js',
            watch: process.env.NODE !== 'production',
            ignore_watch: ['node_modules', 'logs', 'test', 'scripts', '.vscode', '.git'],
            out_file: './logs/app.log',
            max_memory_restart: '800M',
            node_args: '--expose-gc',
            env_development: {
                NODE_ENV: 'development'
            },
            env_production: {
                NODE_ENV: 'production'
            }
        }
    ]
}

再看看周围,我发现PM2 可能导致内存泄漏由于没有彻底运行垃圾收集,所以我加入了节点参数,--expose-gc以强制每隔一分钟运行一次垃圾收集(基于这个例子

exports.generateHeapDumpAndStats = function() {
    try {
        if (global.gc) {
            global.gc()
        } else {
            logger.info('Garbage collection unavailable. Use "--expose-gc" when launching to enable forced garbage collection')
        }
        const heapUsed = process.memoryUsage().heapUsed
        const heapUsedMb = (heapUsed / 1024 * 1024).toFixed(2)
        logger.info(`Program is using ${heapUsedMb} MB of heap`)
    } catch (err) {
        logger.error(`Error: ${err.message}`)
        process.exit(1)
    }
}

我以为这会很顺利,因为即使垃圾收集失败,PM2 也会以 80% 的使用率重新启动。我大约在晚上10:45 (格林威治标准时间 +1)从我的使用情况图来看,容器切出了@凌晨 2:00。这是我过去 24 小时的使用情况图表:

在此处输入图片描述

您可以看到内存使用率甚至还不到 80%,那么我是否应该降低重启阈值作为临时措施?

我试图查看盒子本身的内存使用情况,但我输入的任何命令都会出现上述错误。

值得我尝试设置吗--max_old_space_size?我已经看到 NodeJS 进程尝试为自己分配 1.5GB 内存,而我在这个盒子上没有。

我很困惑为什么会发生这种情况。遗憾的是,容器的日志仅写入盒子上的本地文件,因此我现在无法访问它们。

我尝试检查正在运行的容器并且它返回了一些有用的信息:

在此处输入图片描述

我的npm start命令是:

sudo -E pm2-runtime --raw Ecosystem.config.js --env production --only scraper

并完成Dockerfile

FROM selenium/standalone-chrome

WORKDIR /usr/src/app

RUN curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
RUN sudo apt-get install -y nodejs build-essential firefox

# copy package.json & package-lock.json and install packages
# we do this separate from the application code to better use docker's caching
# `npm install` will be cached on future builds if only the app code changed
COPY package*.json ./

RUN sudo npm install pm2 -g
RUN sudo npm install

# ENV vars dynamically set here by CI

# copy the app
COPY . .

# expose port for express & start
EXPOSE 3000
CMD [ "npm", "start"]

如果需要的话,我会根据要求提供代码,只是最初认为没有必要,也不想让问题变得太大:)

笔记: 我最初在 SO 上发布了这个问题,但被要求将其移到这里

编辑

根据 @dirkt 的评论,看起来我可能达到了资源限制。ulimit -a返回我:

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 3842
max locked memory       (kbytes, -l) 16384
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 3842
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

因此,用户有进程限制,我认为这就是我遇到的问题。但是,我不太确定在哪里可以更改此值,我应该将其设置为多少unlimited还是将其提高到任意值?没有设置限制/etc/security/limits.conf。我见过几种方法来更改软/硬ulimitCLI,,limits.conf-user.conf我想后者与我无关,因为我正在运行root用户限制。还值得注意的是,我正在以以下方式运行此 docker 容器:root (将来会改变)

相关内容