nginx ยุติการเชื่อมต่อหลังจาก 65k bytes


11

ฉันได้รับการกำหนดค่า 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: nginx กำลังส่ง RST

มันจะมีประโยชน์ที่จะเห็น (ก) วิธีที่ gunicorn เลือกเฟรมการตอบกลับจากขนาด 110k ถึง 120k bytes และ (b) วิธีที่ nginx เลือกเฟรมในช่วงเดียวกันของขนาด payload ตัวอย่างระหว่าง 110k และ 120k ไบต์ สามวิธีที่ HTTP สามารถใส่ข้อมูล: จัดเตรียมความยาวเนื้อหา ทำการเข้ารหัส chunked; หรือไม่ให้กรอบเลยยกเว้นสัญญาว่าจะปิดซ็อกเก็ตเมื่อร่างกายสมบูรณ์
Brandon Rhodes

กำลังจัดเตรียมส่วนหัวความยาวเนื้อหา ขอให้ฉันทิ้งแพ็กเก็ตเพื่อดูว่าเกิดอะไรขึ้นระหว่างสองอย่างนี้…
เดวิดโวเลเวอร์

อืมแปลกมาก tcpdump แนะนำว่า nginx กำลังทำการเชื่อมต่อ RST อย่างแข็งขัน (ดูการแก้ไข) Nginx ยังใช้ HTTP / 1.0 Connection: closeและ ฉันยังยืนยันว่าContent-Lengthส่วนหัวนั้นถูกต้อง
David Wolever

คำตอบ:


10

ตกลง! หลังจากตรวจสอบบันทึก nginx ซ้ำสองครั้งสิ่งนี้กลายเป็นปัญหา:

2014/05/26 16:50:56 [crit] 31396#0: *11 open() "…/proxy_temp/2/00/0000000002" failed (13: Permission denied) while reading upstream, client: 1.2.3.4, server: _, request: "GET /debug/big-file HTTP/1.1", upstream: "http://127.0.0.1:1234/debug/big-file", host: "example.com"

วิธีการที่สิทธิ์สำหรับproxy_tempไดเรกทอรีมีความยุ่งเหยิงซึ่งทำให้ nginx ไม่สามารถบัฟเฟอร์ได้อย่างถูกต้อง


1
ใช่ฉันเพิ่งแก้ปัญหาแบบนี้ดูในบันทึก nginx มีบรรทัดที่มี[crit] 6636#0: *16817 open() "/var/lib/nginx/proxy/7/03/0000000037" failed (13: Permission denied) while reading upstreamทำsudo chown -R www-data:www-data /var/lib/nginx/และได้รับการแก้ไขแล้ว
Epigene
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.