2016-01-28 4 views
10

tl; drroute के साथ सजाए गए एक विधि समवर्ती अनुरोधों को संभाल नहीं सकते हैं, जबकि कई कार्यकर्ताओं और धागे के साथ शुरू किए गए बंदूक के पीछे फ्लास्क परोसा जाता है, जबकि दो अलग-अलग विधियां समवर्ती अनुरोधों को ठीक से संभालती हैं। यह मामला क्यों है, और एक ही मार्ग को एक साथ कैसे किया जा सकता है?उसी रूट के लिए समवर्ती अनुरोधों को संभालने के लिए फ्लास्क/गनिकॉर्न कैसे प्राप्त करें?


मैं इस सरल कुप्पी से ऐप्स है: यदि मैं इस के माध्यम से चलाने के

from flask import Flask, jsonify 
import time 
app = Flask(__name__) 

@app.route('/foo') 
def foo(): 
    time.sleep(5) 
    return jsonify({'success': True}), 200 

@app.route('/bar') 
def bar(): 
    time.sleep(5) 
    return jsonify({'success': False}), 200 

:

gunicorn test:app -w 1 --threads 1 

अगर मैं जल्दी /bar और /foo दो अलग-अलग टैब में एक ब्राउज़र में खोलने के लिए, जो भी टैब मैंने पहली बार दर्ज किया है वह 5 सेकंड में लोड होगा, और दूसरा टैब 10 सेकंड में लोड होगा। यह समझ में आता है क्योंकि बंदूक एक काम के साथ एक कार्यकर्ता चल रहा है।

अगर मैं या तो के माध्यम से इस चलाएँ:

gunicorn test:app -w 1 --threads 2 
gunicorn test:app -w 2 --threads 1 

इस मामले में, /foo खोलने और /bar दो अलग-अलग टैब में दोनों 5 सेकंड ले लो। यह समझ में आता है, क्योंकि बंदूकधारी दो धागे के साथ 1 कार्यकर्ता चला रही है, या दो श्रमिक प्रत्येक धागे के साथ चल रहे हैं, और एक ही समय में दो मार्गों को पूरा कर सकते हैं।

हालांकि, अगर मैं एक ही समय में दो /foo खोलता हूं, तो बंदूकधारी कॉन्फ़िगरेशन के बावजूद, दूसरा टैब हमेशा 10 सेकंड लेगा।

समवर्ती अनुरोधों को पूरा करने के लिए route द्वारा सजाए गए एक ही विधि को मैं कैसे प्राप्त कर सकता हूं?

उत्तर

9

यह समस्या शायद गनिकोर्न या फ्लास्क के कारण नहीं बल्कि ब्राउज़र द्वारा की गई है। मैंने अभी इसे पुन: उत्पन्न करने की कोशिश की। दो फ़ायरफ़ॉक्स टैब के साथ यह काम करता है; लेकिन अगर मैं अलग-अलग कंसोल में दो curl प्रक्रियाओं को चलाता हूं तो उन्हें अपेक्षित (समांतर में) के रूप में कार्य किया जाता है, और उनके अनुरोध विभिन्न श्रमिकों द्वारा संभाले जाते हैं - यह बंदूकधारी शुरू करते समय --log-level DEBUG को सक्षम करके चेक किया जा सकता है।

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

नतीजतन, यहां तक ​​कि async कार्यकर्ता का उपयोग कर eventlet तरह मदद मिलेगी नहीं: async कार्यकर्ता एक बार में एकाधिक कनेक्शन संभाल सकता है, लेकिन जब दो अनुरोध तो एक ही कनेक्शन पर भूमि वे आवश्यक रूप से एक-एक करके नियंत्रित किया जाएगा ।

+1

दिलचस्प है कि कनेक्शन के संबंध में मूल रूप से ऐसे ब्राउज़र के व्यवहार का उद्देश्य नए कनेक्शन स्थापित करने के अतिरिक्त ओवरहेड से बचकर * गति * लोड करना है। लेकिन इस स्थिति में (सर्वर पक्ष पर धीमी हैंडलिंग के साथ) हम देखते हैं कि इससे चीजों को धीमा कर दिया जा सकता है। – MarSoft

+0

मैंने क्रोम में एक टैब और फ़ायरफ़ॉक्स में एक टैब के साथ कोशिश की और अपेक्षित परिणाम प्राप्त किए। धन्यवाद और अच्छी कॉल। –

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