Lighttpd + FastCgi + Django: استجابة مقطوعة تم إرسالها إلى العميل بسبب EOF غير المتوقع
سؤال
أحاول الحصول على WebApp المستند إلى Django في تكوين نشر العمل ، وبعد قضاء مجموعة من الوقت في محاولة للحصول على العمل تحت LightTPD / FastCgi ، لا يمكن تجاوز هذه المشكلة. عندما يقوم العميل بتسجيل الدخول لأول مرة ، فإنهم يتلقون تفريغ بيانات كبير من الخادم ، والذي يتم تقسيمه إلى عدة أجزاء بحجم 1 ميجابايت التي يتم إرسالها مرة أخرى باسم JSON.
في كثير من الأحيان ، سيتلقى العميل استجابة مقطوعة لأحد القطع ، سأرى هذه الرسالة في سجلات LightTPD:
2010-09-14 23:25:01: (mod_fastcgi.c.2582) unexpected end-of-file (perhaps the fastcgi process died): pid: 0 socket: tcp:127.0.0.1:8000
2010-09-14 23:25:01: (mod_fastcgi.c.3382) response already sent out, but backend returned error on socket: tcp:127.0.0.1:8000 for /myapp.fcgi?, terminating connection
أنا حقًا أسحب شعري في محاولة لمعرفة سبب حدوث ذلك (وهذا لا يحدث عند تشغيل Django ./manage.py runserver
الوضع). فيما يلي الأشياء التي جربتها والتي لم يكن لها أي تأثير:
تقليل حجم الجزء من 1 ميجابايت إلى 256 كيلو. على الرغم من أن الاقتطاع يحدث عادة في حوالي 600 ألف - 900 ألف علامة ، إلا أنني ما زلت حصلت على اقتطاع تحت حجم قطعة 256K.
وضع
minspare
وmaxchildren
القيم على Django'srunfgci
عالية حقا بحيث يكون هناك الكثير من الخيوط الاحتياطية معلقة.ضبط
maxchildren
إلى 1 بحيث يكون هناك موضوع واحد فقط.التبديل بين وضع مقبس UNIX ووضع TCP/IP لاتصال FASTCGI بين LightTPD و Django.
لقد غوغل كثيرًا لهذه الأشياء ، لكنني لم أتمكن من العثور على أي شيء يبدو أنه حل لجانغو (يبدو أن أي مساعدة حول إعدادات PHP).
الإعداد الخاص بي هو:
OSX 10.6.4
بيثون 2.6.1 (نظام)
LightTPD مثبت من Macports (1.4.26_1+SSL)
تم تثبيت Flup من أحدث موقع Python Egg on Flup (حاول 1.0.2 مستقرًا وأحدث 1.0.3).
Django 1.2.1 مثبت من Tarball على موقع Django
كتلة fastcgi في تكوين Lighttpd الخاص بي هي:
fastcgi.server = ("/myapp.fcgi" =>
("django" =>
(
#"socket" => lighttpd_base + "fcgi.sock",
"host" => "127.0.0.1",
"port" => 8000,
"check-local" => "disable",
"max-procs" => 1,
"debug" => 1
)
)
)
ال runfcgi
الأمر الذي أستخدمه لبدء Django حاليًا:
./manage.py runfcgi daemonize=false debug=true host=127.0.0.1 port=8000
method=threaded maxchildren=1
إذا كان لدى أي شخص أي نظرة ثاقبة حول كيفية منع هذا من الحدوث ، فستكون المساعدة موضع تقدير كبير. إذا لم أتمكن من حل هذا بسرعة نسبيًا ، فسيتعين علي التخلي عن Lighttpd + FastCgi والنظر إلى Apache + Mod_wsgi أو ربما Nginx + FastCgi ، وإمكانية الانتقال إلى تكوين خادم ويب آخر لا أتطلع إليه ...
شكرا مقدما على أي مساعدة.
تحرير: معلومات إضافية
وجدت هذه الصفحة في المنتديات الخفيفة التي تشير إلى أنه يمكن أن يكون خطأ Django ... في هذه الحالة ، كان PHP يتحطم. راجعت أغراضتي من جانب Django واكتشفت أنه حتى بعد الاقتطاع ، فإن خيط Python الذي أرسل الاستجابة المقطوعة سيظل يعمل بعد ذلك وسيقدم الطلبات اللاحقة ، لذلك يبدو أن الدفق لا يتم كسره بواسطة مؤشر الترابط الذي يضرب استثناء والخروج.
كنت أرغب في معرفة ما إذا كان FCGI الخاص بـ Django أو LightTPD الذي كان مخطئًا هنا أم لا (لأن ذلك سيحدد ما إذا كان ينتقل إلى Nginx + Fastcgi أم لا سيحل أي شيء بالفعل) ، لذلك ألقيت نظرة على تتبع الحزمة في Wireshark . السجل المبسط لما يحدث قبل التقسيم أدناه:
No. Time Info
30082 233.411743 django > lighttpd [PSH, ACK] Seq=860241 Ack=869 Win=524280 Len=8184 TSV=417114153 TSER=417114153
30083 233.411749 lighttpd > django [ACK] Seq=869 Ack=868425 Win=524280 Len=0 TSV=417114153 TSER=417114153
30084 233.412235 django > lighttpd [PSH, ACK] Seq=868425 Ack=869 Win=524280 Len=8 TSV=417114153 TSER=417114153
30085 233.412250 lighttpd > django [ACK] Seq=869 Ack=868433 Win=524280 Len=0 TSV=417114153 TSER=417114153
30086 233.412615 django > lighttpd [PSH, ACK] Seq=868433 Ack=869 Win=524280 Len=8184 TSV=417114153 TSER=417114153
30087 233.412628 lighttpd > django [ACK] Seq=869 Ack=876617 Win=524280 Len=0 TSV=417114153 TSER=417114153
30088 233.412723 lighttpd > django [FIN, ACK] Seq=869 Ack=876617 Win=524280 Len=0 TSV=417114153 TSER=417114153
30089 233.412734 django > lighttpd [ACK] Seq=876617 Ack=870 Win=524280 Len=0 TSV=417114153 TSER=417114153
30090 233.412740 [TCP Dup ACK 30088#1] lighttpd > django [ACK] Seq=870 Ack=876617 Win=524280 Len=0 TSV=417114153 TSER=417114153
30091 233.413051 django > lighttpd [PSH, ACK] Seq=876617 Ack=870 Win=524280 Len=8 TSV=417114153 TSER=417114153
30092 233.413070 lighttpd > django [RST] Seq=870 Win=0 Len=0
تأتي الحزم الجيدة من Django في البداية (30082 مقابل 8184 بايت ، ثم مرة أخرى في 30086 ل 8184 بايت آخر) ثم عند الإدخال 30088 لسبب ما يرسل Lighttpd tcp FIN
إلى Django وهو ما يفترض أنه يسبب الاتصال بالإنهاء ، وهكذا تحصل على الاقتطاع.
على وجهه ، يبدو أن هذا خطأ Lighttpd ، لأنه يبدو أنه يغلق الأشياء قبل أن يفترض أن ... على الرغم من أنني لست متأكدًا من أنه لا يفعل هذا لأنه تلقى بعض البيانات السيئة من Django الذي يتفاعل إليه بإغلاقه.
المحلول
لما يستحق الأمر ، انتهى بي الأمر في النهاية إلى القفز إلى Nginx ويبدو أن كل شيء يعمل بشكل جيد ، لذا يبدو أن شكوك في أن خطأ Lighttpd بدلاً من ضمني FCGI في Django قد تم تأسيسه جيدًا.
لقد وجدت بالفعل إعداد Nginx أسهل بكثير من LightTPD ، ناهيك عن أنه يمكنك تثبيت macport من Nginx (Port تثبيت Nginx +SSL) الذي يفعل ليس تحتوي على حشرة SSL التي تعانيها Lighttpd من هنا.
نصائح أخرى
هل أنت متأكد من أنك لا تملك شيئًا آخر يستمع بالفعل على المنفذ 8000. يتم استخدام هذا المنفذ عادة لخوادم HTTP بواسطة المؤتمر وسيكون فكرة سيئة لتشغيل عملية FastCGI عليها. اقترح استخدام منفذ مختلف لا يوجد بالقرب من نطاق 8xxx.