मैं अपने अपाचे / पीएचपी आधारित वेब ऐप में एक स्पष्ट मेमोरी लीक का कारण कैसे निर्धारित कर सकता हूं?


18

सप्ताह में एक बार के बारे में, लेकिन कभी-कभी दिन के लिए ठीक चलने के बाद भी दिन में दो बार, मेरे ईसी 2 उदाहरण अनुत्तरदायी बन जाते हैं। मुनिन की स्मृति रेखायें एक बहुत ही सीधी-सादी कहानी कहती हैं: "ऐप्स" को आवंटित की गई मेमोरी बढ़ने लगती है और तब तक नहीं रुकती जब तक कि स्वैप पूरी तरह से उपयोग नहीं हो जाता है और उदाहरण को प्रभावी ढंग से अपने घुटनों तक लाया जाता है। एक और कस्टम ग्राफ दिखाता है कि लगातार बढ़ती प्रक्रिया अपाचे 2 है।

मैं mod_php और कुछ PHP स्क्रिप्ट के साथ एक मानक प्रीफ़ॉर्क Apache सेटअप चलाता हूं। जैसा कि आप नीचे दिए गए ग्राफ़ में देख सकते हैं, कुछ ऐसा होता है जो अधिक से अधिक मेमोरी का उपभोग शुरू करने के लिए अपाचे 2 प्रक्रियाओं को ट्रिगर करता है। पहली हरी स्पाइक जिसे मैंने समय पर पकड़ा और चीजों को हाथ से निकलने से पहले अपाचे को फिर से चालू कर दिया। दूसरा स्पाइक थोड़ा आगे बढ़ गया और उदाहरण के लिए सीधे रिबूट करना पड़ा।

मुनिन मेमोरी ग्राफ

मैं सोच रहा हूँ कि यह कैसे सबसे अच्छा डिबग करने के लिए है। FastCGI के साथ PHP की स्थापना करने और इसे अपनी प्रक्रियाओं में चलाने से कम, यह पता लगाने का एक अच्छा तरीका है कि क्या यह अपाचे या PHP और मेरे कोड का संयोजन है जो अत्यधिक मेमोरी उपयोग का कारण है? आप लोग इस मुद्दे को ट्रैक करने के लिए क्या कदम उठाएंगे?


अद्यतन: मैट नीचे दिए गए सुझाव के अनुसार, मैं स्ट्रीम को शामिल करने के बाद रिसाव को ट्रैक करने में सक्षम था।

एक अपाचे 2 प्रक्रिया को खोजने के बाद, जो धीरे-धीरे और लगातार मेमोरी में बढ़ रही थी, मैंने अपनी PHP स्क्रिप्ट में कुछ और error_log () कॉल जोड़े, जो कि इसके निष्पादन में विभिन्न बिंदुओं पर उपयोग किए गए RSS की कुल राशि (ps के आउटपुट का उपयोग करके) का प्रिंट निकालते हैं। हालांकि यह भ्रामक निकला - जबकि ऐसा प्रतीत हुआ कि मेरी स्क्रिप्ट को निष्पादित करने के बाद ही आरएसएस कूद गया, बाद में डिबगिंग से पता चला कि वास्तव में ऐसा नहीं था। सावधान रहे!

सौभाग्य से, वे सभी error_log () कॉल अंत में उपयोगी साबित हुए। जब मैंने स्ट्रेस ( strace -p <pid> -tt -o trace.log -s 256) निकाल दिया , तो मैंने देखा कि प्रत्येक अनुरोध के लिए, प्रक्रिया को लगभग 400k मेमोरी ('brk' सिस्टम कॉल के लिए आवंटित किया गया था) और अंतिम कॉल के पहले कॉल के पैरामीटर को घटाएं - कुछ एक में आमतौर पर आते हैं। दूसरे के बाद)। मैंने तब सबसे हाल के 'राइट' सिस्टम कॉल की खोज की जिसमें मेरा error_log () संदेश था, जिसने मुझे बताया था कि किस स्क्रिप्ट में मेमोरी आवंटित की जा रही है। रणनीतिक रूप से रखी गई कुछ और त्रुटि के साथ_लॉग () स्थान को अधिक सटीक रूप से इंगित करने के लिए कॉल करता है, मुझे अंततः अपराधी मिल गया।

जब हम अपने PHP स्क्रिप्ट से curl_exec () कहते हैं तो मेमोरी लीक हो रही थी। SSL कनेक्शन को संभालने से संबंधित कुछ कर्ल कोड कुछ गलत कर रहे हैं - जब मैं HTTP पर स्विच किया गया तो रिसाव दूर हो गया। कर्ल के चैंजगॉग में कुछ एसएसएल मेमोरी लीक हैं जो 7.19.5 में तय किए गए थे (हम 7.18.2 पर थे) इसलिए मैं इसके बाद की कोशिश करूंगा।

इस बीच, मैं बहुत कम MaxRequestsPerChild के साथ चल रहा हूं जो Apache को उचित सीमा के भीतर रख रहा है। सबको धन्यवाद!


एक ही अवधि में अपाचे बाल प्रक्रियाओं की संख्या अलग-अलग कैसे होती है?
सिमोन

@SimonJ साइमन, महान सवाल, संख्या बहुत ज्यादा एक ही रहती है, प्लस कुछ प्रक्रियाओं को घटा देती है। यह लगभग 60 तक घूमता है जब सर्वर को परेशानी हो रही होती है और जब वे आराम कर रहे होते हैं। मैं 100% यकीन है कि हालांकि एक मुनिन ग्राफ की स्थापना करेंगे।
ondrej

समाधान नहीं है, लेकिन अगर किसी एप्लिकेशन को पागल की तरह रैम खाने के लिए जाना जाता है, तो स्वैप बंद रखना बेहतर है: जब कर्नेल रैम की कमी का पता लगाता है, तो यह सबसे बड़ी मेमोरी हॉग्स (अपाचे) को मार देगा। स्वैप सक्षम होने के साथ, कर्नेल कुछ प्रक्रियाओं को बहुत बाद में मार देगा, क्योंकि स्वैप रैम की तुलना में बहुत धीमा है। कोई स्वैप नहीं - तेजी से वसूली, छोटे डाउनटाइम। (मैंने केवल 8GiB रैम के साथ मशीन पर एक समान मामले में स्वैप को अक्षम करने की कोशिश की है, इसलिए YMMW।)
क्रोनोस

जवाबों:


5

WHAT को ट्रैक करने से समस्या पैदा हो रही है और गधे में दर्द हो सकता है। पहली बात तो यह है कि अगर मुझे ऐसी कोई समस्या होती है, तो यह बहुत MaxRequestsPerChildकम संख्या (~ 100-200) तक कम हो जाती है और देखें कि क्या इससे कोई फर्क पड़ता है। यदि ऐसा होता है, तो आपके पास संभवतः एक कोड है जो मेमोरी को लूप में कहीं लीक कर रहा है और आप एक कोड ऑडिट चलाना चाहते हैं।

एक और बात अपाचे के फुलटस को देखने के लिए है, देखें कि क्या आप यह पता लगा सकते हैं कि मेमोरी लीक के कारण क्या विशेष अनुरोध है। अपनी संदिग्ध प्रक्रियाओं पर PID प्राप्त करें और उन पर एक स्ट्रेस चलाएं।


धन्यवाद मैट। 'पीएस ऑक्स | grep apache2 'मुझे बताता है कि 60 में से या तो प्रक्रियाएं सक्रिय हैं, एक दर्जन के आसपास एक बहुत अधिक स्मृति का उपयोग कर रहे हैं जितना उन्हें (आरएसएस में 100 एमबी) करना चाहिए। मैंने / proc / <pid> / smaps के आउटपुट को देखा है और पाया है कि हर एक में एक अनाम मानचित्रण है जो अंतरिक्ष का 95% + ले रहा है। मैं अब यह पता लगाने की कोशिश कर रहा हूं कि स्मृति के इस विशाल समूह को क्या और कब आवंटित किया गया है। मैं स्ट्रीम में देखूंगा - टिप के लिए धन्यवाद।
ondrej

2

शुक्रवार @ ठीक 11 बजे? क्या यह बैकअप समय के अनुरूप है? क्या आपके सिस्टम में I / O है जो उस समय प्रक्रियाओं और बैकअप की सेवा के लिए उपलब्ध है? क्या आप ट्रेंडिंग सॉफ़्टवेयर में भी # procs या फिर अपाचे स्कोरबोर्ड ट्रेंड करते हैं, डिस्क I / O के बारे में कैसे?

पहली बात मैं करना होगा गणना करने के लिए कितना मेम प्रत्येक proc लेता है हो सकता है, तो अपाचे ताकि $ procmem * $ procs अधिक नहीं हो सकता उपलब्ध राम में MaxRequests के लिए एक उचित सीमा निर्धारित करें। मुझे संदेह है कि आपके उदाहरण को रिबूट करने की आवश्यकता है क्योंकि OOM एक चुड़ैल के शिकार को मारता है जो संभवतः (अक्सर) बहुत उपयोगी नहीं है। आपको यह सुनिश्चित करने की आवश्यकता है कि आपका बॉक्स इसकी सीमाओं के भीतर रहकर इन भारी समय को संभाल सकता है और स्वैप में नहीं जा सकता है और निश्चित रूप से OOM नहीं। यह कठिन है यदि आपके पास क्रोनॉजर्स जा रहा है, और अत्यंत कठिन है यदि क्रोनॉजर्स एकतरफा रूप से चलाए बिना यह सुनिश्चित करते हैं कि इसे चलाने के लिए सुरक्षित है (यानी हर 5 मिनट की स्क्रिप्ट यह जांचने में विफल रहती है कि क्या अंतिम 5 मिनट अभी भी चल रहा है)।

अब जब आपने यह सुनिश्चित कर लिया है कि अगर चीजें गलत हो जाती हैं, तो भी आपको अपने बॉक्स को रिबूट करने की आवश्यकता नहीं होगी, चीजें आपके लिए बहुत बेहतर होने लगेंगी। आप इन भारी समय के दौरान लॉगिन करने में सक्षम होंगे और एक अच्छा विचार प्राप्त कर सकते हैं कि शीर्ष, dstat, free -m, iostat, आदि का उपयोग क्या हो रहा है।

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


0

पूछने के लिए पहला सवाल यह है कि अपाचे के माध्यम से आवेदन क्या चल रहा है?

क्या यह आपने लिखा है, या एक तृतीय-पक्ष ऐप है?

क्या अन्य घटक / संकुल इसे संदर्भित करता है?

क्या आप अपने पैकेज पर अप-टू-डेट हैं?

httpd.confप्रदर्शन से संबंधित आपकी फ़ाइलों में कुछ भी विशिष्ट है ?


0

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


राफेल, धन्यवाद। हां, PHP ऐप मेरा है और यह किसी भी SQL डेटाबेस को हिट नहीं करता है। मैं PHP क्विक प्रॉफ़ीलर को एक शॉट दूंगा और वापस रिपोर्ट करूंगा।
ondrej
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.