nginx + fastCGI + Django - क्लाइंट को भेजे गए प्रतिक्रियाओं में डेटा भ्रष्टाचार प्राप्त करना


10

मैं FastCGI का उपयोग कर nginx के पीछे Django चला रहा हूं। मुझे पता चला है कि क्लाइंट को भेजे गए कुछ जवाबों में प्रतिक्रियाओं के बीच में यादृच्छिक डेटा भ्रष्टाचार हो रहा है (हो सकता है कि कुछ सौ बाइट्स या बीच में हो)।

इस बिंदु पर मैंने इसे या तो nginx के FastCGI हैंडलर या Django के FastCGI हैंडलर (यानी शायद फ़्लॉप में बग) में बग होने के लिए संकुचित कर दिया है, क्योंकि यह समस्या तब नहीं होती है जब मैं स्टैंडअलोन (यानी runserver) मोड में Djit सर्वर चलाता हूं । यह केवल FastCGI मोड में होता है।

अन्य दिलचस्प रुझान:

  • यह बड़ी प्रतिक्रियाओं पर होता है। जब कोई क्लाइंट पहली बार लॉग इन करता है, तो उन्हें सर्वर डीबी तक सिंक करने के लिए 1 एमबी चंक्स का एक गुच्छा भेजा जाता है। उस पहले सिंक के बाद, प्रतिक्रियाएं बहुत छोटी होती हैं (आमतौर पर एक समय में कुछ केबी)। भ्रष्टाचार शुरू में भेजे गए उन 1 एमबी चंक्स पर हमेशा लगता है।

  • यह अधिक बार होता है जब क्लाइंट लैन (यानी कम-विलंबता, उच्च-बैंडविड्थ कनेक्शन) के माध्यम से सर्वर से जुड़ा होता है। इससे मुझे लगता है कि नगीनक्स या फ़्लॉप में किसी प्रकार की दौड़ की स्थिति है जो एक बढ़ी हुई डेटा दर से बढ़ा है।

अभी, मुझे प्रतिक्रिया हैडर में एक अतिरिक्त SHA1 डाइजेस्ट डालकर इसके चारों ओर काम करना है, और क्लाइंट ने उन प्रतिक्रियाओं को अस्वीकार कर दिया है जहां हेडर बॉडी चेकसम से मेल नहीं खाता है, लेकिन यह एक भयानक समाधान की तरह है।

क्या किसी और को ऐसा कुछ भी अनुभव हुआ है, या कोई संकेत है कि कैसे पहचानें कि क्या यह फ्लॉप या नगनेक्स है जो यहां गलती पर है इसलिए मैं उपयुक्त टीम के साथ बग दर्ज कर सकता हूं?

किसी भी सहायता के लिए अग्रिम रूप से धन्यवाद।

नोट: मैंने कुछ समय पहले भी lighttpd + FastCGI + Django में एक समान बग पोस्ट किया था: /programming/3714489/lighttpd-fastcgi-django-truncated-response-sent-to-client-due-to -अनुभवी ... भले ही यह एक ही चीज़ (भ्रष्टाचार बनाम भ्रष्टाचार) नहीं है, लेकिन ऐसा लगने लगा है कि आम अपराधी वेब सर्वर के बजाय फ़्लॉप / Django है।

संपादित करें: मुझे यह भी ध्यान देना चाहिए कि मेरा पर्यावरण क्या है:

  • मैक मिनी पर OSX 10.6.6

  • अजगर 2.6.1 (सिस्टम)

  • Django 1.3 (आधिकारिक टारबॉल से)

  • फ्लाप 1.0.2 (फ्लॉप साइट पर पायथन अंडे से)

  • nginx + ssl 1.0.0 (Macports से)

EDIT: जेरज़ेक की टिप्पणी के जवाब में, कोड पथ जो प्रतिक्रिया को इकट्ठा करता है, ऐसा लगता है (रसीलापन के लिए संपादित):

# This returns an objc NSData object, which is an array.array 
# when pushed through the PyObjC bridge
ret = handler( request ) 

response = HttpResponse( ret )
response[ "Content-Length" ] = len( ret )
return response

मुझे नहीं लगता कि यह संभव है कि उस पर आधारित सामग्री-लंबाई गलत है, और AFAIK में पाठ के विपरीत स्पष्ट रूप से द्विआधारी के रूप में एक Django HttpResponse वस्तु को चिह्नित करने का कोई तरीका नहीं है। इसके अलावा, चूंकि यह समस्या केवल रुक-रुक कर होती है, इसलिए मुझे नहीं लगता कि यह इसे समझाता है अन्यथा संभवतः आप इसे हर अनुरोध पर देखेंगे।

EDIT @ionelmc: आपको Django में सामग्री-लंबाई निर्धारित करनी होगी - nginx ने आपके लिए यह सेट नहीं किया है, जैसा कि नीचे दिए गए उदाहरण के अनुसार एक बार मैंने सामग्री-लंबाई को स्पष्ट रूप से अक्षम कर दिया:

$ curl -i http://localhost/io/ping
HTTP/1.1 200 OK
Server: nginx/1.0.0
Date: Thu, 23 Jun 2011 13:37:14 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive

AKSJDHAKLSJDHKLJAHSD

यदि प्रारंभिक हिस्सा अक्सर नहीं बदलते हैं या उपयोगकर्ता विशिष्ट नहीं हैं तो डिस्क पर लिखना और नगीनक्स के माध्यम से सीधे सेवा करना एक बेहतर तरीका है?
सूरन ०

दुर्भाग्य से, विखंडू दोनों उपयोगकर्ता-विशिष्ट और अक्सर बदलते हैं, इसलिए इस तरह का कोई भी कैशिंग इस एप्लिकेशन के लिए उपयुक्त नहीं होगा। मैं यह भी जानने के लिए उत्सुक हूं कि वास्तव में इस डेटा भ्रष्टाचार के कारण क्या हो रहा है, इसके चारों ओर काम करने के बजाय (जो मैं पहले ही हेडर में अतिरिक्त SHA1 डाइजेस्ट के साथ कर रहा हूं)।
ग्लेन

मैं दो संभावित कारणों के बारे में सोच सकते हैं: गलत एन्कोडिंग - HttpRespose पाठ बनाम द्विआधारी या गलत हेडर (विशेष रूप से सामग्री-लंबाई) के रूप में
Jerzyk

1
@glenc इस प्रतिक्रिया के लिए सामग्री-प्रकार क्या है? यदि यह द्विआधारी है - तो क्या आप इसे सेट करने का प्रयास कर सकते हैं? (उदा। mimetype = 'application / x-ms-excel' या अन्य)
Jerzyk

2
यदि आपके स्थानांतरण-एन्कोडिंग को ठगा हुआ है, तो आपको सामग्री-लंबाई निर्धारित करने की आवश्यकता नहीं है। rfc 2616 स्पष्ट रूप से यह मना करता है: "यदि ये दो लंबाई अलग हैं (यानी, यदि ट्रांसफर-एन्कोडिंग हेडर फ़ील्ड मौजूद है तो) सामग्री लंबाई लंबाई हेडर फ़ील्ड जरूरी नहीं भेजा जाएगा।"
आयनमांक

जवाबों:


1

क्या आपके पास किसी भी तरह का नग्नेक्स कैशिंग (बाईपास / no_cache) निर्देश फास्टैगी प्रतिक्रियाओं के लिए सक्रिय है?

नगीनक्स '1.0.3 चेंजेनोट्स में उन्होंने एक प्रतिक्रिया भ्रष्टाचार तय किया:

Bugfix: एक कैश्ड प्रतिक्रिया को तोड़ा जा सकता है यदि "प्रॉक्सी / फास्टसी / स्केगी / uwsgi_cache_bypass" और "प्रॉक्सी / फास्टसीगी / स्केगी / uwsgi_no_cache" निर्देश मान अलग था; बग 0.8.46 में दिखाई दिया था।

स्रोत: http://nginx.org/en/CHANGES (1.0.3 अनुभाग)


0

शायद सामयिक भ्रष्टाचार केवल तभी होता है जब आउटपुट में कम से कम एक UTF-8 वर्ण शामिल होता है।

सामग्री-लंबाई और स्ट्रिंग लंबाई एक ही बात नहीं है, क्योंकि एक UTF-8 वर्ण में 2 से 5 बाइट्स हो सकते हैं।


हम्मम .. जबकि यह सच है कि यह कारण होने की संभावना नहीं लगती है क्योंकि भ्रष्टाचार डेटा चंक्स के बीच में हो रहा था और अंत में गायब डेटा का मामला नहीं था।
ग्लेन

0

इस मामले का थोड़ा और निवारण करने का एक तरीका यह होगा:

  • अलग-अलग हार्डवेयर पर nginx और django चल रहे हैं (ताकि आप ट्रैफ़िक को आसानी से पकड़ सकें)
  • क्लाइंट से ट्रैफ़िक कैप्चर करें - / -> nginx और nginx - / -> django (यानी वायरशर्क का उपयोग करें)

एक बार जब आप क्लाइंट साइड (sha1 के आधार पर) में एक त्रुटि का पता लगाते हैं, तो नेटवर्क कैप्चर पर जाएं, रिकॉर्डेड (टीसीपी) स्ट्रीम देखें और यह पता लगाने की कोशिश करें कि क्या समस्या nginx द्वारा उत्पन्न की गई है या यह django से आती है (सीधे) ।


0

मेरे पास एक बहुत ही समान मुद्दा था जो मुझे तब तक के लिए परेशान कर रहा था जब तक मेरे पास यह सेटअप है। आपकी तरह, मैं FastCGI, Nginx और macOS का उपयोग करता हूं, और बड़े अनुरोधों के बीच यादृच्छिक भ्रष्टाचार पाया गया (यह 1.5 एमबी दस्तावेज़ के अनुरोधों का लगभग 2% था)।

मैं PHP-FPM (मेरे मामले में) और Nginx के बीच FastCGI कनेक्शन के लिए टीसीपी पर यूनिक्स सॉकेट्स पर स्विच करके अपनी समस्या को हल करने में सक्षम था। मुझे नहीं पता कि भ्रष्टाचार के लिए पहेली का कौन सा टुकड़ा जिम्मेदार है, लेकिन आंतरिक टीसीपी कनेक्शन से बचने ने इसे ठीक कर दिया।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.