เรามีเซิร์ฟเวอร์ที่ทำงานบนไซต์ WordPress ที่มี nginx stack ที่ติดตั้งบน Ubuntu 20 LTS
การอัปโหลดที่มีขนาดใหญ่มากดูเหมือนจะติดค้างอยู่ในแฮนด์ออฟระหว่างพร็อกซี nginx และ PHP และฉันได้มาถึงจุดสิ้นสุดของสิ่งที่ฉันรู้วิธีแก้ปัญหาโดยไม่ต้องแค่จิ้มเพื่อดูว่าเกิดอะไรขึ้น (ซึ่งไม่ค่อยใช้เวลาหรือ ทางข้างหน้า) เท่าที่ฉันสามารถบอกได้ ฉันได้เพิ่มระยะหมดเวลาที่จำเป็นและเพิ่มขีดจำกัดของดิสก์ทั้งหมดแล้ว แต่เห็นได้ชัดว่าฉันยังคงขาดบางสิ่งไป
สำหรับกรณีการใช้งานของเรา เราจำเป็นต้องอนุญาตให้อัปโหลดได้สูงสุด 50GB ซึ่งเราทำงานได้อย่างไม่มีปัญหาในสภาพแวดล้อมการจัดเตรียมที่รัน LAMP stack มาตรฐาน เราไม่มีปัญหากับไฟล์ที่มีขนาดต่ำกว่า ~2GB แต่สิ่งใดก็ตามที่อาจล้มเหลวหรือล้มเหลวตามเกณฑ์บางอย่างที่ฉันไม่สามารถติดตามได้ ในขณะที่แก้ไขปัญหาก่อนหน้านี้ เวลาที่การคัดลอกไฟล์หยุดดูเหมือนไม่มีกฎเกณฑ์ (โดยสำเร็จสูงสุด 10GB) แต่ด้วยการกำหนดค่าปัจจุบัน (ดูด้านล่าง) เวลาจะหยุดอย่างต่อเนื่องเมื่อ PHP ทีเอ็มพี
ไฟล์ถึง 2GB
เมื่อเราอัปโหลดไฟล์ขนาดใหญ่มาก เราสามารถดูไฟล์ temp ที่เข้ามาใช้พื้นที่ดิสก์จนกว่าไฟล์ทั้งหมดจะอยู่ /mnt/tmp/[nginx_tmp_path]
(ใช่ มีพื้นที่ว่างในดิสก์เหลือเฟือ) หลังจากนั้นเราจะเห็นไฟล์ถูกคัดลอกไปยัง php.ini ทีเอ็มพี
เส้นทาง แต่หลังจากนั้นไม่กี่วินาที php.ini ทีเอ็มพี
ไฟล์มีขนาดไม่ใหญ่ขึ้นและกระบวนการคัดลอกหยุดทำงาน ในที่สุด การหมดเวลาหนึ่งใน 600 วินาทีก็มาถึง และมีข้อผิดพลาดที่บันทึกไว้ (ดูด้านล่าง) ในภาพหน้าจอนี้ เราได้อัปโหลดเสร็จสมบูรณ์ (จากมุมมองของเบราว์เซอร์/ผู้ใช้ปลายทาง) ขนาด 14.8GB ที่ค้างอยู่บนการถ่ายโอนไฟล์ tmp ที่ขนาดประมาณ 2GB
เมื่อสิ้นสุดช่วงเวลา 600 วินาที จะอยู่ในบันทึกข้อผิดพลาดของ Apache:
(70008) ผลลัพธ์บางส่วนถูกต้อง แต่การประมวลผลไม่สมบูรณ์: [ไคลเอนต์ <MY_IP>] AH01075: เกิดข้อผิดพลาดในการส่งคำขอไปที่: (กำลังอ่านอินพุตกลุ่ม), ผู้อ้างอิง: https://<THE_URL>/wp-admin/media-new.php
และบันทึกข้อผิดพลาด nginx กล่าวว่า:
2512066#0: *9 อัปสตรีมหมดเวลา (110: การเชื่อมต่อหมดเวลา) ขณะส่งคำขอไปยังอัปสตรีม ไคลเอ็นต์: <MY_IP> เซิร์ฟเวอร์: <INTERNAL_IP> คำขอ: "POST /wp-admin/async-upload.php HTTP/ 2.0", อัปสตรีม: "http://127.0.0.1:81/wp-admin/async-upload.php", โฮสต์: "<THE_URL>", ผู้อ้างอิง: "https://<THE_URL>/wp-admin/ สื่อใหม่.php"
สิ่งสำคัญคือต้องสังเกตว่าข้อความเหล่านี้จะไม่ปรากฏในไฟล์บันทึกจนกว่าจะครบ 10 นาทีหลังจากที่การอัปโหลดเริ่มต้นมาถึงเซิร์ฟเวอร์โดยสมบูรณ์ ซึ่งเป็นเวลา 9 นาทีขึ้นไปหลังจากที่ดูเหมือนว่าการคัดลอกไฟล์จะหยุดชั่วคราว/หยุดทำงาน ฉันเชื่อว่ามีบางอย่างที่ทำให้การคัดลอกไฟล์ติดขัด และในที่สุดก็ถึงระยะหมดเวลา - ฉันไม่เชื่อว่าปัญหาเกิดจากการหมดเวลาเอง ระหว่างการหยุดการคัดลอกไฟล์และข้อผิดพลาดการหมดเวลาที่ปรากฏในไฟล์บันทึก ไม่มีกิจกรรมที่เพิ่มขึ้นหรือผิดปกติบนเซิร์ฟเวอร์ และบริการทั้งหมดทำงานและตอบสนองตามที่คาดไว้
ด้วยการกำหนดค่าปัจจุบัน PHP ทีเอ็มพี
ไฟล์จะเติบโตเป็น 2097152 KB เสมอ (อ้างอิงจาก ดู่ -a
) ซึ่งทำให้ฉันเชื่อว่าฉันถึงขีดจำกัดขนาดไฟล์ในตัวที่ฉันยังไม่ได้เปิดเผยในตอนนี้
ตัวเลือกการกำหนดค่าเซิร์ฟเวอร์ nginx ที่เกี่ยวข้องคือ:
ใน เซิร์ฟเวอร์
บริบท:
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;
proxy_max_temp_file_size 51200m;
fastcgi_connect_timeout 600;
fastcgi_read_timeout 600;
fastcgi_send_timeout 600;
ปิด fastcgi_request_buffering;
keepalive_timeout 600;
send_timeout 600;
client_max_body_size 0;
client_body_temp_path /mnt/tmp;
client_body_in_file_only สะอาด;
การกำหนดค่า VirtualHost ของ Apache:
ส่วนหัว RequestReadTimeout=0 เนื้อหา=0
หมดเวลา 3600
ProxyTimeout 3600
และสุดท้าย config PHP:
memory_limit = -1
max_execution_time = 0
max_input_time = -1
post_max_size = 50G
upload_max_filesize = 50G
default_socket_timeout = -1
ฉันไม่รู้ว่าอะไรเป็นสาเหตุของอาการที่ฉันเห็นพอยน์เตอร์ใด ๆ ที่ชื่นชม!
หมายเหตุเพิ่มเติม: อาการดังกล่าวทำให้รู้สึกว่าไม่เกี่ยวข้อง แต่ในกรณีที่เป็น... ไซต์ทำงานผ่าน WP Rocket แต่ไม่มีบริการพร็อกซีภายนอกเช่น CloudFlare
อัปเดต: ฉันเพิ่มบรรทัดเหล่านี้ในการกำหนดค่า nginx:
proxy_http_version 1.1;
การเชื่อมต่อ proxy_set_header "";
สิ่งนี้เปลี่ยนอาการเล็กน้อย แต่ไม่ได้แก้ไขปัญหา ด้วยการเปลี่ยนแปลงนี้ พฤติกรรมจะเปลี่ยนกลับเป็นสิ่งที่ฉันอธิบายไปก่อนหน้านี้ และการถ่ายโอนไฟล์จะหยุดชะงักในจุดที่คาดเดาไม่ได้ ตัวอย่างแรกด้านล่างหยุดที่ 3823176 KB และตัวที่สองหยุดที่ 3264364 KB สาเหตุของความแตกต่างในพฤติกรรมไม่สมเหตุสมผลสำหรับฉัน แต่ควรรายงาน
อัพเดท 2: ฉันสามารถระบุได้อย่างชัดเจนว่าสิ่งนี้เป็นปัญหาในการส่งต่อของ ทีเอ็มพี
ไฟล์ระหว่าง nginx และ php แต่ฉันไม่สามารถระบุสิ่งเฉพาะที่ทำให้กระบวนการหยุดทำงาน
เราสามารถข้าม nginx proxy และใช้เฉพาะ PHP เท่านั้น ทีเอ็มพี
โดยเพิ่มบรรทัดเหล่านี้ในการกำหนดค่า nginx:
ปิด proxy_buffering;
ปิด proxy_request_buffering;
ด้วยการกำหนดค่านี้ ไฟล์จะเข้าไปโดยตรง /mnt/tmp/php<RND_STR>
และเมื่อการอัปโหลดเสร็จสิ้น แอปพลิเคชันของเราจะเลือกไฟล์อย่างถูกต้อง ทีเอ็มพี
และเสร็จสิ้นภารกิจ
อย่างไรก็ตาม การอัปโหลดช้าลงเหลือประมาณ 1/3 ของแบนด์วิดท์ที่มีอยู่ ดังนั้นจึงไม่ใช่วิธีแก้ปัญหาที่ดี อย่างไรก็ตาม พิสูจน์ได้ว่านี่ไม่ใช่ปัญหาของแอปพลิเคชัน
นี่คือสิ่งที่เกิดขึ้น:
- ผู้ใช้อัปโหลดไฟล์ขนาดใหญ่ (50GB เป็นกรณีการใช้งานสูงสุดของเรา)
- ไฟล์มาถึงใน nginx
ทีเอ็มพี
ที่ตั้งไว้อย่างครบถ้วน
- มีความพยายามที่จะคัดลอกไฟล์จาก nginx
ทีเอ็มพี
เป็น PHP ทีเอ็มพี
- กระบวนการคัดลอกจะหยุดทำงานภายในไม่กี่วินาทีโดยที่ไม่สามารถคาดเดาได้ แต่ระหว่าง 3GB และ 10GB [3b] ณ เวลานี้ เราสามารถเห็นทั้งสองอย่าง ทีเอ็มพี
ไฟล์และ PHP ทีเอ็มพี
ไฟล์มีจำนวนไบต์ที่ควรจะเติบโตจนกว่าจะเท่ากับขนาดของ nginx ทีเอ็มพี
ไฟล์ แต่พวกเขาไม่ได้ทั้งสองไฟล์จะอยู่ตามเดิมจนกว่าจะครบเวลาหนึ่งใน 600 วินาที (ดูด้านบน) จากนั้นข้อผิดพลาดจะปรากฏขึ้นในไฟล์บันทึกและทั้งสองไฟล์ ทีเอ็มพี
ไฟล์หายไป [3c] หากไฟล์มีขนาดต่ำกว่า 3GB ไฟล์จะทำงานทุกครั้ง หากไฟล์มีขนาดใหญ่กว่า 3GB บางครั้งไฟล์จะทำงานได้ แต่ไฟล์อื่นไม่สามารถใช้งานได้ ยิ่งไฟล์มีขนาดเล็กเท่าใด โอกาสในการทำงานก็จะยิ่งมากขึ้นเท่านั้น
- ข้าม nginx's
ทีเอ็มพี
ทำงานได้อย่างสมบูรณ์ตามที่คาดไว้ ยกเว้นว่าการอัปโหลดจะช้า
มีบางอย่างกำลังวางสายอย่างแน่นอนในระหว่าง ทีเอ็มพี
การส่งต่อไฟล์ระหว่าง nginx และ PHP เมื่อไฟล์มีขนาดใหญ่อย่างน่าขยะแขยง และฉันก็อยากรู้ว่ามันคืออะไร