<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Docker的僵尸進(jìn)程問題

          共 2083字,需瀏覽 5分鐘

           ·

          2021-03-04 11:36

          2b0f75c62b42bef26517490493cdd28e.webp

          最近因為是招聘旺季,我自己作的產(chǎn)品<橙子簡歷>[1]的用戶量增長很大,從而暴露出了不少的問題。這次記錄一下昨天剛解決的一個問題: Docker容器中的僵尸進(jìn)程問題。

          背景

          首先說一下引起問題的程序組件: puppeteer。這個組件主要是用來渲染簡歷的,puppeteer其實只是一個node library,真正在后臺工作的其實就是chrome瀏覽器。那么在調(diào)用puppeteer執(zhí)行任務(wù)的過程中,它會生成一個chrome的子進(jìn)程。而我在幾個月之前將橙子簡歷整體遷移到了Docker環(huán)境中,之后就經(jīng)常收到類似"Resource temporarily unavailable"的報錯。因為報錯不是很頻繁,我又忙于其他工作,所以對這個問題沒有仔細(xì)研究,只是去服務(wù)器上查看了一下內(nèi)存占用情況,發(fā)現(xiàn)是有可用內(nèi)存的。最近因為用戶量的上漲,這個問題日益嚴(yán)重,所以昨天就花了一些時間研究了一下。

          研究

          首先,我用ps命令查看了一下機器上的進(jìn)程情況,發(fā)現(xiàn)有大量的chrome[defunct]進(jìn)程。而且通過我進(jìn)一步測試,每當(dāng)我渲染一次簡歷,這種進(jìn)程就會增長,而且不會減少。所以我覺得初步就可以認(rèn)為是這些"僵尸進(jìn)程"占用了系統(tǒng)資源,從而不能再生成子進(jìn)程。

          僵尸進(jìn)程

          關(guān)于僵尸進(jìn)程,我這里只做一下簡單的介紹,更多細(xì)節(jié)可以參考[Wikipedia[2]] 。

          在Linux(包括其他Unix系統(tǒng),以下只用Linux代指)中,所有進(jìn)程是一個樹狀結(jié)構(gòu),每個進(jìn)程都會有一個父進(jìn)程(最頂層的那個進(jìn)程除外)以及多個子進(jìn)程。這里最頂層的那個進(jìn)程是比較特殊的,它有一個專屬的名稱:init進(jìn)程[3]。init進(jìn)程的PID總是為1。在現(xiàn)代的Linux環(huán)境中,這個init進(jìn)程一般會是systemd或者upstartd等重量級的進(jìn)程,它們會做很多額外的工作。

          Linux對進(jìn)程的管理有一個機制,當(dāng)一個進(jìn)程調(diào)用exit退出的的時候,首先它的內(nèi)存和其他系統(tǒng)資源會被操作系統(tǒng)自動回收。但是有一項資源不會被自動回收:進(jìn)程的PID。Linux內(nèi)核中有一張表(process table)存儲所有進(jìn)程相關(guān)的信息,而為了使父進(jìn)程可以得到子進(jìn)程的退出狀態(tài),只有當(dāng)父進(jìn)程調(diào)用了wait來讀取子進(jìn)程的退出狀態(tài)之后,才會在process table中刪除已退出進(jìn)程的PID,這個PID才可以被重新使用。而上面提到的init進(jìn)程就會有一項重要的工作:調(diào)用wait,從而保證不會有僵尸進(jìn)城產(chǎn)生。

          所以到這里,大家應(yīng)該可以猜到,之前的"Resource temporarily unavailable"的問題就是僵尸進(jìn)程占滿了process table引起的。我通過docker exec命令進(jìn)入容器中查看了一下進(jìn)程情況,發(fā)現(xiàn)PID為1的進(jìn)程是node,它不具備回收僵尸進(jìn)程的功能,所以會不斷的產(chǎn)生僵尸進(jìn)程。而Linux中默認(rèn)最大的PID是32768,所以僵尸進(jìn)程雖然不會占用內(nèi)存等其他資源,但對PID的占用會導(dǎo)致系統(tǒng)不能spawn新的子進(jìn)程。這個問題是非常嚴(yán)重的。

          修復(fù)

          接下來要修復(fù)這個問題,我在網(wǎng)上搜了一下資料,發(fā)現(xiàn)一篇不錯的文章[4]。這個問題的核心原因就是在docker環(huán)境中不存在"正常的init進(jìn)程"(因為docker的理念是一個容器只運行一個worker進(jìn)程)。那么解決問題的方式也很直接:給docker容器加一個init進(jìn)程。這個init進(jìn)程只需要做好signal的處理以及僵尸進(jìn)程的回收就好了,所以我們不需要給它加一個重量級的systemd的系統(tǒng)。文章中的解決方案是自己寫了一個輕量級的init進(jìn)程,文章在最后也寫到了,希望Docker官方可以解決這個問題。很幸運的是,現(xiàn)在的Docker已經(jīng)在官方層面解決了這個問題,只需要在docker run中加入--init參數(shù)即可,參考docker run init[5]。
          當(dāng)然,如果你像我一樣使用docker-compose來運行docker,那么在docker-compose.yml文件中 加入init: true參數(shù)即可,參考compose-file init[6]

          參考資料

          [1]

          <橙子簡歷>: https://wonderfulcv.com

          [2]

          [Wikipedia: https://en.wikipedia.org/wiki/Zombie_process

          [3]

          init進(jìn)程: https://en.wikipedia.org/wiki/Init

          [4]

          文章: https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/

          [5]

          這里: https://docs.docker.com/engine/reference/run/#specify-an-init-process

          [6]

          這里: https://docs.docker.com/compose/compose-file/compose-file-v3/#init


          瀏覽 94
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  热久久蜜芽 | 五月天亚洲综合 | 大香蕉中文娱乐网 | 奇米影视一区二区三区 | 美女极度色诱图片www视频 |