प्रतिनिधि इंटरव्यू विषय

Linux इंटरव्यू: आप ज़ॉम्बी प्रोसेस का निदान और समाधान कैसे करेंगे?

सामान्यकठिन
Offer.cc संपादकीय टीमप्रकाशित अपडेट किया गया

प्रश्न

एक Linux सर्विस बार-बार कम समय तक चलने वाली हेल्पर प्रोसेस शुरू करती है। नए जॉब अब बीच-बीच में `fork: Resource temporarily unavailable` के साथ विफल हो रहे हैं; CPU और RSS सामान्य दिख रहे हैं, जबकि `ps` एक ही पैरेंट के तहत `Z` स्थिति में हजारों चाइल्ड प्रोसेस दिखाता है और कंटेनर का `pids.current` `pids.max` के करीब है। आप कारण को कैसे साबित करेंगे, यदि संभव हो तो रीबूट किए बिना सर्विस को कैसे पुनर्स्थापित करेंगे, और होस्ट या कंटेनर में इसकी पुनरावृत्ति को कैसे रोकेंगे?

समस्या विवरण और यह कहाँ लागू होता है

एक Linux सर्विस बार-बार कम समय तक चलने वाले हेल्पर प्रोसेस शुरू करती है। नए जॉब अब रुक-रुक कर fork: Resource temporarily unavailable के साथ विफल हो रहे हैं। CPU और रेजिडेंट मेमोरी सामान्य दिख रहे हैं, लेकिन ps एक ही पैरेंट के तहत Z स्थिति में हजारों चाइल्ड प्रोसेस दिखाता है। एक कंटेनर में, pids.current pids.max के करीब है और pids.events में max काउंटर बढ़ गया है।

बताएं कि ज़ॉम्बी क्या है, यह साबित करें कि क्या अनरीप्ड (unreaped) चाइल्ड प्रोसेस ने विफलताओं का कारण बना, यदि संभव हो तो रीबूट किए बिना सर्विस को पुनर्स्थापित करें, और पुनरावृत्ति को रोकें। एक सामान्य होस्ट और एक कंटेनर दोनों को कवर करें जिसका एप्लिकेशन PID 1 के रूप में चल सकता है। संख्याएं और परिनियोजन (deployment) इंटरव्यू के अनुमान हैं; एक मजबूत उत्तर को अभी भी अन्य सीमाओं का परीक्षण करना चाहिए जो fork() को EAGAIN लौटाने का कारण बन सकती हैं।

यह एक general प्रश्न है क्योंकि इसका मुख्य कौशल Linux प्रोसेस लाइफसाइकिल और इंसिडेंट डायग्नोसिस है। वर्तमान सार्वजनिक Linux इंटरव्यू गाइडों में ज़ॉम्बी-बनाम-ऑर्फन प्रश्न शामिल हैं, जबकि Linux और Docker दस्तावेज़ परिचालन सीमाएं प्रदान करते हैं। यह किसी कंपनी-विशिष्ट संकेत या इंटरव्यू आवृत्ति का संकेत दिए बिना एक प्रतिनिधि और टिकाऊ प्रश्न का समर्थन करता है।

इंटरव्यूअर क्या मूल्यांकन कर रहा है

पहला संकेत यह है कि क्या उम्मीदवार प्रोसेस की स्थिति को रिसोर्स लक्षणों से अलग करता है। एक ज़ॉम्बी प्रोसेस पहले ही समाप्त (terminate) हो चुका होता है। कर्नेल PID, समाप्ति स्थिति (termination status) और अकाउंटिंग जानकारी तब तक बनाए रखता है जब तक कि उसका पैरेंट wait-फैमिली कॉल के साथ उन्हें कलेक्ट नहीं कर लेता। यह न तो सामान्य CPU की खपत करता है और न ही समाप्त प्रोसेस की यूजर-स्पेस मेमोरी की, लेकिन यह अभी भी एक सीमित प्रोसेस-टेबल/PID स्लॉट पर कब्जा करता है।

दूसरा संकेत ओनरशिप (स्वामित्व) है। दोषपूर्ण घटक आमतौर पर वह जीवित पैरेंट प्रोसेस होता है जिसने चाइल्ड प्रोसेस शुरू किए लेकिन उन्हें रीप (reap) करने में विफल रहा। ज़ॉम्बी को SIGKILL भेजने से वह दोबारा एग्जिट नहीं हो सकता। कोई शेल किसी असंबंधित प्रोसेस के चाइल्ड के लिए wait() को भी कॉल नहीं कर सकता। उम्मीदवार को कार्रवाई करने से पहले पैरेंट, उसके सुपरवाइजर, उसकी परिनियोजन इकाई और उसके चाइल्ड-प्रबंधन कोड की पहचान करनी चाहिए।

तीसरा संकेत कारणात्मक निदान (causal diagnosis) है। fork() से EAGAIN का अर्थ प्रति-उपयोगकर्ता RLIMIT_NPROC, सिस्टम-व्यापी threads-max, pid_max, या cgroup pids.max सीमा हो सकता है। ज़ॉम्बी देखना मजबूत सबूत है, इन जांचों को छोड़ने की अनुमति नहीं। थ्रेड्स और असंबंधित प्रोसेस भी उसी सीमा में योगदान दे सकते हैं।

अंतिम संकेत एक ऐसा समाधान है जो बर्स्ट, त्रुटियों, शटडाउन और कंटेनरों में बना रहे। प्रति SIGCHLD केवल एक waitpid() कॉल अपर्याप्त है क्योंकि सिग्नल समेकित (coalesce) हो सकते हैं। पैरेंट को सभी समाप्त हो चुके चाइल्ड प्रोसेस को ड्रेन करना होगा, और एक कंटेनर में एक PID 1 होना चाहिए जो अनाथ (orphaned) वंशजों को सही ढंग से अपनाता है और रीप करता है।

उत्तर देने से पहले स्पष्ट करने योग्य प्रश्न

  • विफलता कहाँ देखी गई है? पूरे होस्ट का आउटेज, एक यूजर अकाउंट, और एक कंटेनर अलग-अलग सीमाओं और प्रभाव क्षेत्रों (blast radii) की ओर इशारा करते हैं।
  • सटीक त्रुटि और सिस्कॉल (syscall) क्या है? EAGAIN एक प्रोसेस/थ्रेड सीमा का सुझाव देता है; ENOMEM या एप्लिकेशन कतार अस्वीकृति एक अन्य मार्ग का अनुसरण करती है।
  • क्या Z प्रविष्टियाँ एक ही PPID के तहत केंद्रित हैं? एक प्रमुख PPID एक ओनरशिप पथ की पहचान करता है। कई PPID एक साझा रैपर या टूटे हुए कंटेनर-इनिट पैटर्न का संकेत दे सकते हैं।
  • क्या पैरेंट जीवित, स्वस्थ और सुपरवाइज्ड है? एक जीवित पैरेंट को ठीक किया जा सकता है या सुरक्षित रूप से पुनरारंभ किया जा सकता है। यदि यह समाप्त हो जाता है, तो चाइल्ड प्रोसेस निकटतम सबरिपर (subreaper) या नेमस्पेस init को रीपैरेंट हो जाते हैं, जिसे बाद में उन्हें रीप करना चाहिए।
  • क्या एप्लिकेशन कंटेनर में PID 1 के रूप में चलता है? PID 1 की अनाथों को रीप करने की अतिरिक्त जिम्मेदारी होती है; रनटाइम को एक छोटे init प्रोसेस की आवश्यकता हो सकती है।
  • क्या ट्रैफ़िक या जॉब इनटेक को ड्रेन किया जा सकता है? नए फोर्क्स को रोकने और इन-फ़्लाइट कार्य को संरक्षित करने के बाद एक नियंत्रित पुनरारंभ सुरक्षित होता है।
  • चाइल्ड एग्जिट से क्या संरक्षित किया जाना चाहिए? एग्जिट कोड, त्रुटि आउटपुट, और पुनर्गणना निर्णय यह निर्धारित करते हैं कि रीपिंग एक ब्लॉकिंग कॉल, इवेंट लूप, वर्कर पूल, या रनटाइम-विशिष्ट प्रोसेस API में संबंधित है या नहीं।

30-सेकंड उत्तर ढांचा

"एक ज़ॉम्बी प्रोसेस पहले ही समाप्त हो चुका होता है; उसके पैरेंट ने एग्जिट स्टेटस कलेक्ट नहीं किया है। मैं Z स्थितियों की गणना करूँगा, उन्हें PPID द्वारा समूहित करूँगा, उस पैरेंट का निरीक्षण करूँगा, और विफल फोर्क्स के साथ समय श्रृंखला को सहसंबंधित करूँगा। मैं RLIMIT_NPROC, threads-max, pid_max, और cgroup के pids.current, pids.max, और pids.events की भी जाँच करूँगा, क्योंकि EAGAIN की कई संभावित सीमाएँ हैं। मैं kill -9 के साथ ज़ॉम्बी को ठीक नहीं कर सकता; मैं नए प्रोसेस निर्माण को रोकूँगा, ट्रैफ़िक को ड्रेन करूँगा, फिर पैरेंट को सुरक्षित रूप से पुनरारंभ या ठीक करूँगा ताकि एक कार्यशील सबरिपर या PID 1 चाइल्ड प्रोसेस को अपनाए और रीप करे। स्थायी रूप से, पैरेंट को waitpid(-1, ..., WNOHANG) को तब तक ड्रेन करना चाहिए जब तक कि कोई समाप्त चाइल्ड न बचे, जिसमें त्रुटि और शटडाउन पथ भी शामिल हैं। कंटेनर में, मैं एक उचित init का भी उपयोग करूँगा जब ऐप PID 1 के कर्तव्यों को पूरा नहीं कर सकता है, फिर बर्स्ट लोड-टेस्ट करूँगा और सत्यापित करूँगा कि ज़ॉम्बी गणना और PID उपयोग सीमित रहे।"

चरण-दर-चरण गहन विश्लेषण

चरण 1: प्रोसेस की स्थिति और ओनर स्थापित करें

उन कमांड्स से शुरुआत करें जो PID हेडरूम कम होने पर बड़ी पाइपलाइन नहीं बनाते हैं:

bash
ps -eo pid=,ppid=,stat=,etime=,comm= | awk '$3 ~ /^Z/'
ps -eo ppid=,stat= | awk '$2 ~ /^Z/ { count[$1]++ } END { for (p in count) print count[p], p }' | sort -nr

ps में, Z से शुरू होने वाला स्टेटस एक ज़ॉम्बी है। /proc/PID/stat स्थिति Z और PPID को भी उजागर करता है। केवल कटे हुए प्रोसेस नाम से अधिक के साथ PPID की पुष्टि करें, फिर जीवित पैरेंट का निरीक्षण करें:

bash
ps -o pid=,ppid=,stat=,lstart=,etime=,cmd= -p PARENT_PID
cat /proc/PARENT_PID/status
cat /proc/PARENT_PID/limits

ज़ॉम्बी की संख्या, नए ज़ॉम्बी बनने की दर, पैरेंट का परिनियोजन संस्करण, और पहली विफलता का समय रिकॉर्ड करें। नियंत्रित शटडाउन के दौरान कुछ समय के लिए छोड़ी गई स्थिर संख्या उस संख्या से भिन्न होती है जो प्रत्येक जॉब के साथ बढ़ती है।

चरण 2: साबित करें कि किस सीमा ने नए चाइल्ड प्रोसेस को अस्वीकार किया

यूजर-फेसिंग वाक्यांश "Resource temporarily unavailable" से "आउट ऑफ मेमोरी" का अनुमान न लगाएं। Linux कई fork() पथों का दस्तावेजीकरण करता है जो EAGAIN लौटाते हैं:

  • वास्तविक यूजर का RLIMIT_NPROC;
  • /proc/sys/kernel/threads-max;
  • /proc/sys/kernel/pid_max;
  • प्रभावी cgroup PIDs सीमा।

cgroup v2 के लिए, रूट पथ मानने के बजाय सर्विस के वास्तविक cgroup में फाइलों की जांच करें:

bash
cat /proc/PARENT_PID/cgroup
cat /sys/fs/cgroup/SERVICE_CGROUP/pids.current
cat /sys/fs/cgroup/SERVICE_CGROUP/pids.max
cat /sys/fs/cgroup/SERVICE_CGROUP/pids.events

बढ़ता हुआ max इवेंट काउंटर सीधे साबित करता है कि फोर्क्स PIDs-कंट्रोलर की सीमा तक पहुँच गए हैं। pids.current की तुलना ज़ॉम्बी संख्या और लाइव थ्रेड/प्रोसेस संख्या से करें; कंट्रोलर वंशजों के सभी कार्यों की गणना करता है, इसलिए केवल ज़ॉम्बी ही उपभोक्ता नहीं हो सकते हैं। होस्ट पर, प्रति-उपयोगकर्ता कार्य गणना और सिस्टम योग की उनकी सीमाओं के साथ भी तुलना करें। कारणात्मक श्रृंखला सबसे मजबूत होती है जब ज़ॉम्बी वृद्धि, शेष PID हेडरूम, EAGAIN, और पैरेंट की स्पॉन दर समय में संरेखित होती है।

चरण 3: बताएं कि सामान्य "समाधान" क्यों विफल होते हैं

kill -9 ZOMBIE_PID एग्जिट लॉजिक नहीं चला सकता क्योंकि प्रोसेस पहले ही समाप्त हो चुका है। शेष कर्नेल रिकॉर्ड तभी गायब होता है जब उसका पैरेंट, या बाद का कोई दत्तक (adopter), उसके लिए प्रतीक्षा करता है। शेल का wait बिल्टइन केवल उस शेल के अपने चाइल्ड प्रोसेस का प्रबंधन करता है।

pids.max, pid_max, या RLIMIT_NPROC को आंख मूंदकर बढ़ाने से रिकवरी का समय मिल सकता है, लेकिन यह रिसाव को सक्रिय रखता है और अगले विफलता प्रभाव क्षेत्र को बढ़ा सकता है। यादृच्छिक लाइव प्रोसेस को समाप्त करने से स्लॉट खाली हो जाते हैं लेकिन पैरेंट ठीक नहीं होता है। रीबूट करने से पूरे प्रोसेस ट्री को नष्ट करके काम तो बन जाता है, लेकिन यह सबूत मिटा देता है और टाले जा सकने वाले डाउनटाइम का कारण बनता है।

स्थिति D को भी अलग पहचानें: एक अनइंटरप्टिबल स्लीपिंग प्रोसेस जीवित होता है और कर्नेल में प्रतीक्षा कर रहा होता है। इसका एक अलग निदान होता है भले ही SIGKILL अप्रभावी प्रतीत हो। प्रत्येक हठी PID को ज़ॉम्बी मान लेना जांच को गलत दिशा में भेज देता है।

चरण 4: नियंत्रित पैरेंट ट्रांज़िशन के साथ सर्विस पुनर्प्राप्त करें

पहले नए जॉब इनटेक को रोकें या थ्रॉटल करें ताकि दोषपूर्ण पैरेंट शेष स्लॉट का उपभोग न कर सके। स्थिति बदलने से पहले एक प्रशासनिक सत्र को सुरक्षित रखें और पैरेंट लॉग, /proc सबूत, सीमाएं और संस्करण की जानकारी एकत्र करें।

यदि पैरेंट के पास एक दस्तावेजीकृत रीलोड है जो इसके चाइल्ड-प्रबंधन लूप को सुरक्षित रूप से फिर से बनाता है, तो उसका उपयोग करें। अन्यथा इन-फ़्लाइट कार्य को ड्रेन करें और उस पैरेंट को उसके सुपरवाइज़र के माध्यम से पुनरारंभ करें। जब पैरेंट समाप्त हो जाता है, तो अनरीप्ड वंशज निकटतम चाइल्ड सबरिपर या PID-नेमस्पेस init द्वारा अपना लिए जाते हैं; एक सही एडॉप्टर उनकी प्रतीक्षा करता है। इनटेक को फिर से खोलने से पहले सत्यापित करें कि ज़ॉम्बी की संख्या कम हो गई है।

यदि एडॉप्टर उन्हें रीप नहीं करता है, तो केवल वर्कर को पुनरारंभ करने से रिकवरी पूरी नहीं होगी। होस्ट पर, सर्विस सुपरवाइजर/सबरिपर का निरीक्षण करें। कंटेनर में, एक नियंत्रित कंटेनर प्रतिस्थापन की आवश्यकता हो सकती है क्योंकि नेमस्पेस PID 1 की अंतिम जिम्मेदारी होती है। PID सीमा बढ़ाना केवल एक प्रलेखित, अस्थायी हेडरूम उपाय के रूप में स्वीकार्य है जिसे थ्रॉटलिंग और एक निश्चित परिनियोजन के साथ जोड़ा गया हो।

चरण 5: ऐसा रीपिंग लागू करें जो बर्स्ट और त्रुटियों को संभाले

एक ऐसे पैरेंट के लिए जिसे तब तक ब्लॉक करना होगा जब तक कि कोई ज्ञात चाइल्ड समाप्त न हो जाए, waitpid(child_pid, ...) को कॉल करें और रुकावट को संभालें। एक एसिंक्रोनस पैरेंट के लिए, इवेंट लूप को जगाने के लिए SIGCHLD की व्यवस्था करें, फिर प्रत्येक उपलब्ध स्थिति को ड्रेन करें:

c
for (;;) {
  pid_t pid = waitpid(-1, &status, WNOHANG);
  if (pid > 0) {
    record_child_result(pid, status);
    continue;
  }
  if (pid == 0) break;
  if (errno == EINTR) continue;
  if (errno == ECHILD) break;
  report_wait_error(errno);
  break;
}

यह लूप सामान्य इवेंट-लूप संदर्भ में होना चाहिए; एक रॉ सिग्नल हैंडलर को केवल रनटाइम के सिग्नल-सुरक्षा नियमों द्वारा अनुमत ऑपरेशन करने चाहिए, अक्सर एक फ्लैग सेट करना या सेल्फ-पाइप में लिखना। ड्रेन करना महत्वपूर्ण है क्योंकि कई चाइल्ड एग्जिट एक अवलोकन योग्य सूचना उत्पन्न कर सकते हैं। स्पॉन और पंजीकरण के बीच की विफलताओं, टाइमआउट, रद्दीकरण, पैरेंट शटडाउन और प्रत्येक पुनर्गणना पथ को कवर करें। प्रबंधित रनटाइम में, समकक्ष नियम अभी भी प्रत्येक चाइल्ड-प्रोसेस पूर्णता की प्रतीक्षा करना या अन्यथा उपभोग करना है।

स्पष्ट रूप से SIGCHLD को अनदेखा करना या SA_NOCLDWAIT का उपयोग करना सहायक प्रणालियों पर स्वचालित सफाई का अनुरोध कर सकता है, लेकिन यह सामान्य एग्जिट-स्टेटस संग्रह को भी हटा देता है और इसके पोर्टेबिलिटी/API परिणाम होते हैं। यह एक जानबूझकर किया गया डिज़ाइन विकल्प है, न कि ऐसे वर्कर मैनेजर के लिए शॉर्टकट जिसे परिणामों की आवश्यकता है।

चरण 6: कंटेनर PID 1 और सत्यापन को सुधार का हिस्सा बनाएं

एक कंटेनर का मुख्य प्रोसेस उन प्रोसेस के लिए ज़िम्मेदार होता है जिन्हें वह शुरू करता है और वंशजों के लिए एडॉप्टर बन सकता है। यदि एप्लिकेशन PID 1 के रूप में सिग्नलों को अग्रेषित और सही ढंग से रीप नहीं कर सकता है, तो इसे रनटाइम की छोटी init सुविधा के तहत चलाएं, जैसे कि Docker का --init या समकक्ष Compose सेटिंग। एक init प्रोसेस एप्लिकेशन को अपने प्रत्यक्ष चाइल्ड प्रोसेस की प्रतीक्षा करने से छूट नहीं देता है जिनके परिणाम उसके पास हैं; यह अनाथ-गोद लेने के अंतर को समाप्त करता है।

मूल समवर्तीता से अधिक के बर्स्ट के साथ सुधार को सत्यापित करें, साथ ही चाइल्ड विफलताओं और तेजी से निकास का परीक्षण करें। स्वीकृति शर्तों में शामिल होना चाहिए:

  1. प्रत्येक शुरू किया गया चाइल्ड एक उपभोग की गई पूर्णता स्थिति उत्पन्न करता है;
  2. प्रत्येक बर्स्ट के बाद ज़ॉम्बी गणना शून्य या एक प्रलेखित संक्षिप्त सीमा पर लौटती है;
  3. pids.current चढ़ने के बजाय स्थिर हो जाता है और pids.events नई सीमा हिट दर्ज नहीं करता है;
  4. अपेक्षित भार पर कोई fork()/spawn EAGAIN नहीं होता है;
  5. शटडाउन चाइल्ड प्रोसेस को ड्रेन या समाप्त करता है और फिर उन्हें रीप करता है;
  6. एक पैरेंट क्रैश वंशजों को एक परीक्षण किए गए सबरिपर या PID 1 के पास छोड़ देता है;
  7. जॉब निर्माण विफल होने से पहले ज़ॉम्बी विकास दर और शेष PID हेडरूम पर अलर्ट सक्रिय होते हैं।

उच्च-गुणवत्ता वाला नमूना उत्तर

"मैं पहले यह सत्यापित करूँगा कि प्रविष्टियाँ वास्तव में स्थिति Z से शुरू होती हैं, उन्हें PPID द्वारा समूहित करूँगा, और प्रमुख जीवित पैरेंट का निरीक्षण करूँगा। एक ज़ॉम्बी प्रोसेस का निष्पादन पूरा हो चुका होता है, इसलिए सामान्य CPU और RSS की अपेक्षा की जाती है। कर्नेल अपनी PID और एग्जिट स्थिति तब तक रखता है जब तक पैरेंट एक wait-फैमिली फ़ंक्शन को कॉल नहीं करता। यही कारण है कि ज़ॉम्बी पर kill -9 अप्रभावी है और पैरेंट ही सुधार का लक्ष्य है।

"मैं तब विफल-फोर्क सीमा को साबित करूँगा। पैरेंट के लिए मैं RLIMIT_NPROC की जाँच करूँगा; होस्ट पर मैं threads-max और pid_max की जाँच करूँगा; सर्विस के cgroup में मैं pids.current, pids.max, और pids.events को पढ़ूँगा। यदि त्रुटि के समय ही max काउंटर बढ़ता है और समूह अपनी सीमा के करीब है, तो यह cgroup वाले हिस्से को साबित करता है। मैं अभी भी लाइव थ्रेड्स और वंशज कार्यों की गणना करूँगा ताकि मैं हर स्लॉट को ज़ॉम्बी के खाते में न डाल दूँ।

"रिकवरी के लिए, मैं नए जॉब्स को थ्रॉटल करूँगा, डायग्नोस्टिक्स को संरक्षित करूँगा, काम को ड्रेन करूँगा, और पैरेंट को उसके सुपरवाइज़र के माध्यम से रीस्टार्ट या रीलोड करूँगा। इसके ज़ॉम्बी को एक कार्यशील सबरिपर या नेमस्पेस PID 1 द्वारा अपनाया और रीप किया जाना चाहिए। यदि कंटेनर PID 1 टूटा हुआ एडॉप्टर है, तो मैं कंटेनर को init-सक्षम कॉन्फ़िगरेशन से बदल दूँगा। सीमा बढ़ाना केवल अस्थायी हेडरूम है।

"स्थायी कोड सुधार प्रत्येक चाइल्ड परिणाम का उपभोग करना है। एक सिंक्रोनस ओनर सटीक PID की प्रतीक्षा करता है। एक इवेंट-संचालित ओनर SIGCHLD को वेक-अप के रूप में मानता है और नॉन-ब्लॉकिंग waitpid() के साथ तब तक लूप करता है जब तक कि कोई पूर्ण चाइल्ड न बचे, साथ ही स्पॉन विफलताओं, रद्दीकरण और शटडाउन को संभालता है। मैं तेजी से निकास, जबरन विफलताओं, पैरेंट क्रैश और ग्रेसफुल शटडाउन का लोड-टेस्ट करूँगा। रिलीज़ तभी पास होती है जब पूर्णता का हिसाब आमने-सामने हो, ज़ॉम्बी सीमित रहें, PID उपयोग स्थिर हो, और कोई नया सीमा इवेंट न हो।"

सामान्य गलतियाँ

  • प्रत्येक ज़ॉम्बी को kill -9 भेजना → चाइल्ड पहले ही समाप्त हो चुका है, इसलिए सिग्नल उसकी एग्जिट स्थिति एकत्र नहीं कर सकता → पैरेंट/एडॉप्टर को पहचानें और ठीक करें, रीलोड करें या रीस्टार्ट करें।
  • इसे मेमोरी लीक कहना → ज़ॉम्बी समाप्त प्रोसेस के सामान्य एड्रेस स्पेस के बजाय कर्नेल बुककीपिंग को बनाए रखते हैं → इसे प्रोसेस-टेबल/PID समाप्ति के रूप में वर्णित करें और वास्तविक सीमित संसाधन को मापें।
  • एक ps स्नैपशॉट से cgroup समाप्ति मान लेना → EAGAIN की कई सीमाएँ हैं और लाइव थ्रेड्स भी टास्क क्षमता का उपभोग करते हैं → सीमाओं, काउंटरों, टास्क काउंट और टाइमस्टैम्प को सहसंबंधित करें।
  • प्रति सिग्नल एक बार waitpid() को कॉल करना → चाइल्ड-एग्जिट सिग्नल समेकित हो सकते हैं, जिससे अतिरिक्त स्थितियाँ अनरीप्ड रह जाती हैं → नॉन-ब्लॉकिंग प्रतीक्षाओं को तब तक ड्रेन करें जब तक कि कॉल यह रिपोर्ट न करे कि कोई तैयार नहीं है।
  • स्थायी सुधार के रूप में pids.max को बढ़ाना → दोषपूर्ण पैरेंट स्लॉट लीक करना जारी रखता है → अतिरिक्त हेडरूम का उपयोग केवल रिकवरी के लिए करें, साथ में थ्रॉटलिंग और एक निर्धारित निश्चित परिनियोजन हो।
  • एक init प्रोसेस जोड़ना और प्रत्यक्ष चाइल्ड प्रोसेस को अनदेखा करना → एप्लिकेशन अभी भी प्रत्यक्ष चाइल्ड परिणामों और पुनर्गणना शब्दार्थ का मालिक है → प्रत्यक्ष बच्चों की प्रतीक्षा करें; PID 1 कर्तव्यों और अपनाए गए वंशजों को संभालने के लिए init का उपयोग करें।
  • सबूत इकट्ठा करने से पहले रीस्टार्ट करना → यह साबित किए बिना घटना गायब हो जाती है कि कौन सी सीमा या कोड पथ विफल हुआ → हेडरूम अनुमति देने पर पहले PPID, सीमाएं, काउंटर, संस्करण, दर और लॉग रिकॉर्ड करें।

फॉलो-अप प्रश्न और उत्तर

क्या होगा यदि व्यावसायिक घंटों के दौरान पैरेंट को पुनरारंभ नहीं किया जा सकता है?

पहले लीक होने वाले पथ को रोकें: जॉब प्रकार को अक्षम करें, समवर्तीता कम करें, या स्वस्थ प्रतिकृतियों को काम रूट करें। यदि नीति अनुमति देती है, तो केवल प्रभावी PIDs सीमा को प्रशासनिक और स्वास्थ्य-जांच क्षमता बनाए रखने के लिए पर्याप्त बढ़ाएं। केवल संख्या के बजाय ढलान की निगरानी करें और एक रूढ़िवादी समाप्ति समय सीमा की गणना करें। एक जीवित पैरेंट अपने बच्चों को केवल तभी रीप कर सकता है जब वह समर्थित मरम्मत कार्रवाई को उजागर करता है या प्राप्त कर सकता है; एक बाहरी प्रोसेस उनकी प्रतीक्षा नहीं कर सकता। अस्थायी हेडरूम का उपभोग होने से पहले एक नियंत्रित पैरेंट ट्रांज़िशन शेड्यूल करें।

क्या होगा यदि ज़ॉम्बी केवल एक कंटेनर के अंदर दिखाई देते हैं?

PID नेमस्पेस दृश्य में प्रवेश करें और नेमस्पेस PID 1 और ज़ॉम्बी के PPID की पहचान करें। होस्ट या ऑर्केस्ट्रेटर से सर्विस के cgroup पथ और PIDs काउंटरों की पुष्टि करें। यदि एप्लिकेशन PID 1 है और रीपिंग/सिग्नल फ़ॉरवर्डिंग लागू नहीं करता है, तो एक छोटी init प्रोसेस तैनात करें। यदि कोई रैपर PID 1 है, तो सत्यापित करें कि यह जल्दी समाप्त नहीं होता है या केवल एक बच्चे की प्रतीक्षा नहीं करता है। कंटेनर समाप्ति का परीक्षण करें ताकि सिग्नल एप्लिकेशन तक पहुंचें, बच्चे बाहर निकलें, और ग्रेस अवधि समाप्त होने से पहले सभी स्थितियां एकत्र हो जाएं।

एक SIGCHLD हैंडलर आह्वान एक चाइल्ड एग्जिट क्यों नहीं है?

पारंपरिक सिग्नल सूचनाएं हैं, प्रति चाइल्ड एक घटना की टिकाऊ कतार नहीं। प्रोसेस द्वारा सिग्नल को संभालने से पहले कई बच्चे बाहर निकल सकते हैं, और सूचनाएं समेकित हो सकती हैं। मजबूत अनुबंध यह है कि "एक अधिसूचना का अर्थ है चाइल्ड स्थिति का निरीक्षण करना," इसके बाद बार-बार गैर-अवरोधक प्रतीक्षाएं तब तक होती हैं जब तक कि कोई पूर्ण चाइल्ड न बचे। एप्लिकेशन प्रत्येक लौटाए गए PID को ठीक एक बार रिकॉर्ड करता है।

क्या SIGCHLD को SIG_IGN पर सेट करने से समस्या हल हो जाएगी?

Linux पर, स्पष्ट रूप से SIGCHLD को अनदेखा करना या SA_NOCLDWAIT सेट करना ज़ॉम्बी व्यवहार को बदल देता है, लेकिन एप्लिकेशन तब wait() के माध्यम से सामान्य एग्जिट स्थिति एकत्र करने पर भरोसा नहीं कर सकता है। डिफ़ॉल्ट स्वभाव को "अनदेखा" के रूप में वर्णित किया जाना स्पष्ट रूप से SIG_IGN स्थापित करने के समान नहीं है। इस मोड का उपयोग केवल तब करें जब चाइल्ड परिणामों का वास्तव में कोई व्यावसायिक मूल्य न हो और भाषा/रनटाइम अनुबंध सत्यापित हो; वर्कर प्रबंधकों को आम तौर पर स्पष्ट पूर्णता लेखांकन की आवश्यकता होती है।

उपयोगकर्ताओं को विफल फोर्क्स दिखने से पहले आप कैसे सचेत करेंगे?

पैरेंट द्वारा समूहीकृत निरंतर सकारात्मक ज़ॉम्बी-विकास दर, कम शेष cgroup PID हेडरूम, pids.events:max में वृद्धि, और स्पॉन विफलताओं पर अलर्ट करें। उन संकेतों को जॉब थ्रूपुट के साथ जोड़ें ताकि एक वैध छोटा बर्स्ट अकेले संख्या से पेज न करे। सुपरवाइज़र, टेलीमेट्री और रिकवरी कमांड के लिए पर्याप्त हेडरूम आरक्षित करें, फिर गैर-उत्पादन नेमस्पेस में नियंत्रित रिसाव के खिलाफ अलर्ट का परीक्षण करें।

सार्वजनिक स्रोत

संबंधित प्रश्न