2013-04-27 8 views
7

कुछ ऐसा जो मैंने अभी सोचा था:क्या होता है जब आपके पास Django व्यू कोड में अनंत लूप होता है?

कहें कि मैं अपने Django साइट के लिए व्यू कोड लिख रहा हूं, और मैं एक गलती करता हूं और अनंत लूप बनाता हूं।

जब भी कोई व्यक्ति दृश्य तक पहुंचने का प्रयास करेगा, तो अनुरोधकर्ता को अनुरोध (जिसे यह एक गेवेंट कार्यकर्ता या पायथन थ्रेड हो) अनिश्चित काल तक रहना होगा।

यदि मैं सही ढंग से समझता हूं, तो सर्वर 30 सेकंड के बाद क्लाइंट को टाइमआउट त्रुटि भेज देगा। लेकिन पायथन कार्यकर्ता के साथ क्या होगा? क्या यह अनिश्चित काल तक काम करेगा? यह खतरनाक लगता है!

कल्पना कीजिए कि मेरे पास एक सर्वर है जिसमें मैंने 10 श्रमिकों को आवंटित किया है। मैंने इसे चलाने दिया और किसी बिंदु पर, क्लाइंट अनंत लूप के साथ दृश्य तक पहुंचने का प्रयास करता है। एक कार्यकर्ता इसे सौंपा जाएगा, और अगले सर्वर पुनरारंभ होने तक प्रभावी ढंग से मर जाएगा। खतरनाक बात यह है कि सबसे पहले मैं इसे नहीं देखूंगा, क्योंकि साइट केवल 10 की बजाय 9 श्रमिकों के साथ धीमी गति से धीमी होगी, लेकिन फिर यह लंबे समय तक, शायद महीनों में बार-बार हो सकती है। साइट अभी भी धीरे-धीरे धीमी हो जाएगी, अंत में यह केवल एक कार्यकर्ता के साथ वास्तव में धीमी होगी।

एक सर्वर पुनरारंभ समस्या को हल करेगा, लेकिन मुझे लगता है कि मेरी साइट की कार्यक्षमता सर्वर पुनरारंभ पर निर्भर करती है।

क्या यह एक वास्तविक समस्या है जो होता है? क्या इससे बचने का कोई तरीका है?

अद्यतन: मैं भी वास्तव में धागा/कार्यकर्ता है कि एक अनंत लूप में अटक गया है की एक स्टैकट्रेस लेने के लिए एक तरह से इसकी सराहना करेंगे, तो मुझे लगता है कि मुझे ईमेल कर दी तो मैं समस्या से अवगत हो जाएगा हो सकता था । (मैं ऐसा करने के तरीके भी इसका अपवाद नहीं उठाया जा रहा है, क्योंकि पता नहीं।)

"लेखन कोड अनंत लूप है कि बचें" के प्रभाव के लिए बातें कह लोगों को अद्यतन: मामले में यह नहीं था जाहिर है, मैं जानबूझ कर अपने कोड में अनंत लूप डालने का अपना खाली समय नहीं व्यतीत करता हूं। जब ये बातें होती हैं, तो वे गलतियां होती हैं, और गलतियों को कम किया जा सकता है लेकिन पूरी तरह से कभी नहीं बचाया जाता है। मैं जानना चाहता हूं कि जब भी मैं गलती करता हूं, तब भी एक सुरक्षा नेट होगा जो मुझे सूचित करेगा और मुझे समस्या को ठीक करने की अनुमति देगा।

+2

दिलचस्प पढ़ने सूचना मिल सकती है:: http: // stackoverflow

आत्महत्या की मौत हो गई प्रक्रिया के प्रिंट स्टैक ट्रेस नहीं करता है। कॉम/प्रश्न/8685695/कैसे-करें-i-run-long-term-अनंत-पायथन-प्रक्रिया –

+0

मैंने अपना उत्तर अपडेट कर लिया है, मुझे उम्मीद है कि यह अब आपके प्रश्न का उत्तर देगा :) –

उत्तर

4

यह एक वास्तविक समस्या है। भूगर्भ के मामले में, संदर्भ स्विचिंग के कारण, यह आपकी वेबसाइट को तुरंत प्रतिक्रिया देने से रोक सकता है।

सब कुछ आपके पर्यावरण पर निर्भर करता है। उदाहरण के लिए, जब आप uwsgi के माध्यम से उत्पादन में django चलाते हैं तो आप harakiri सेट कर सकते हैं - यह सेकंड में समय है, जिसके बाद अनुरोध को संभालने वाले धागे को मार दिया जाएगा, अगर उसने प्रतिक्रिया को संभालना समाप्त नहीं किया है। कुछ दोषपूर्ण अनुरोधों या खराब कोड से निपटने के लिए इस तरह के मूल्य को निर्धारित करने की दृढ़ता से अनुशंसा की जाती है। यूवीजीआई लॉग में इस तरह की घटना की सूचना दी गई है। मेरा मानना ​​है कि उत्पादन में डीजेगो चलाने के लिए अन्य समाधानों में समान विकल्प हैं।

अन्यथा, नेटवर्क आर्किटेक्चर के कारण, क्लाइंट डिस्कनेक्शन अनंत लूप को नहीं रोकेगा, और डिफ़ॉल्ट रूप से कोई प्रतिक्रिया नहीं होगी - केवल अनंत लोडिंग। विभिन्न टाइमआउट विकल्प (जिनमें से एक harakiri है) कनेक्शन टाइमआउट दिखा सकता है - उदाहरण के लिए, php में (जहां तक ​​मुझे याद है) 30 सेकंड के डिफ़ॉल्ट टाइमआउट और यह 504 गेटवे टाइमआउट वापस कर देगा। सॉकेट डिस्कनेक्शन टाइमआउट http सर्वर सेटिंग्स पर निर्भर करता है और यह एप्लिकेशन थ्रेड को रोक नहीं देगा, यह केवल क्लाइंट सॉकेट बंद कर देगा।

यदि गीवेंट (या किसी अन्य हरे धागे) का उपयोग नहीं करते हैं, तो अनंत लूप 100% उपलब्ध CPU पावर (एक कोर तक सीमित) ले सकता है, संभवतः अधिक से अधिक स्मृति खा रहा है, इसलिए आपकी वेबसाइट सुंदर काम करेगी धीमी और/या समय सीमा वास्तव में जल्दी। Django खुद अनुरोध समय के बारे में पता नहीं है, तो - जैसा कि पहले उल्लेख किया गया है - आपके उत्पादन पर्यावरण ढेर यह होने से रोकने के लिए रास्ता है। Uwsgi के मामले में, http://uwsgi-docs.readthedocs.org/en/latest/Options.html#harakiri-verbose जाने का रास्ता है। (https://uwsgi-docs.readthedocs.org/en/latest/Tracebacker.html?highlight=harakiri) सीधे लॉग ऑन uwsgi के लिए, और अलार्म प्रणाली की वजह से आप ई-मेल के माध्यम से (http://uwsgi-docs.readthedocs.org/en/latest/AlarmSubsystem.html)

+0

हरकीरी विकल्प सही दिशा में एक कदम है, क्योंकि यह सर्वर को अटकने से रोकता है, लेकिन यह आपको समस्या की जड़ खोजने और इसे ठीक करने में मदद नहीं करता है। मैं जो चाहता हूं वह अपमानजनक कार्यकर्ता का एक स्टैकट्रैक है जो मुझे ईमेल करता है ताकि मैं इसका निरीक्षण कर सकूं और कोड में समस्या को ठीक कर सकूं। –

+0

हरकीरी प्रिंट स्टैक ट्रेस प्रिंट करता है और सूचना का अनुरोध करता है, और nginx अलार्म सिस्टम ई-मेल अधिसूचना की अनुमति देता है। लिंक के साथ अद्यतन उत्तर। –

+0

क्षमा करें, मैं निश्चित रूप से uwsgi अलार्म सिस्टम मतलब था :) –

0

हां, आपका विश्लेषण सही है। कार्यकर्ता धागा/प्रक्रिया चलती रहेगी। इसके अलावा, अगर लूप में कोई प्रतीक्षा/नींद नहीं है, तो यह सीपीयू को हॉग करेगा। अन्य धागे/प्रक्रिया बहुत कम सीपीयू मिल जाएगी, जिसके परिणामस्वरूप आपकी पूरी साइट धीमी प्रतिक्रिया पर होगी।

इसके अलावा, मुझे नहीं लगता कि सर्वर स्पष्ट रूप से क्लाइंट को कोई टाइमआउट त्रुटि भेज देगा। यदि टीसीपी टाइमआउट सेट है, तो टीसीपी कनेक्शन बंद हो जाएगा।

ग्राहक को प्रतिक्रिया प्राप्त करने के लिए कुछ टाइमआउट सेटिंग भी हो सकती है, जो तस्वीर में आ सकती है।

ऐसे कोड से बचने के लिए इस तरह के कोड से बचने का सबसे अच्छा तरीका है। आप सीपीयू/मेमोरी उपयोग को देखने के लिए सर्वर पर कुछ निगरानी उपकरण भी प्राप्त कर सकते हैं और असामान्य गतिविधि के लिए सूचित कर सकते हैं ताकि आप कार्रवाई कर सकें।

2

मैंने डीजेगो के विकास सर्वर पर इसका परीक्षण किया।

परिणाम:

  • 30 सेकंड के बाद समय समाप्त नहीं देता है।(ऐसा इसलिए हो सकता है क्योंकि यह उत्पादन सर्वर नहीं है)
  • जब तक मैं पृष्ठ बंद नहीं करता तब तक लोड होने में रहता है।

मुझे लगता है कि इससे बचने के लिए एक तरीका है, वास्तव में इस तरह के कोड से बचने के बिना, टाइमआउट पर नियंत्रण रखने और थ्रेड को रोकने में सक्षम होने के लिए थ्रेडिंग का उपयोग करना होगा।

हो सकता है कि कुछ की तरह:

import threading 
from django.http import HttpResponse 

class MyThread(threading.Thread): 
    def __init__(self): 
     threading.Thread.__init__(self) 
    def run(self): 
     print "your possible infinite loop code here" 

def possible_loop_view(request): 
    thread = MyThread() 
    thread.start() 
    return HttpResponse("html response") 
+0

असल में, अब मैं सोचता हूं, आप थ्रेड = MyThread() को किसी अन्य फ़ंक्शन में कॉल करना चाहते हैं ताकि आप वास्तव में इसे एक्सेस कर सकें और बाद में इसे रोक सकें .. लेकिन फिर भी एक संभावित समाधान? – Ramalus

+0

मैं वास्तव में समझ में नहीं आता कि आपका उत्तर कुछ हल कैसे करता है। एक बात के लिए, प्रतिक्रिया वापस लौटने से पहले * कोड को खत्म करने की जरूरत है। दूसरा, आपने यह भी नहीं दिखाया कि आपके द्वारा बनाए गए धागे को स्वचालित रूप से बंद कर दिया जाएगा। –

+0

ओह, आप सही हैं, मुझे लगता है कि मैंने इसे इतना नहीं सोचा था। मुझे माफ कर दो। – Ramalus

संबंधित मुद्दे