วิธีการแก้จุดบกพร่องหมดเวลา apache?


14

ผมใช้โปรแกรมเว็บ PHP บนเซิร์ฟเวอร์ Apache 2.2 (อูบุนตูเซิร์ฟเวอร์ 10.04, 8x2GHz, 12GB RAM) preforkโดยใช้ ในแต่ละวัน Apache ได้รับคำขอประมาณ 100k-200k คำขอเหล่านี้มีประมาณ 100-200 ครั้งซึ่ง จำกัด การหมดเวลา (ดังนั้นประมาณหนึ่งในทุก ๆ พันครั้ง) คำขออื่น ๆ ทั้งหมดจะได้รับบริการต่ำกว่าการหมดเวลา

ฉันจะทำอย่างไรเพื่อค้นหาสาเหตุที่เกิดขึ้น หรือเป็นเรื่องปกติที่จะมีบางส่วนของคำขอทั้งหมดหมดเวลาหรือไม่

นี่คือสิ่งที่ฉันทำไปแล้ว:

ร้องขอเวลาตอบกลับ

จะเห็นได้ว่ามีคำขอน้อยมากที่อยู่ระหว่างขีด จำกัด การหมดเวลาและคำขอที่สมเหตุสมผล ปัจจุบันการ จำกัด การหมดเวลาถูกตั้งไว้ที่ 50 วินาทีก่อนหน้านี้มันถูกตั้งไว้ที่ 300 และยังคงเป็นสถานการณ์เดียวกันกับการหมดเวลาและจากนั้นช่องว่างขนาดใหญ่ลงไปที่คำขออื่น ๆ

คำขอทั้งหมดที่หมดเวลานั้นเป็นAJAXคำขอ แต่หลังจากนั้นส่วนใหญ่จะเป็นคำขอดังนั้นอาจเป็นเรื่องบังเอิญมากกว่า โค้ดส่งคืนของ Apache คือ200แต่ถึงขีด จำกัด การหมดเวลาอย่างชัดเจน พวกเขามาจากหลากหลาย IP ที่แตกต่างกัน

ฉันได้ดูคำขอที่หมดเวลาและไม่มีอะไรพิเศษเกี่ยวกับพวกเขาหากฉันทำคำขอเดียวกันที่พวกเขาทำในเวลาน้อยกว่าหนึ่งวินาที

ฉันพยายามดูแหล่งข้อมูลต่าง ๆ เพื่อดูว่าฉันสามารถหาสาเหตุ แต่ไม่มีโชคได้หรือไม่ มีหน่วยความจำฟรีมากมายอยู่เสมอ (ขั้นต่ำคือประมาณ 3GB ฟรี) บางครั้งการโหลดจะสูงถึง 1.4 และการใช้ CPU ถึง 40% แต่การหมดเวลาส่วนใหญ่เกิดขึ้นเมื่อการโหลดและการใช้งาน CPU ต่ำ การเขียน / อ่านดิสก์ค่อนข้างคงที่ระหว่างวัน ไม่มีรายการในบันทึกการสืบค้นแบบช้าของ MySQL (ตั้งค่าให้บันทึกสิ่งใด ๆ ที่สูงกว่า 1 วินาที) การร้องขอไม่ใช้ฐานข้อมูลจำนวนมากที่เขียน / อ่าน

ร้องขอเวลาตอบกลับด้วยโหลดระบบ / cpu

สีน้ำเงินคือการใช้ประโยชน์ CPU ซึ่งสูงสุดที่ 40% และสีแดงจะโหลดสูงสุดที่ 1.4 ดังนั้นเราจะเห็นว่าเราได้รับการหมดเวลาแม้จะมีการใช้งาน CPU / โหลดต่ำ (แหลมสิบวินาทีนั้นสอดคล้องกับการใช้งาน CPU แต่นั่นเป็นอีกปัญหาหนึ่งฉันมีความหวังสูงในการค้นหาสาเหตุที่อาจเกิดขึ้น)

ไม่มีข้อผิดพลาดในบันทึกข้อผิดพลาดของ Apache และฉันไม่ได้เห็นว่ามันเข้าสู่กระบวนการ Apache มากกว่า 200 กระบวนการ

การตั้งค่าเซิร์ฟเวอร์:

Timeout 50 
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2

<IfModule mpm_prefork_module>
    ServerLimit     350
    StartServers        20
    MinSpareServers     75
    MaxSpareServers     150
    MaxClients          320
    MaxRequestsPerChild 5000
</IfModule>

ปรับปรุง:

ฉันอัปเดตเป็น Ubuntu 12.04.1 ในกรณีที่ไม่มีการเปลี่ยนแปลง ฉันได้เพิ่ม mod_reqtimeout ด้วยการตั้งค่า:

RequestReadTimeout header=20-40,minrate=500
RequestReadTimeout body=10,minrate=500

ตอนนี้หมดเวลาเกือบทั้งหมดเกิดขึ้นที่ 10 วินาทีหนึ่งหรือสองที่ 20 วินาที ฉันหมายความว่าเวลาส่วนใหญ่ที่ได้รับคำขอที่เป็นปัญหาจะได้รับหรือไม่ เนื้อหาคำขอไม่ควรใหญ่กว่าสองสามร้อยไบต์ ฉันได้ตรวจสอบการรับส่งข้อมูลเครือข่ายเป็นเวลา 1 วินาทีและมันไม่เคยสูงกว่า 1Mbit / s และฉันไม่เห็น rxerrs หรือ rxdorps ใด ๆ โดยพิจารณาว่าเซิร์ฟเวอร์นั้นอยู่ในสาย 1Gbit / s ซึ่งไม่เหมือนกับ HopelessN00b โพสต์เกี่ยวกับ เป็นกรณีของการเชื่อมต่อผู้ใช้ที่ไม่ดีบ้างไหม?

สำหรับหนามแหลมทุกชั่วโมง (ดูเหมือนว่าจะลอยไปรอบ ๆ เล็กน้อยในกราฟด้านบนพวกเขาอยู่บน 33 นาทีที่ผ่านมาชั่วโมงตอนนี้พวกเขาใน 12 นาทีที่ผ่านมา) ฉันพยายามที่จะดูว่ามีอะไรทำงานเป็นระยะ ๆ ( crons ฯลฯ ) แต่ไม่พบอะไรเลย การรวบรวมขยะ PHP ทำงานสองครั้งต่อชั่วโมง แต่ไม่ใช่ในช่วงเวลาที่แทบจะหยุดนิ่ง แต่ฉันก็พยายามปิดการใช้งาน แต่ก็ไม่ได้ทำให้แตกต่าง

ฉันใช้ dstat กับ --top-cpu และ top เพื่อดูกระบวนการในเวลาที่ spikes และสิ่งที่ปรากฏขึ้นคือ apache ทำงานหนักไม่กี่วินาที แต่ไม่มีกระบวนการอื่นที่ใช้ cpu ที่สำคัญ

ฉันได้ซูมเข้าไปในกราฟของขวาก: เวลาตอบสนองคำขอที่ถูกซูม

สำหรับฉันดูเหมือนว่า apache จะหยุดสักครู่แล้วทำงานอย่างหนักเพื่อประมวลผลคำขอที่เข้ามาในช่วงหยุดพัก สิ่งใดที่อาจทำให้เกิดการหยุดชะงักเช่นนี้หรือฉันกำลังตีความหมายผิด ๆ


1
ฉันต้องการโพสต์ด้วยกราฟมากกว่าคำขอ แต่ตัวแทนของฉันต่ำเกินไป
Leon

คำตอบ:


4

สิ่งแรกที่ฉันสังเกตดูกราฟแรกของคุณดูเหมือนว่าจะมีการชะลอตัวทุกชั่วโมง (เกิดขึ้นประมาณ 40 นาทีที่ผ่านมาชั่วโมง) ซึ่งอาจก่อให้เกิดปัญหา คุณควรดูที่ตัวกำหนดเวลางานบนระบบปฏิบัติการ / ฐานข้อมูล

ตามข้อมูลที่คุณให้ไว้ขั้นตอนต่อไปของฉันคือดูความถี่ของเวลาตอบสนอง (จำนวนการตอบสนองบนแกน Y เทียบกับระยะเวลา X) แต่รวมเฉพาะ URL ที่แสดงการหมดเวลา (หรือมากกว่าหนึ่งครั้ง ) ในระบบทั่วไปสิ่งนี้ควรเป็นไปตามการแจกแจงแบบปกติหรือปัวซอง - คำขอที่หมดเวลาอาจเป็นส่วนหนึ่งของหาง - ซึ่งในกรณีนี้คุณต้องมุ่งเน้นความพยายามของคุณในการปรับจูนทั่วไป OTOH ถ้าการแจกแจงนั้นเป็นแบบไบโอดัลคุณจำเป็นต้องค้นหาความขัดแย้งในรหัสของคุณ


ขอบคุณสำหรับคำตอบของคุณ ฉันกำลังตรวจสอบสิ่งที่อาจทำให้เกิดการชะลอตัวทุกชั่วโมง ในช่วงเวลาที่ฉันทำพล็อตความถี่ของข้อมูลที่ฉันมีอยู่แล้ว นี่เป็นเพียงหนึ่งใน URL ที่มีปัญหาการหมดเวลา (แต่ URL อื่น ๆ ดูคล้ายกันมาก): leela.kikora.no/apache_hist_show.pngจำนวนการหมดเวลาน้อยมากเมื่อเทียบกับที่ใช้เวลาน้อยกว่า 10 วินาที แต่ดูเหมือน เหมือนว่ามันอาจไม่ได้เป็นส่วนหนึ่งของหาง แต่ในทางกลับกันอาจเป็นเพราะพวกเขาเป็นตัวแทนของสิ่งที่จะใช้เวลา 50+ วินาทีมันควรจะเป็นแบบนี้
ลีออน

3

ฉันมีความคิดอื่นเกี่ยวกับเรื่องนี้ตามความจริงที่ว่าคุณได้รับคำขอจำนวนมากต่อวันและดูเหมือนว่าจะมีการหมดเวลาเฉพาะในช่วงชั่วโมงเร่งด่วนเท่านั้น (จากรูปภาพที่คุณโพสต์)

มีโพสต์ในบล็อก Server FaultPer Second Measurements Don't Cut It ... เป็นไปได้หรือไม่ว่าคำขอเหล่านี้บางส่วนกำลังประสบปัญหาเดียวกับที่ทีม ServerFault พบ

เราค้นพบว่าเราทิ้งแพ็คเก็ตบ่อยๆบน 1 Gbit / s อินเตอร์เฟสที่อัตราเพียง 10-30 MBit / s ซึ่งทำให้ประสิทธิภาพของเราแย่ลง เนื่องจากอัตรา 10-30 MBit / s นั้นเป็นจำนวนบิตที่ถ่ายโอนต่อ 5 นาทีที่แปลงเป็นอัตราหนึ่งวินาที เมื่อเราขุดเข้าไปใกล้กับ Wireshark และใช้กราฟ IO หนึ่งมิลลิวินาทีเราเห็นว่าเรามักจะปล่อยอัตรา 1 Mbit ต่อมิลลิวินาทีของส่วนต่อประสานที่เรียกว่า 1 Gbit / s


น่าสนใจฉันจะดูมัน ฉันเปิดใช้งาน mod_reqtimeout และตั้งเป็น RequestReadTimeout header = 20-40, minrate = 500 และ RequestReadTimeout body = 10, minrate = 500 และหมดเวลาเกือบทั้งหมดที่ 10 วินาที ฉันหมายความว่าเนื้อหาร้องขอยาวเกินไป (เนื้อหาไม่ควรเกินสองสามร้อยไบต์) ดังนั้นผู้ใช้บางรายของฉันมีการเชื่อมต่อที่ไม่ดีหรืออย่างที่คุณบอกว่ามีความแออัดของเซิร์ฟเวอร์ของฉัน
Leon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.