प्रॉम्प्ट और लागू संदर्भ
एक Linux HTTP सर्विस Kubernetes कंटेनर में चल रही है। रोलिंग अपडेट के दौरान इसे SIGTERM 30-सेकंड की ग्रेस अवधि के साथ प्राप्त होता है, जबकि 200 रिक्वेस्ट्स इन-फ्लाइट हैं, दो चाइल्ड वर्कर्स चल रहे हैं, और एक बैकग्राउंड-जॉब कंज्यूमर एक्टिव है। सिग्नल डिलीवरी से लेकर प्रोसेस एग्जिट तक का शटडाउन प्रोटोकॉल डिज़ाइन करें। SIGTERM और SIGKILL का व्यवहार, सिग्नल-हैंडलर सुरक्षा, ट्रैफ़िक ड्रेनिंग, जॉब और चाइल्ड-प्रोसेस हैंडलिंग, डेडलाइन और सत्यापन की व्याख्या करें।
30 सेकंड और 200 रिक्वेस्ट्स इंटरव्यू परिदृश्य के इनपुट हैं। Kubernetes आमतौर पर 30-सेकंड की डिफ़ॉल्ट Pod टर्मिनेशन ग्रेस अवधि का उपयोग करता है, लेकिन प्रोडक्शन वैल्यूज मापी गई रिक्वेस्ट अवधि, क्लीनअप समय, वर्कलोड सिमेंटिक्स और उपलब्धता आवश्यकताओं से आनी चाहिए। इस परिदृश्य में, 25-सेकंड की आंतरिक ड्रेन डेडलाइन का उपयोग करें और अंतिम क्लीनअप और शेड्यूलिंग वेरिएंस के लिए पाँच सेकंड आरक्षित रखें। यह विभाजन एक इंजीनियरिंग विकल्प है, कोई प्लेटफ़ॉर्म गारंटी नहीं।
मुख्य समस्या Linux प्रोसेस-लाइफसाइकिल प्रोटोकॉल है। Kubernetes और HTTP ऑपरेटिंग संदर्भ प्रदान करते हैं। एक मजबूत उत्तर कर्नेल से लक्षित प्रोसेस तक सिग्नल को ट्रैक करता है, इसे एक सुरक्षित स्टेट ट्रांज़िशन में बदलता है, एडमिशन और इन-फ्लाइट काम को नियंत्रित करता है, और साबित करता है कि टर्मिनेशन डेडलाइन के भीतर रहता है।
इंटरव्यूअर क्या मूल्यांकन करता है
पहला, इंटरव्यूअर सिग्नल सिमेंटिक्स की जाँच करता है। एक प्रोसेस SIGTERM को कैच, ब्लॉक या इग्नोर कर सकती है; इसका डिफ़ॉल्ट एक्शन टर्मिनेशन है। एक बार जब कोई एप्लिकेशन इसे कैच कर लेता है, तो एप्लिकेशन को अंततः खुद को समाप्त करना होगा। SIGKILL को कैच, ब्लॉक या इग्नोर नहीं किया जा सकता, इसलिए यह क्लीनअप का कोई अवसर प्रदान नहीं करता। दोहराए गए मानक सिग्नल एक ड्यूरेबल कतार नहीं हैं: एक ही मानक सिग्नल के कई पेंडिंग इंस्टेंसेस संयोजित (coalesce) हो सकते हैं।
दूसरा, इंटरव्यूअर यह जाँचता है कि सिग्नल सर्विस तक पहुँचता है या नहीं। एक कंटेनर में, शेल-फॉर्म एंट्री पॉइंट /bin/sh -c को PID 1 के रूप में छोड़ सकता है और निष्पादन योग्य फ़ाइल (एग्जीक्यूटेबल) को अपेक्षित SIGTERM प्राप्त करने से रोक सकता है। सर्विस को सामान्य रूप से exec-फॉर्म एंट्री पॉइंट होना चाहिए, या एक रैपर को exec के साथ समाप्त होना चाहिए। एक सर्विस जो बच्चों (चाइल्ड प्रोसेस) को बनाती है, उसे भी टर्मिनेशन को आगे अग्रेषित (फॉरवर्ड) करना चाहिए और उन्हें रीप करना चाहिए, या जब वह स्वयं PID 1 कर्तव्यों का पालन नहीं कर सकती है तो एक उपयुक्त टाइनी इनिट के साथ चलना चाहिए।
तीसरा, इंटरव्यूअर एक async-signal-safe बाउंड्री की तलाश करता है। एक रॉ C सिग्नल हैंडलर सामान्य निष्पादन को किसी भी निर्देश पर बाधित करता है। printf को कॉल करना, मेमोरी एलोकेट करना, म्यूटेक्स लेना, एप्लिकेशन ऑब्जेक्ट ग्राफ़ को बंद करना, या क्लाइंट लाइब्रेरी को फ्लश करना डेडलॉक कर सकता है या स्टेट को दूषित कर सकता है। हैंडलर को केवल सिग्नल-सुरक्षित ऑपरेशन्स का उपयोग करके एक न्यूनतम सूचना प्रकाशित करनी चाहिए; सामान्य कंट्रोल पाथ क्लीनअप का स्वामित्व रखता है।
चौथा, इंटरव्यूअर शटडाउन क्रम का मूल्यांकन करता है। सर्विस को अनरेडी हो जाना चाहिए और नए काम को स्वीकार करना बंद कर देना चाहिए, फिर डेडलाइन के तहत स्वीकृत काम को ड्रेन या कैंसिल करना चाहिए। इसे लीज़ का स्वामित्व खोए बिना जॉब इनटेक को रोकना चाहिए, साझा डिपेंडेंसी को तब तक खुला रखना चाहिए जब तक कि उनके उपयोगकर्ता समाप्त न हो जाएं, बच्चों को समाप्त और रीप करना चाहिए, सीमित टेलीमेट्री फ्लश निष्पादित करना चाहिए, और ऑर्केस्ट्रेटर द्वारा SIGKILL तक एस्केलेट करने से पहले एग्जिट होना चाहिए।
अंत में, इंटरव्यूअर ऑपरेशनल प्रमाण चाहता है। केवल एक हैंडलर यूनिट टेस्ट कंटेनर PID लेआउट, एंडपॉइंट हटाने, कनेक्शन व्यवहार, जॉब पुनः वितरण (रीडिलीवरी), चाइल्ड रीपिंग, या ग्रेस अवधि के अनुपालन को साबित नहीं कर सकता है। उत्तर में देखने योग्य पास मानदंडों के साथ कंटेनर-स्तरीय और रोलआउट-स्तरीय परीक्षण शामिल होने चाहिए।
उत्तर देने से पहले स्पष्ट करने योग्य प्रश्न
- सिग्नल कौन भेजता है, और किस PID को? कंटेनर रनटाइम, कॉन्फ़िगर किए गए स्टॉप सिग्नल, एंट्री पॉइंट, रैपर्स की पुष्टि करें और क्या एप्लिकेशन PID 1 है।
- 30 सेकंड क्या उपयोग करता है? एक Kubernetes
preStopहुक उसी टर्मिनेशन ग्रेस अवधि के भीतर चलता है। इसकी अवधि एप्लिकेशन ड्रेनिंग के लिए बचे समय को कम कर देती है। - "इन-फ्लाइट" का क्या अर्थ है? स्वीकृत रिक्वेस्ट्स, बिना किसी रिक्वेस्ट के कीप-अलाइव कनेक्शन, स्ट्रीमिंग रिस्पॉन्स, अपग्रेडेड कनेक्शन और कतारबद्ध एप्लिकेशन कार्य को अलग करें। उन्हें अलग-अलग पूर्णता नीतियों की आवश्यकता होती है।
- क्या सर्विस नए काम को तुरंत अस्वीकार कर सकती है? रेडीनेस प्रोब, लोड बैलेंसर, लिसनर, सर्विस मेश और किसी भी डायरेक्ट कॉलर की पहचान करें। रेडीनेस प्रोपेगेशन तात्कालिक नहीं होता है।
- रिक्वेस्ट-अवधि और पुनरावृत्ति (रीट्राई) अनुबंध क्या हैं? एक छोटा आइडम्पोटेंट रीड समाप्त हो सकता है; एक लंबे अपलोड या साइड-इफ़ेक्ट वाले राइट को रद्दीकरण, हैंडऑफ़, या एक आइडम्पोटेन्सी की आवश्यकता हो सकती है।
- बैकग्राउंड जॉब्स का स्वामित्व कैसे होता है? पावती (एक्नॉलेजमेंट) समय, दृश्यता टाइमआउट या लीज़, हार्टबीट व्यवहार, रीडिलीवरी और आइडम्पोटेन्सी को स्पष्ट करें। इस अनुबंध के बिना "वर्कर को रोकना" असुरक्षित है।
- चाइल्ड वर्कर्स का मालिक कौन है? निर्धारित करें कि क्या पैरेंट प्रोसेस ग्रुप को सिग्नल भेज सकता है, क्या बच्चों का अपना शटडाउन प्रोटोकॉल है, और
waitpidको कौन कॉल करता है। - कौन सा रनटाइम सिग्नल्स को हैंडल करता है? एक समर्पित
sigwaitथ्रेड, एक इवेंट-लूप कॉलबैक, और एक रॉ C हैंडलर की अलग-अलग सुरक्षा सीमाएँ होती हैं। वास्तविक रनटाइम व्यवहार बताएं। - कौन सा परिणाम सफलता को परिभाषित करता है? नए एडमिशन्स, पूरे किए गए और रद्द किए गए काम, डुप्लिकेट साइड इफेक्ट्स, ज़ॉम्बी प्रोसेस, एग्जिट समय और जबरन-टर्मिनेशन दर के लिए सीमाएं निर्धारित करें।
30-सेकंड का उत्तर फ़्रेमवर्क
"मैं सत्यापित करता हूँ कि एक exec-फॉर्म एंट्री पॉइंट एप्लिकेशन को SIGTERM डिलीवर करता है। रॉ हैंडलर केवल सामान्य कंट्रोल पाथ को जगाता है। वह पाथ रेडीनेस को फ़ेल करता है, रिक्वेस्ट और जॉब एडमिशन को रोकता है, और स्वीकृत काम को 25-सेकंड की आंतरिक डेडलाइन तक ड्रेन करता है। फिर यह बचे हुए काम को सुरक्षित रूप से रद्द करता है, दोनों बच्चों को समाप्त और रीप करता है, सीमित अंतिम फ्लश निष्पादित करता है, और 30-सेकंड की ग्रेस अवधि समाप्त होने से पहले एग्जिट हो जाता है। SIGKILL क्लीनअप नहीं चला सकता। मैं एक साथ आने वाली रिक्वेस्ट्स और जॉब्स के तहत निर्मित कंटेनर का परीक्षण करता हूँ, जिसमें एडमिशन कटऑफ़, रीट्राई व्यवहार, चाइल्ड रीपिंग और एग्जिट समय की जाँच की जाती है।"
यह फ़्रेमवर्क कंट्रोल फ़्लो स्थापित करता है। विस्तृत उत्तर में मल्टीथ्रेडेड सिग्नल डिलीवरी, इंटरप्टेड सिस्टम कॉल्स, बार-बार शटडाउन अनुरोध और एंडपॉइंट हटाने और लिसनर एडमिशन के बीच अंतर को भी शामिल किया जाना चाहिए।
चरण-दर-चरण विस्तृत विश्लेषण
डिलीवरी पाथ से शुरुआत करें। ENTRYPOINT या CMD के निष्पादन योग्य फ़ॉर्म का उपयोग करें ताकि एप्लिकेशन सीधे रनटाइम का स्टॉप सिग्नल प्राप्त करे। यदि सेटअप के लिए एक रैपर की आवश्यकता है, तो इसे exec "$@" के साथ समाप्त करें। केवल Dockerfile पर भरोसा करने के बजाय चल रहे कंटेनर का निरीक्षण करें: PID 1, इसकी कमांड लाइन, पैरेंट-चाइल्ड संबंधों और कॉन्फ़िगर किए गए स्टॉप सिग्नल को सत्यापित करें। एक रोलआउट परीक्षण जो कंटेनर को SIGTERM भेजता है, निर्णायक जाँच है।
हैंडलर इंस्टॉल करने से पहले वेक-अप तंत्र को इनिशियलाइज़ करें, और रेडीनेस का विज्ञापन करने से पहले हैंडलर इंस्टॉल करें। एक C-आकार का स्केच नॉन-ब्लॉकिंग सेल्फ़-पाइप का उपयोग कर सकता है:
static volatile sig_atomic_t stop_requested = 0;
static int wake_fd; /* initialized as nonblocking before sigaction */
static void on_term(int signo) {
int saved_errno = errno;
stop_requested = 1;
const unsigned char byte = 1;
(void)write(wake_fd, &byte, sizeof byte);
errno = saved_errno;
}write async-signal-safe है। नॉन-ब्लॉकिंग डिस्क्रिप्टर हैंडलर को प्रतीक्षा करने से रोकता है यदि सूचनाएं पहले से ही पाइप को भर देती हैं; फ़्लैग स्थिति को सुरक्षित रखता है भले ही वेक-अप राइट कोई अन्य बाइट न जोड़ सके। हैंडलर लॉग नहीं करता, मेमोरी एलोकेट नहीं करता, लॉक नहीं करता, बच्चों की प्रतीक्षा नहीं करता, या एप्लिकेशन क्लाइंट्स को कॉल नहीं करता। साधारण इवेंट लूप पाइप को खाली करता है और एक आइडम्पोटेंट शटडाउन स्टेट मशीन को आगे बढ़ाता है।
मल्टीथ्रेडेड सर्विस के लिए एक विकल्प वर्कर थ्रेड्स बनाने से पहले टर्मिनेशन सिग्नल्स को ब्लॉक करना है, फिर एक समर्पित थ्रेड को sigwait कॉल करने दें या Linux पर signalfd का उपयोग करने दें। सिग्नल डिस्पोज़िशन पूरे प्रोसेस में होती है, जबकि प्रत्येक थ्रेड का अपना सिग्नल मास्क होता है। एक प्रोसेस-निर्देशित सिग्नल किसी भी थ्रेड को डिलीवर किया जा सकता है जो इसे ब्लॉक नहीं करता है। केंद्रीकृत सिंक्रोनस सिग्नल हैंडलिंग एप्लिकेशन कोड से एसिंक्रोनस हैंडलर को हटा देती है, बशर्ते थ्रेड्स शुरू होने से पहले सिग्नल मास्क लगातार स्थापित किए जाएं।
सर्विस को जगाने के लिए केवल एक बाधित (interrupted) सिस्टम कॉल पर निर्भर न रहें। इंटरफ़ेस और SA_RESTART के आधार पर, एक ब्लॉकिंग कॉल स्वचालित रूप से फिर से शुरू हो सकती है या EINTR लौटा सकती है। सेल्फ़-पाइप, इवेंट डिस्क्रिप्टर, रनटाइम सिग्नल चैनल, या समर्पित सिग्नल थ्रेड एक स्पष्ट वेक-अप पाथ बनाता है। शटडाउन में प्रत्येक ब्लॉकिंग वेट की एक डेडलाइन भी होनी चाहिए।
सर्विस को स्पष्ट स्टेट्स के माध्यम से चलाएं:
RUNNING
--SIGTERM--> QUIESCING
--admission closed--> DRAINING
--work finished or 25 s reached--> FINALIZING
--children reaped and bounded flush complete--> EXITEDRUNNING से ट्रांज़िशन परमाणु (atomic) और आइडम्पोटेंट होना चाहिए। पहला SIGTERM प्रारंभ समय और डेडलाइन रिकॉर्ड करता है। एक दूसरा SIGTERM दूसरा क्लीनअप ग्राफ़ शुरू नहीं करना चाहिए या उसी संसाधन को दो बार बंद नहीं करना चाहिए। टीम यह चुन सकती है कि यह केवल एक पुनरावृत्ति रिकॉर्ड करता है या ड्रेन को छोटा करता है, लेकिन व्यवहार का दस्तावेजीकरण और परीक्षण किया जाना चाहिए।
QUIESCING पर, रेडीनेस को फ़ेल करें और नए एप्लिकेशन एडमिशन को तुरंत रोकें। Kubernetes एक टर्मिनेटिंग एंडपॉइंट को अनरेडी चिह्नित करता है, लेकिन कंट्रोल-प्लेन और प्रॉक्सी प्रोपेगेशन में समय लगता है। लिसनिंग सॉकेट को बंद करें, स्वीकार को अक्षम करें, या एडमिशन लेयर को उन रिक्वेस्ट्स के लिए रीट्राई करने योग्य प्रतिक्रिया वापस करने के लिए कहें जो स्वीकृत-कार्य सीमा को पार नहीं कर पाई हैं। मौजूदा स्वीकृत कनेक्शन ड्रेनिंग के लिए खुले रह सकते हैं। HTTP कीप-अलाइव को स्पष्ट रूप से हैंडल करें ताकि एक निष्क्रिय पुराना कनेक्शन शटडाउन शुरू होने के बाद असीमित नई रिक्वेस्ट्स सबमिट न कर सके।
उसी सीमा पर बैकग्राउंड कंज्यूमर को नए जॉब लाने से रोकें। पहले से लीज़ पर ली गई जॉब के लिए, तभी जारी रखें जब वह डेडलाइन से पहले सुरक्षित रूप से समाप्त हो सके। अन्यथा हार्टबीट बंद करें या कतार के अनुबंध का उपयोग करके लीज़ को रिलीज़/nack करें ताकि दूसरा वर्कर पुन: प्रयास कर सके। पावती (एक्नॉलेजमेंट) ड्यूरेबल समाप्ति के बाद ही होनी चाहिए। साइड इफेक्ट्स को आइडम्पोटेन्सी कीज़ या ट्रांज़ेक्शनल स्टेट ट्रांज़िशन की आवश्यकता होती है क्योंकि जबरन टर्मिनेशन बाहरी राइट के बाद और पावती से पहले हो सकता है।
DRAINING पर, एक काउंटर या रजिस्ट्री के साथ स्वीकृत कार्य को ट्रैक करें। रिक्वेस्ट्स को पूरा होने दें जबकि उनकी डिपेंडेंसी उपलब्ध रहें। जब तक रिक्वेस्ट हैंडलर अभी भी उनका उपयोग कर रहे हों, डेटाबेस पूल, कैश क्लाइंट, या टेलीमेट्री एक्सपोर्टर को बंद न करें। 25-सेकंड की आंतरिक डेडलाइन पर, प्रोटोकॉल के अनुसार शेष कार्य को रद्द करें: स्ट्रीमिंग बंद करें, रद्दीकरण का प्रसार करें, जहाँ संभव हो एक परिभाषित प्रतिक्रिया लौटाएं, और पुन: प्रयास करने योग्य स्थिति को सुसंगत छोड़ें। रद्दीकरण कॉलबैक, चाइल्ड रीपिंग, अंतिम स्थिति राइट्स और रनटाइम शेड्यूलिंग वेरिएंस के लिए शेष पाँच सेकंड आरक्षित रखें।
दो चाइल्ड वर्कर्स के लिए, पहले उनका इनपुट रोकें, उनका सहमत टर्मिनेशन सिग्नल भेजें, और एक डेडलाइन के साथ प्रतीक्षा करें। यदि पैरेंट का एक समर्पित प्रोसेस ग्रुप है, तो वह असंबंधित प्रक्रियाओं से बचते हुए उस ग्रुप को सिग्नल दे सकता है। प्रत्येक एग्जिट हुए बच्चे को waitpid के साथ रीप करें ताकि कोई ज़ॉम्बी न बचे। एक टाइनी इनिट उस कंटेनर के लिए सिग्नल अग्रेषण और रीपिंग प्रदान कर सकता है जिसका एप्लिकेशन ऐसा नहीं कर सकता है, लेकिन यह एप्लिकेशन के जॉब या रिक्वेस्ट सिमेंटिक्स को परिभाषित नहीं करता है।
FINALIZING पर, अंतिम शटडाउन मेट्रिक्स उत्सर्जित करें और एक सख्त समय बजट के तहत लॉग या ट्रेस फ्लश करें। ऑब्ज़र्वेबिलिटी जबरन एग्जिट की व्याख्या करने में मदद करती है, फिर भी एक अनुपलब्ध टेलीमेट्री बैकएंड को कभी भी पूरी ग्रेस अवधि का उपभोग नहीं करना चाहिए। डिपेंडेंसी क्रम में शेष संसाधनों को बंद करें और एक पूर्ण ग्रेसफुल शटडाउन के लिए एग्जिट स्टेटस शून्य लौटाएं। यदि प्रोसेस प्लेटफ़ॉर्म डेडलाइन से चूक जाती है, तो Kubernetes अंततः रनटाइम को SIGKILL भेजने के लिए कहता है; उस बिंदु के बाद कोई हैंडलर, डिफर्ड ब्लॉक, या शटडाउन हुक नहीं चलता है।
सिग्नल्स का उपयोग कंट्रोल नोटिफिकेशन्स के रूप में करें, कार्य संदेशों के रूप में नहीं। मानक सिग्नल संयोजित हो सकते हैं, उनमें बहुत कम पेलोड होता है, और वे अप्रत्याशित कोड स्थानों में आ सकते हैं। कार्य, पुनरावृत्ति और ड्यूरेबल स्वामित्व को कतारों या स्टेट स्टोर्स में रखें। सिग्नल केवल स्थानीय लाइफसाइकिल ट्रांज़िशन को शुरू या एस्केलेट करता है।
सत्यापन में उसी सीमा का प्रयोग करना चाहिए जिसका उपयोग प्रोडक्शन में किया जाता है:
- वास्तविक इमेज बनाएं, PID 1 का निरीक्षण करें, सर्विस शुरू करें, और आंतरिक शटडाउन एंडपॉइंट को इनवोक करने के बजाय कंटेनर को
SIGTERMभेजें। - 200 मिश्रित-अवधि की रिक्वेस्ट्स को रोककर रखें, जिसमें वह कार्य शामिल है जो 25 सेकंड के भीतर समाप्त होता है और वह कार्य जिसे रद्द किया जाना चाहिए। दावा करें कि कटऑफ के बाद किसी भी रिक्वेस्ट को नया एडमिट नहीं किया गया है और प्रत्येक स्वीकृत रिक्वेस्ट का एक रिकॉर्डेड अंतिम परिणाम है।
- पुष्टि करें कि रेडीनेस फ़ाल्स हो जाती है और एंडपॉइंट प्रोपेगेशन के बाद पुराने Pod को कोई नया रोलआउट ट्रैफ़िक प्राप्त नहीं होता है। एक सीधे कनेक्शन का भी परीक्षण करें ताकि लिसनर एडमिशन का स्वतंत्र रूप से सत्यापन हो सके।
- टर्मिनेशन के दौरान लीज़ पर लिए गए बैकग्राउंड जॉब्स चलाएं। सत्यापित करें कि पूर्ण कार्य को एक बार स्वीकार किया गया है, अधूरा कार्य पुन: प्रयास के लिए योग्य हो जाता है, और डुप्लिकेट डिलीवरी व्यावसायिक प्रभाव को डुप्लिकेट नहीं कर सकती है।
- सत्यापित करें कि दोनों चाइल्ड वर्कर्स को टर्मिनेशन प्राप्त होता है, वे अपनी डेडलाइन तक एग्जिट होते हैं, और उन्हें रीप किया जाता है। ज़ॉम्बीज़ के लिए प्रोसेस टेबल का निरीक्षण करें।
- दूसरा
SIGTERMभेजें और साबित करें कि क्लीनअप आइडम्पोटेंट रहता है। अलग सेSIGKILLभेजें ताकि यह साबित हो सके कि किसी क्लीनअप का अनुमान नहीं लगाया गया है और रिकवरी अनुबंध अभी भी ड्यूरेबल काम की रक्षा करते हैं। shutdown_started, एडमिशन स्टेट, इन-फ़्लाइट काउंट, ड्रेन-डेडलाइन उल्लंघन, चाइल्ड स्टेटस, एग्जिट समय और ज़बरन टर्मिनेशन रिकॉर्ड करें। यदि ग्रेसफुल एग्जिट 30 सेकंड तक पहुँचता है तो परीक्षण को फ़ेल करें।
उच्च-गुणवत्ता वाला नमूना उत्तर
"मैं कंटेनर सीमा से शुरुआत करूँगा। मैं एक exec-फॉर्म एंट्री पॉइंट का उपयोग करूँगा और रनटाइम पर इमेज का निरीक्षण करूँगा ताकि यह सत्यापित किया जा सके कि HTTP सर्विस PID 1 है या किसी इनिट के पीछे है जो सिग्नल्स को फॉरवर्ड करता है। एक शेल रैपर exec के साथ समाप्त होगा, ताकि SIGTERM शेल पर न रुके।
रेडीनेस ट्रू होने से पहले, सर्विस अपना सिग्नल पाथ इंस्टॉल करेगी। एक रॉ C हैंडलर में मैं केवल एक sig_atomic_t फ़्लैग सेट करूँगा और एक नॉन-ब्लॉकिंग सेल्फ़-पाइप में लिखूँगा। लॉगिंग, म्यूटेक्स, मेमोरी एलोकेशन, डेटाबेस कॉल और चाइल्ड वेट उस हैंडलर से बाहर रहेंगे। एक मल्टीथ्रेडेड कार्यान्वयन में मैं वर्कर्स बनाने से पहले टर्मिनेशन सिग्नल्स को ब्लॉक करना और उन्हें एक sigwait थ्रेड से उपभोग करना पसंद करूँगा। कोई भी डिज़ाइन EINTR पर निर्भर होने के बजाय सामान्य कंट्रोल लूप को स्पष्ट रूप से जगाता है।
पहला SIGTERM सर्विस को रनिंग से क्वीसिंग में एटॉमिक रूप से ले जाता है और 25 सेकंड बाद एक आंतरिक डेडलाइन तय करता है। सर्विस तुरंत रेडीनेस को फ़ेल करती है, नए एडमिशन को बंद या अक्षम करती है, कीप-अलाइव कनेक्शन को अधिक रिक्वेस्ट्स शुरू करने से रोकती है, और बैकग्राउंड जॉब्स लाना बंद कर देती है। रेडीनेस को हटाना और एडमिशन बंद करना दोनों आवश्यक हैं क्योंकि एंडपॉइंट प्रोपेगेशन एसिंक्रोनस होता है।
200 स्वीकृत रिक्वेस्ट्स जारी रह सकती हैं जबकि उनके डेटाबेस और कैश क्लाइंट खुले रहते हैं। मैं उन्हें सीधे ट्रैक करता हूँ। 25 सेकंड से पहले पूरी होने वाली रिक्वेस्ट्स सामान्य रूप से वापस आती हैं। आंतरिक डेडलाइन पर, मैं एप्लिकेशन प्रोटोकॉल के माध्यम से बाकियों को रद्द करता हूँ और पुन: प्रयास करने योग्य स्थिति को सुरक्षित रखता हूँ। जॉब कंज्यूमर के लिए, मैं केवल ड्यूरेबल पूर्णता को स्वीकार करता हूँ; अधूरे लीज़ वाले काम को कतार अनुबंध के अनुसार रिलीज़ किया जाता है या समाप्त होने दिया जाता है, और उनके साइड इफेक्ट्स आइडम्पोटेन्सी कीज़ का उपयोग करते हैं।
फिर मैं दोनों चाइल्ड वर्कर्स को उनके परिभाषित सिग्नल पाथ के माध्यम से समाप्त करता हूँ और एक सीमित प्रतीक्षा के साथ उन्हें रीप करता हूँ। रिक्वेस्ट और चाइल्ड यूज़र्स के चले जाने के बाद ही मैं शेयर्ड क्लाइंट्स को बंद करता हूँ। लॉग और ट्रेस को एक छोटा सीमित फ्लश बजट प्राप्त होता है। एक सफल पाथ 30 सेकंड से पहले ज़ीरो एग्जिट करता है। यदि वह डेडलाइन छूट जाती है, तो SIGKILL प्रोसेस को समाप्त कर सकता है और कोई क्लीनअप कोड नहीं चलेगा, इसलिए ड्यूरेबल शुद्धता अंतिम हुक पर निर्भर नहीं हो सकती है।
सत्यापन के लिए, मैं 200 समवर्ती मिश्रित-अवधि की रिक्वेस्ट्स और सक्रिय लीज़्ड जॉब्स के साथ निर्मित कंटेनर चलाता हूँ, फिर इसे SIGTERM भेजता हूँ। मैं दावा करता हूँ कि वास्तविक प्रोसेस सिग्नल प्राप्त करती है, रेडीनेस बदलती है, कोई नया काम एडमिशन सीमा को पार नहीं करता है, स्वीकृत काम 25 सेकंड तक पूरा होता है या स्पष्ट रूप से रद्द कर दिया जाता है, अधूरे जॉब डुप्लिकेट प्रभावों के बिना पुन: प्रयास कर सकते हैं, दोनों बच्चों को रीप किया जाता है, और प्रोसेस 30 सेकंड से पहले एग्जिट हो जाती है। मैं आइडम्पोटेन्सी के लिए बार-बार SIGTERM और रिकवरी व्यवहार के लिए SIGKILL का भी परीक्षण करता हूँ। रोलआउट डैशबोर्ड को शटडाउन अवधि, इन-फ्लाइट कार्य, डेडलाइन उल्लंघन और जबरन निकास को प्रदर्शित करना चाहिए।"
सामान्य गलतियाँ
- रॉ हैंडलर के अंदर क्लीनअप करना → सिग्नल कोड को बाधित कर सकता है जबकि एक लाइब्रेरी लॉक या एलोकेटर स्टेट सक्रिय है → एक न्यूनतम सिग्नल-सुरक्षित अधिसूचना प्रकाशित करें और सामान्य कंट्रोल पाथ पर क्लीनअप करें।
- यह मान लेना कि एप्लिकेशन
SIGTERMप्राप्त करता है → एक शेल-फॉर्म एंट्री पॉइंट शेल को PID 1 के रूप में रख सकता है → exec फ़ॉर्म याexecमें समाप्त होने वाले रैपर का उपयोग करें, फिर निर्मित कंटेनर का परीक्षण करें। - रेडीनेस विफलता को एडमिशन क्लोज़र के रूप में मानना → एंडपॉइंट अपडेट में समय लगता है और प्रत्यक्ष या मौजूदा कनेक्शन अभी भी काम भेज सकते हैं → रेडीनेस को फ़ेल करें और एप्लिकेशन लिसनर/एडमिशन कटऑफ लागू करें।
- शेयर्ड क्लाइंट्स को पहले बंद करना → इन-फ्लाइट हैंडलर एडमिशन के बाद विफल हो सकते हैं भले ही उनके पास समाप्त करने का समय था → उपयोगकर्ताओं को उनकी ज़रूरत के संसाधनों को बंद करने से पहले ड्रेन करें।
- लीज़ की जाँच किए बिना जॉब कंज्यूमर को रोकना → काम अदृश्य रह सकता है, बहुत जल्दी स्वीकार किया जा सकता है, या साइड इफेक्ट्स दोहराए जा सकते हैं → पावती, लीज़, पुनरावृत्ति और आइडम्पोटेन्सी अनुबंधों का स्पष्ट रूप से पालन करें।
- एक आदर्श ड्रेन के लिए हमेशा प्रतीक्षा करना → ऑर्केस्ट्रेटर अंततः
SIGKILLभेजता है और सभी क्लीनअप अवसरों को हटा देता है → अंतिम रूप देने के लिए आरक्षित समय के साथ एक आंतरिक डेडलाइन का उपयोग करें। - चाइल्ड ओनरशिप को भूल जाना → बच्चे पैरेंट से थोड़े समय के लिए अधिक जीवित रह सकते हैं या रीप न होने पर ज़ॉम्बी बन सकते हैं → टर्मिनेशन को जानबूझकर अग्रेषित करें और एक सीमित
waitpidलूप का उपयोग करें। - बार-बार सिग्नलों पर दो बार क्लीनअप शुरू करना → डुप्लिकेट क्लोज़ और फ्लश ऑपरेशन्स रेस या क्रैश कर सकते हैं → स्टेट ट्रांज़िशन को एटॉमिक और क्लीनअप को आइडम्पोटेंट बनाएं।
- मानक सिग्नल्स को कमांड कतार के रूप में उपयोग करना → समान पेंडिंग मानक सिग्नल संयोजित हो सकते हैं और कोई ड्यूरेबल ओनरशिप नहीं रखते → काम और पुनरावृत्ति को कतार में स्टोर करें; केवल लाइफसाइकिल नियंत्रण के लिए सिग्नल का उपयोग करें।
- केवल एक आंतरिक शटडाउन मेथड का परीक्षण करना → यह PID लेआउट, रनटाइम सिग्नल डिलीवरी और ऑर्केस्ट्रेशन व्यवहार को बायपास करता है → यथार्थवादी समवर्ती कार्य के तहत प्रोडक्शन इमेज को वास्तविक सिग्नल भेजें।
फ़ॉलो-अप प्रश्न और उत्तर
फ़ॉलो-अप 1: सिग्नल हैंडलर सामान्य शटडाउन फ़ंक्शन को कॉल क्यों नहीं कर सकता?
हैंडलर प्रोग्राम को बाधित कर सकता है जबकि दूसरा थ्रेड या बाधित थ्रेड एलोकेटर, stdio, लॉगिंग, या एप्लिकेशन लॉक रखता है। अधिकांश एप्लिकेशन क्लीनअप फ़ंक्शन async-signal-safe नहीं हैं। उन्हें कॉल करने से डेडलॉक हो सकता है या आंतरिक स्थिति दूषित हो सकती है। हैंडलर को एक फ़्लैग सेट करना चाहिए और सिग्नल-सुरक्षित वेक-अप ऑपरेशन का उपयोग करना चाहिए; इवेंट लूप या एक समर्पित सिग्नल थ्रेड बाद में सामान्य शटडाउन कोड को इनवोक करता है।
फ़ॉलो-अप 2: मल्टीथ्रेडेड प्रोसेस में सिग्नल्स कैसे व्यवहार करते हैं?
सिग्नल डिस्पोज़िशन प्रोसेस द्वारा साझा किया जाता है, लेकिन प्रत्येक थ्रेड का अपना सिग्नल मास्क होता है। एक प्रोसेस-निर्देशित सिग्नल किसी भी योग्य अनब्लॉक किए गए थ्रेड को दिया जा सकता है। एक मजबूत पैटर्न वर्कर्स बनने से पहले टर्मिनेशन सिग्नल्स को ब्लॉक करता है और एक थ्रेड को sigwait या signalfd के साथ उन्हें सिंक्रोनस रूप से प्राप्त करने देता है। दूसरा एक न्यूनतम प्रोसेस-व्यापी हैंडलर का उपयोग करता है जो केवल एक सुरक्षित सूचना पोस्ट करता है। मिश्रित और असंगत मास्क व्यवहार को समझना कठिन बनाते हैं।
फ़ॉलो-अप 3: यहाँ SIGTERM और SIGKILL के बीच व्यावहारिक अंतर क्या है?
SIGTERM टर्मिनेशन का अनुरोध करता है और एप्लिकेशन को अपना प्रोटोकॉल चलाने का मौका देता है क्योंकि इसे कैच किया जा सकता है। इसका डिफ़ॉल्ट एक्शन अभी भी प्रोसेस को समाप्त करता है। SIGKILL कर्नेल द्वारा लागू टर्मिनेशन है: इसे कैच, ब्लॉक या इग्नोर नहीं किया जा सकता है, और कोई क्लीनअप नहीं चलता है। ग्रेस अवधि केवल तभी मूल्यवान होती है जब SIGTERM पाथ सुलभ, सुरक्षित और सीमित हो।
फ़ॉलो-अप 4: रेडीनेस को फ़ेल क्यों करें और एडमिशन को भी बंद क्यों करें?
रेडीनेस परिवर्तन Kubernetes और इसके प्रॉक्सी को रूटिंग रोकने के लिए कहते हैं, लेकिन एंडपॉइंट अपडेट और कनेक्शन ड्रेनिंग एसिंक्रोनस हैं। मौजूदा कीप-अलाइव या डायरेक्ट कनेक्शन अभी भी प्रोसेस तक पहुँच सकते हैं। एप्लिकेशन कटऑफ उस सटीक बिंदु को परिभाषित करता है जिसके बाद नया काम प्रवेश नहीं कर सकता है, जबकि रेडीनेस Pod को सामान्य रूटिंग से हटा देती है। सत्यापन में दोनों लेयर्स का निरीक्षण किया जाना चाहिए।
फ़ॉलो-अप 5: आधे पूरे हो चुके काम का क्या होना चाहिए?
जॉब के ओनरशिप अनुबंध का उपयोग करें। केवल तभी जारी रखें जब यह आंतरिक डेडलाइन से पहले सुरक्षित रूप से समाप्त हो सके। अन्यथा इसकी लीज़ को रोकें या रिलीज़ करें ताकि इसे पुन: प्रयास किया जा सके, और ड्यूरेबल पूर्णता से पहले इसे स्वीकार करने से बचें। बाहरी साइड इफेक्ट्स के लिए एक आइडम्पोटेन्सी की या ट्रांज़ेक्शनल स्टेट ट्रांज़िशन की आवश्यकता होती है क्योंकि साइड इफेक्ट और पावती के बीच टर्मिनेशन हो सकता है।
फ़ॉलो-अप 6: जब एक preStop हुक मौजूद होता है तो क्या बदलता है?
हुक उसी Pod टर्मिनेशन ग्रेस अवधि का उपभोग करता है। इसके सबसे खराब स्थिति की अवधि को मापें और इसे एप्लिकेशन बजट से घटाएं। हुक को सीमित रखें और दो प्रतिस्पर्धी पाथ्स में एप्लिकेशन क्लीनअप को दोहराने से बचें। एप्लिकेशन को अभी भी SIGTERM को हैंडल करना चाहिए, क्योंकि हुक विफल हो सकते हैं और प्रोसेस सामान्य रोलआउट के बाहर सिग्नल प्राप्त कर सकते हैं।
फ़ॉलो-अप 7: आप प्रोडक्शन में ज़बरन टर्मिनेशन की जांच कैसे करेंगे?
Pod टर्मिनेशन कारण और टाइमस्टैम्प को एप्लिकेशन शटडाउन-शुरुआत समय, इन-फ्लाइट संख्या, जॉब लीज़, चाइल्ड स्थिति और अंतिम पूर्ण शटडाउन स्थिति के साथ सहसंबंधित करें। छूटी हुई सिग्नल डिलीवरी को स्लो ड्रेन, अटके हुए बच्चे, या ब्लॉक किए गए अंतिम फ्लश से अलग करें। वर्शन के अनुसार ग्रेसफुल शटडाउन अवधि और जबरन-एग्जिट दर को ट्रैक करें ताकि कैनरी रोलआउट के दौरान कोई रिग्रेशन दिखाई दे।