Docker 容器死掉並給予:-bash: fork: retry: 資源暫時無法使用

Docker 容器死掉並給予:-bash: fork: retry: 資源暫時無法使用

不確定是在這裡還是其他社區問這個問題(即超級用戶或 Unix&Linux)但暫時留在這裡。

我有一個使用 Selenium 的 Dockerized NodeJS 應用程序,並由 PM2 運行時管理。該應用程式在 DO 盒上運行1GB記憶 &25GB磁碟.該應用程式只是使用 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 (將來會改變)

相關內容