ฉันได้รับการกำหนดค่า nginx เป็นส่วนหน้าของแอปพลิเคชัน Python ที่ทำงานภายใต้ gunicorn แต่ nginx กำลังยุติการเชื่อมต่อหลังจากส่งข้อมูลไปแล้วประมาณ 65k
ตัวอย่างเช่นฉันมีมุมมองที่มีลักษณะเช่นนี้:
def debug_big_file(request):
return HttpResponse("x" * 500000)
แต่เมื่อฉันเข้าถึง URL นั้นผ่าน nginx ฉันจะได้รับ 65283 ไบต์เท่านั้น:
$ curl https://example.com/debug/big-file | wc
…
curl: (18) transfer closed with outstanding read data remaining
0 1 65283
โปรดทราบว่าทุกอย่างทำงานได้ตามที่คาดไว้เมื่อเข้าถึง gunicorn โดยตรง:
$ curl http://localhost:1234/debug/big-file | wc
…
0 1 500000
การกำหนดค่า nginx ที่เกี่ยวข้อง:
location / {
proxy_pass http://localhost:1234/;
proxy_redirect off;
proxy_headers_hash_bucket_size 96;
}
และรุ่น nginx 1.7.0
ข้อเท็จจริงอื่น ๆ :
- จำนวนไบต์สอดคล้องกันจากการร้องขอการร้องขอ แต่มันแตกต่างกันไปตามเนื้อหา (ฉันสังเกตเห็นครั้งแรกด้วยไฟล์ PNG ขนาดใหญ่ซึ่งถูกตัดหลังจาก 65,372 ไบต์ไม่ใช่ 65,283)
- 110k ไบต์ถูกส่งอย่างถูกต้อง (เช่น
"x" * 110000
ส่งคืน 110,000 ไบต์ทั้งหมด) แต่ 120k ไบต์ไม่ใช่ tcpdump
แนะนำว่า nginx กำลังส่งแพ็กเก็ต RST ไปยัง gunicorn:
มันจะมีประโยชน์ที่จะเห็น (ก) วิธีที่ gunicorn เลือกเฟรมการตอบกลับจากขนาด 110k ถึง 120k bytes และ (b) วิธีที่ nginx เลือกเฟรมในช่วงเดียวกันของขนาด payload ตัวอย่างระหว่าง 110k และ 120k ไบต์ สามวิธีที่ HTTP สามารถใส่ข้อมูล: จัดเตรียมความยาวเนื้อหา ทำการเข้ารหัส chunked; หรือไม่ให้กรอบเลยยกเว้นสัญญาว่าจะปิดซ็อกเก็ตเมื่อร่างกายสมบูรณ์
—
Brandon Rhodes
กำลังจัดเตรียมส่วนหัวความยาวเนื้อหา ขอให้ฉันทิ้งแพ็กเก็ตเพื่อดูว่าเกิดอะไรขึ้นระหว่างสองอย่างนี้…
—
เดวิดโวเลเวอร์
อืมแปลกมาก tcpdump แนะนำว่า nginx กำลังทำการเชื่อมต่อ RST อย่างแข็งขัน (ดูการแก้ไข) Nginx ยังใช้ HTTP / 1.0
—
David Wolever
Connection: close
และ ฉันยังยืนยันว่าContent-Length
ส่วนหัวนั้นถูกต้อง