python 104, 'सहकर्मी सॉकेट त्रुटि द्वारा कनेक्शन रीसेट, या जब एफआईएन के बजाय आरएसटी में सॉकेट परिणाम बंद करता है?




sockets wsgi (4)

हम समानांतर में एक पायथन वेब सेवा और क्लाइंट वेब साइट विकसित कर रहे हैं। जब हम क्लाइंट से सेवा में HTTP अनुरोध करते हैं, तो एक कॉल लगातार सॉकेट उठाता है। Socket.py में आतंक, पढ़ने में:

(104, 'Connection reset by peer')

जब मैं वायरशर्क के साथ सुनता हूं, तो "अच्छा" और "बुरा" प्रतिक्रिया बहुत समान दिखती है:

  • OAuth शीर्षलेख के आकार के कारण, अनुरोध दो पैकेट में विभाजित है। सेवा एसीके के साथ दोनों का जवाब देती है
  • सेवा प्रतिक्रिया भेजती है, प्रति हेडर एक पैकेट (HTTP / 1.0 200 ठीक है, फिर दिनांक शीर्षलेख, आदि)। ग्राहक एसीके के साथ प्रत्येक को जवाब देता है।
  • (अच्छा अनुरोध) सर्वर एक एफआईएन, एसीके भेजता है। ग्राहक एक एफआईएन, एसीके के साथ जवाब देता है। सर्वर एसीके का जवाब देता है।
  • (खराब अनुरोध) सर्वर एक आरएसटी, एसीके भेजता है, ग्राहक एक टीसीपी प्रतिक्रिया नहीं भेजता है, सॉकेट। ग्राहक पक्ष पर आतंक उठाया जाता है।

वेब सेवा और क्लाइंट दोनों जेनेटू लिनक्स x86-64 बॉक्स पर चल रहे हैं glibc-2.6.1 चल रहे हैं। हम उसी वर्चुअल_एनवी के अंदर पाइथन 2.5.2 का उपयोग कर रहे हैं।

ग्राहक एक Django 1.0.2 ऐप है जो अनुरोध करने के लिए httplib2 0.4.0 को कॉल कर रहा है। हम OAuth हस्ताक्षर एल्गोरिदम के साथ अनुरोधों पर हस्ताक्षर कर रहे हैं, OAuth टोकन हमेशा खाली स्ट्रिंग पर सेट होता है।

सेवा Werkzeug 0.3.1 चल रही है, जो Python के wsgiref.simple_server का उपयोग कर रहा है। मैं wgsiref.validator के माध्यम से WSGI ऐप चलाया बिना किसी समस्या के।

ऐसा लगता है कि इसे डीबग करना आसान होना चाहिए, लेकिन जब मैं सेवा पक्ष पर एक अच्छे अनुरोध के माध्यम से पता लगाता हूं, तो यह socket._socketobject.close () फ़ंक्शन में खराब अनुरोध की तरह दिखता है, प्रतिनिधि विधियों को डमी विधियों में बदल देता है। जब प्रेषण या प्रेषण (जिसे याद नहीं किया जा सकता) विधि बंद कर दी जाती है, तो एफआईएन या आरएसटी भेजा जाता है, और ग्राहक प्रसंस्करण शुरू कर देता है।

"सहकर्मी द्वारा कनेक्शन रीसेट" सेवा पर दोष लगाने लगता है, लेकिन मुझे httplib2 पर भरोसा नहीं है। क्या ग्राहक गलती हो सकता है?

** आगे डीबगिंग - लिनक्स पर सर्वर की तरह दिखता है **

मेरे पास एक मैकबुक है, इसलिए मैंने एक और ग्राहक वेबसाइट पर सेवा चलाने की कोशिश की। लिनक्स क्लाइंट बग के बिना ओएस एक्स सर्वर को कॉल करता है (एफआईएन एसीके)। ओएस एक्स क्लाइंट लिनक्स सेवा को बग (आरएसटी एसीके, और ए (54, 'पीयर द्वारा कनेक्शन रीसेट') के साथ कॉल करता है)। तो, ऐसा लगता है कि यह लिनक्स पर चल रही सेवा है। क्या यह x86_64 है? एक बुरा glibc? wsgiref? अभी भी देख रहा है...

** आगे परीक्षण - wsgiref flaky दिखता है **

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


आम तौर पर, आपको एक आरएसटी मिल जाएगा यदि आप एक करीबी काम करते हैं जो कि रुकता नहीं है (यानी जिसमें डेटा को स्टैक द्वारा छोड़ा जा सकता है यदि उसे भेजा नहीं गया है और ACK'd) और यदि आप बंद करने की अनुमति देते हैं तो सामान्य FIN अदरक करने के लिए (यानी बंद एसीकेड होने के लिए पारगमन में डेटा के लिए इंतजार कर रहा है)।

शायद आपको बस इतना करना है कि आप अपनी सॉकेट को अदरक पर सेट करें ताकि आप सॉकेट पर किए गए गैर-करीब बंद होने और एसीके पहुंचने के बीच दौड़ की स्थिति को हटा दें?



मुझे यह समस्या है। पाइथन देखें "पीयर द्वारा कनेक्शन रीसेट" समस्या

आपके पास पाइथन ग्लोबल इंटरप्रेटर लॉक के आधार पर छोटे समय के मुद्दों का सामना करना पड़ता है (सबसे अधिक संभावना है)।

आप (कभी-कभी) एक time.sleep(0.01) साथ इसे सही कर सकते हैं। time.sleep(0.01) रणनीतिक रूप से रखा गया है।

"कहा पे?" तुम पूछो। मुझे पता नहीं। विचार क्लाइंट अनुरोधों के आस-पास और आसपास कुछ बेहतर थ्रेड समेकन प्रदान करना है। अनुरोध करने से पहले इसे डालने का प्रयास करें ताकि जीआईएल रीसेट हो और पाइथन दुभाषिया किसी भी लंबित धागे को साफ़ कर सके।


उत्पादन के लिए wsgiref का उपयोग न करें। अपाचे और mod_wsgi, या कुछ और का प्रयोग करें।

हम इन कनेक्शन रीसेट को कभी-कभी देखते हैं, कभी-कभी, wsgiref (werkzeug test server द्वारा उपयोग किए जाने वाले बैकएंड, और संभवतः Django परीक्षण सर्वर जैसे अन्य) के साथ। हमारा समाधान त्रुटि लॉग करना था, एक लूप में कॉल को पुनः प्रयास करना था, और दस विफलताओं के बाद छोड़ देना था। httplib2 दो बार कोशिश करता है, लेकिन हमें कुछ और चाहिए। वे बंच में भी आते हैं - एक दूसरी नींद जोड़ना इस मुद्दे को साफ़ कर सकता है।

Apache और mod_wsgi के माध्यम से चलते समय हमने कभी कनेक्शन रीसेट नहीं देखा है। मुझे नहीं पता कि वे अलग-अलग क्या करते हैं, (शायद वे सिर्फ उन्हें मुखौटा करते हैं), लेकिन वे प्रकट नहीं होते हैं।

जब हमने स्थानीय देव समुदाय से मदद के लिए पूछा, तो किसी ने पुष्टि की कि वे उत्पादन सर्वर पर जाने वाले wsgiref के साथ बहुत से कनेक्शन रीसेट देख रहे हैं। वहां एक बग है, लेकिन इसे ढूंढना मुश्किल होगा।





werkzeug