Lighttpd + FastCgi + Django: استجابة مقطوعة تم إرسالها إلى العميل بسبب EOF غير المتوقع

StackOverflow https://stackoverflow.com/questions/3714489

سؤال

أحاول الحصول على 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's runfgci عالية حقا بحيث يكون هناك الكثير من الخيوط الاحتياطية معلقة.

  • ضبط 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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top