SIGKILL के माध्यम से समाप्त करने के लिए छोटी गाड़ी प्रणाली सेवा को कॉन्फ़िगर करें


20

पृष्ठभूमि

मुझे systemdएक नई सेवा के लिए एक स्क्रिप्ट बनाने के लिए कहा गया है foo_daemon, जो कभी-कभी एक "खराब स्थिति" में हो जाती है, और SIGTERM(कस्टम सिग्नल हैंडलर के कारण) होने की संभावना नहीं होगी । डेवलपर्स के लिए यह समस्याग्रस्त है, क्योंकि उन्हें सेवा शुरू / बंद करने / फिर से शुरू करने का निर्देश दिया जाता है:

  • systemctl start foo_daemon.service
  • systemctl stop foo_daemon.service
  • systemctl restart foo_daemon.service

मुसीबत

कभी-कभी, foo_daemonएक बुरी स्थिति में होने के कारण , हमें जबरन इसे मारना पड़ता है:

  • systemctl kill -s KILL foo_daemon.service

सवाल

मैं अपनी systemdस्क्रिप्ट को कैसे सेट कर सकता हूं foo_daemonताकि, जब भी कोई उपयोगकर्ता सेवा को रोकने / पुनः आरंभ करने का प्रयास systemdकरेगा , वह करेगा:

  • के foo_daemonमाध्यम से एक सुंदर बंद का प्रयास करें SIGTERM
  • शटडाउन / समाप्ति के लिए 2 सेकंड तक का समय दें foo_daemon
  • यदि प्रक्रिया अभी भी जीवित है, तो इसके foo_daemonमाध्यम से एक मजबूर शटडाउन का प्रयास करें SIGKILL(इसलिए हमारे पास पुनर्नवीनीकरण होने का खतरा नहीं है और गलत पीआईडी ​​के खिलाफ systemdमुद्दे SIGKILLहैं)। जिस उपकरण का हम परीक्षण कर रहे हैं, वह कई प्रक्रियाओं को तेजी से आगे बढ़ा रहा है, इसलिए पीआईडी ​​रीसाइक्लिंग के बारे में एक दुर्लभ लेकिन बहुत ही वास्तविक चिंता का कारण है।
  • अगर, व्यवहार में, मैं सिर्फ पीआईडी ​​रीसाइक्लिंग के बारे में पागल हो रहा हूं, तो मैं ठीक हूं कि स्क्रिप्ट के साथ SIGKILLप्रक्रिया के खिलाफ जारी करने के बिना जारी किए गए पीआईडी ​​की पुनरावृत्ति की परवाह किए बिना पीआईडी।


2
यहां तक ​​कि अगर आप दो सेकंड में 4 मिलियन पीआईडी ​​से अधिक रोल करने के लिए तेजी से प्रक्रिया करते हैं, तो सिस्टमड एक लूप चेकिंग में नहीं बैठता है "क्या यह पिड अभी भी जीवित है? क्या यह पिड अभी भी जीवित है?" क्योंकि यह नहीं है की जरूरत करने के लिए; इसके बारे में पहले ही सूचित कर दिया जाता है कि इसकी तत्काल बाल प्रक्रियाएं अभी भी जीवित हैं या नहीं (साधारण एसआईजीसीएचडीएल और वाट्सएप के माध्यम से) ()। इसलिए यदि यह देखता है कि यह प्रक्रिया SIGTERM के बाद बाहर निकल गई है, तो यह उस बिंदु पर सेवा को केवल 'निष्क्रिय' के रूप में चिह्नित करेगा - यह SIGKILL की जाँच, प्रतीक्षा और भेजने के साथ परेशान नहीं करेगा।
विशालता

जवाबों:


26

systemd पहले से ही इस बॉक्स का समर्थन करता है, और यह डिफ़ॉल्ट रूप से सक्षम है

केवल एक चीज जिसे आप अनुकूलित करना चाहते हैं, वह टाइमआउट है, जिसे आप कर सकते हैं TimeoutStopSec=। उदाहरण के लिए:

[Service]
TimeoutStopSec=2

अब, systemd एक SIGTERM भेजेगा, सेवा से बाहर निकलने के लिए दो सेकंड प्रतीक्षा करें, और यदि ऐसा नहीं होता है, तो यह SIGKILL भेज देगा।

यदि आपकी सेवा व्यवस्थित नहीं है, तो आपको इसकी PID फ़ाइल को पथ प्रदान करना पड़ सकता है PIDFile=

अंत में, आपने उल्लेख किया कि आपका डेमन कई प्रक्रियाओं को जन्म देता है। इस स्थिति में, आप सेट करने की इच्छा रख सकते हैं KillMode=control-groupऔर सिस्टमग्रुप cgroup में सभी प्रक्रियाओं के लिए सिग्नल भेजेगा।


धन्यवाद। एक अंतिम प्रश्न: मान लें कि सेवा प्रणालीगत-जागरूक नहीं है। मैं इस सेवा के लिए systemd स्क्रिप्ट में क्या जोड़ सकता हूं ताकि systemd PID फ़ाइल बनाता / प्रबंधित करता है? इसके अतिरिक्त, सेवा टेम्पलेट इकाइयों के माध्यम से बहु-आवृत्ति हो सकती है, इसलिए हम आम तौर पर इसे `systemctl start foo_dameon@1.service" के माध्यम से लॉन्च करते हैं, इसलिए यह स्क्रिप्ट में PID फ़ाइल तर्क को प्रभावित करेगा?
Cloud

4
@DevNull systemd PID फ़ाइलों का निर्माण या प्रबंधन नहीं करता है। ऐसा करने का कोई कारण नहीं है। यदि आपकी सेवा अपनी PID फ़ाइल नहीं बनाती है, तो यदि संभव हो तो इसे अग्रभूमि में चलाने के लिए कॉन्फ़िगर करें (डामेंटाइजिंग के बजाय) और सिस्टम Type=simpleयूनिट में सेट करें ।
माइकल हैम्पटन

1
यदि सेवा पर आश्रित हैं, तो Type=forkingइसका लाभ है (यदि सेवा ठीक से लिखी गई हो) सिस्टम को सूचित करते समय यह पूरी तरह से 'तैयार' है जो टाइप = सरल नहीं कर सकता है। एक पीआईडी ​​फ़ाइल के बिना भी, डीमॉनेटाइजिंग एक समस्या नहीं है - सिस्टमड वैसे भी मुख्य प्रक्रिया को ट्रैक करेगा।
विशालता

1
यह सच है कि सेवा शुरू करने से पहले तैयार होने से पहले यह मेरा अनुभव रहा है कि सेवाओं में काफी कमी आई है। सिस्टमड-जागरूक सेवा का उपयोग Type=notifyकरना सिस्टमड के लिए सबसे अच्छा है, और कई सामान्य सेवाएं पहले से ही ऐसा करती हैं। लेकिन शायद यह विरासत सेवा नहीं है। ओपी के मामले में, उनके पास एक सेवा है जो कई प्रक्रियाओं को जन्म देती है। इस मामले के बारे में systemd डॉक्स चेतावनी देते हैं
माइकल हैम्पटन

1

चूँकि किसी को भी आवश्यकता का उल्लेख नहीं किया गया है Type=oneshot, यहाँ एक पूर्ण उदाहरण है जो समय समाप्त होने के कारण बाहर निकलता है।

[Unit]
Description=timeout test

[Service]
Type=oneshot
TimeoutStartSec=2
ExecStart=/bin/sleep 10
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.