ประมาณสัปดาห์ละครั้ง แต่บางครั้งแม้แต่สองครั้งต่อวันหลังจากทำงานได้ดีสำหรับวันอินสแตนซ์ EC2 ของฉันไม่ตอบสนอง กราฟหน่วยความจำของ Munin บอกเล่าเรื่องราวที่ค่อนข้างตรงไปตรงมา: หน่วยความจำที่จัดสรรให้กับ "แอพ" เริ่มเพิ่มขึ้นและจะไม่หยุดจนกว่าจะมีการใช้งาน swap อย่างเต็มประสิทธิภาพ กราฟที่กำหนดเองอื่น ๆ แสดงว่ากระบวนการที่กำลังเติบโตอย่างต่อเนื่องคือ apache2
ฉันเรียกใช้การตั้งค่า Apache prefork มาตรฐานพร้อม mod_php และสคริปต์ PHP สองสามตัว ดังที่คุณเห็นในกราฟด้านล่างมีบางอย่างเกิดขึ้นที่เรียกใช้กระบวนการ apache2 เพื่อเริ่มใช้หน่วยความจำมากขึ้นเรื่อย ๆ เข็มสีเขียวอันแรกที่ฉันจับได้ทันเวลาและรีสตาร์ท Apache ก่อนที่สิ่งต่าง ๆ จะหมดไป เข็มที่สองได้รับอีกนิดและอินสแตนซ์จะต้องรีบูตทันที
สิ่งที่ฉันสงสัยคือจะแก้ไขข้อบกพร่องนี้ได้อย่างไร ขาดการตั้งค่า PHP ด้วย FastCGI และทำให้มันทำงานในกระบวนการของตัวเองเป็นวิธีที่ดีในการค้นหาว่าเป็น Apache หรือการรวมกันของ PHP และรหัสของฉันที่ทำให้เกิดการใช้หน่วยความจำมากเกินไป? พวกคุณทำอะไรเพื่อติดตามปัญหานี้?
UPDATE: ฉันสามารถติดตามการรั่วไหลหลังจากที่ strace เข้าร่วมตามที่ Matt แนะนำด้านล่าง
หลังจากค้นหากระบวนการ apache2 ที่ค่อยๆเพิ่มขึ้นอย่างต่อเนื่องในหน่วยความจำฉันเพิ่ม error_log () อีกครั้งในการเรียกใช้สคริปต์ PHP ของฉันซึ่งพิมพ์จำนวน RSS ทั้งหมดที่ใช้ในจุดต่างๆในการดำเนินการ (โดยใช้เอาต์พุตของ ps) อย่างไรก็ตามนั่นกลับกลายเป็นความเข้าใจผิด - ในขณะที่ปรากฏว่า RSS เพิ่มขึ้นหลังจากสคริปต์ของฉันดำเนินการเสร็จสิ้นการตรวจแก้จุดบกพร่องในภายหลังพบว่าไม่ใช่กรณีดังกล่าว ระวัง!
โชคดีที่การโทร error_log () เหล่านั้นกลายเป็นประโยชน์ในที่สุด เมื่อฉันเพิ่ม strace ( strace -p <pid> -tt -o trace.log -s 256
) ฉันเห็นว่าสำหรับแต่ละคำขอกระบวนการจัดสรรหน่วยความจำประมาณ 400k (มองหาการเรียกระบบ 'brk' และลบพารามิเตอร์ของการโทรครั้งแรกจากการโทรครั้งสุดท้าย - ไม่กี่คนที่มาในครั้งเดียว หลังจากนั้น) จากนั้นฉันค้นหาการเรียกระบบ 'เขียน' ครั้งล่าสุดที่มีข้อความ error_log () ของฉันซึ่งบอกฉันว่าจุดใดในสคริปต์ที่มีการจัดสรรหน่วยความจำ ด้วยการโทร error_log () ที่วางไว้อย่างมีกลยุทธ์เพื่อระบุตำแหน่งที่แม่นยำยิ่งขึ้นในที่สุดฉันก็พบผู้กระทำผิด
หน่วยความจำรั่วเมื่อเราเรียก curl_exec () จากสคริปต์ PHP ของเรา รหัส curl บางตัวที่เกี่ยวข้องกับการจัดการการเชื่อมต่อ SSL กำลังทำสิ่งผิดปกติ - การรั่วไหลหายไปเมื่อฉันเปลี่ยนเป็น HTTP รายการเปลี่ยนแปลงของ Curl อ้างอิงการรั่วไหลของหน่วยความจำ SSL สองสามรายการที่ได้รับการแก้ไขใน 7.19.5 (เราอยู่ที่ 7.18.2) ดังนั้นฉันจะลองต่อไป
ในขณะเดียวกันฉันทำงานกับ MaxRequestsPerChild ที่ต่ำมากซึ่งทำให้ Apache อยู่ในขอบเขตที่เหมาะสม ขอบคุณทุกคน!