วิธีการตรวจสอบการรั่วไหลของหน่วยความจำด้วย Apache และ PHP?


16

เรากำลังใช้งานเว็บไซต์ Drupal ที่มีประสิทธิภาพซึ่งทำตัวแบบทางการเงิน ดูเหมือนว่าเราจะใช้หน่วยความจำรั่วบางส่วนเนื่องจากข้อเท็จจริงที่ว่าเวลาที่หน่วยความจำ apache ใช้เพิ่มขึ้นในขณะที่จำนวนกระบวนการ apache ยังคงมีเสถียรภาพ:

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

เรารู้ว่าปัญหาหน่วยความจำมาจาก apache / PHP เพราะเมื่อใดก็ตามที่เราออก/etc/init.d/httpd reloadการใช้งานหน่วยความจำลดลง (ดูภาพหน้าจอด้านบนและด้านล่างเอาท์พุท CLI):

ก่อนที่จะโหลด httpd

$ ฟรี
             แคชบัฟเฟอร์ที่ใช้ร่วมกันทั้งหมดที่ใช้รวมกันหมดแล้ว
Mem: 49447692 45926468 3521224 0 191100 22609728
- / + บัฟเฟอร์ / แคช: 23125640 26322052
แลกเปลี่ยน: 2097144 536552 1560592

หลังจาก httpd โหลดซ้ำ

$ ฟรี
             แคชบัฟเฟอร์ที่ใช้ร่วมกันทั้งหมดที่ใช้รวมกันหมดแล้ว
Mem: 49447692 28905752 20541940 0 191360 22598428
- / + บัฟเฟอร์ / แคช: 6115964 43331728
แลกเปลี่ยน: 2097144 536552 1560592

แต่ละเธรด apache ได้รับการกำหนด PHP ที่memory_limit512MB ซึ่งอธิบายการใช้งานหน่วยความจำสูงขึ้นอยู่กับปริมาณการร้องขอที่ต่ำและmax_execution_time120 วินาทีซึ่งควรยุติเธรดที่การดำเนินการใช้เวลานานและควรป้องกันการเติบโตของการใช้หน่วยความจำอย่างต่อเนื่อง เห็น

ถาม: เราจะตรวจสอบสิ่งที่ทำให้หน่วยความจำรั่วได้อย่างไร

นึกคิดฉันกำลังมองหาขั้นตอนการแก้ไขปัญหาที่ฉันสามารถทำได้ในระบบโดยไม่ต้องรบกวนทีมงาน dev

ข้อมูลเพิ่มเติม:

OS: RHEL 5.6
PHP: 5.3
Drupal: 6.x
MySQL: 5.6

FYI เราทราบถึงปัญหาการแลกเปลี่ยนที่เรากำลังตรวจสอบแยกต่างหากและไม่มีส่วนเกี่ยวข้องกับการรั่วไหลของหน่วยความจำที่เราได้สังเกตเห็นก่อนที่การแลกเปลี่ยนจะเกิดขึ้น


ครั้งล่าสุดที่ฉันประสบปัญหาการใช้งานหน่วยความจำอย่างรุนแรงกับ LAMP + Drupal คือเมื่อฉันมีไลบรารี memcached PHP ที่ใช้งานอยู่ หลังจากที่ฉันลบมันทิ้งการใช้งานหน่วยความจำลดลงอย่างมาก เพียงแค่เดา อาจพิมพ์คำตอบที่เหมาะสมสำหรับคุณอีกเล็กน้อยในภายหลัง
Janne Pikkarainen

@JannePikkarainen: เรากำลังใช้memcachedห้องสมุดPHP จากหน้าผู้ดูแล memcache memcache.phpทั้งหมดที่เราเห็นคือเราได้จัดสรร5GBให้กับ memcache ซึ่ง3.3GBมีการใช้งานอยู่ จะดีมากถ้าคุณสามารถช่วยเหลือเราเพิ่มเติมได้ที่นี่
สูงสุด

ใช่memcachedภูตเองอาจจะไม่เป็นไร มันเป็นไลบรารี memcache ของ PHP ซึ่งอาจหรืออาจจะไม่รั่วไหลหน่วยความจำ (และทำให้ Apache ใช้กระบวนการหน่วยความจำมากขึ้น) ปัญหาของฉันประมาณ 1-2 ปีที่ผ่านมาดังนั้นสิ่งต่างๆอาจได้รับการแก้ไขหลังจากนั้น อย่างไรก็ตามหาก memcached นั้นไม่จำเป็นสำหรับคุณลองปิดการใช้งานชั่วขณะหนึ่งและดูว่าการใช้หน่วยความจำ Apache ยังคงเพิ่มขึ้นหรือไม่
Janne Pikkarainen

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

@DavidSchwartz: ปัญหาคือถ้าเราไม่รีสตาร์ทhttpdการใช้หน่วยความจำจะเพิ่มขึ้นเรื่อย ๆ และในที่สุดกล่องก็ล้มเหลวด้วยข้อความเคอร์เนลหน่วยความจำบางส่วน การแสดงนั้นดี (จนกว่าการใช้หน่วยความจำใกล้ถึงขีด จำกัด หน่วยความจำ) โปรดเพิกเฉยต่อปัญหาการแลกเปลี่ยน
Max

คำตอบ:


11

เรารู้ว่าปัญหาหน่วยความจำมาจาก apache / PHP เพราะเมื่อใดก็ตามที่เราออก / etc / init.d/httpd โหลดการใช้งานหน่วยความจำลดลง

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

แต่ละเธรด apache จะถูกกำหนดเป็น PHP memory_limit 512MB ซึ่งจะอธิบาย

ไม่มันไม่ คุณกำลังรายงานค่าเฉลี่ยของเซิร์ฟเวอร์ที่ไม่ว่าง 7 และสูงสุด 25 เซิร์ฟเวอร์ แต่กราฟหน่วยความจำของคุณแสดงเดลต้าประมาณ 25Gb

จริง ๆ แล้วคุณควรเริ่มต้นใหม่ด้วยการปรับแต่ง HTTP ขั้นพื้นฐาน - ดูเหมือนว่าคุณจะเรียกใช้ 256 httpds คงที่ แต่การใช้งานสูงสุดของคุณคือ 25 - นี่เป็นเพียงใบ้ธรรมดา

และ max_execution_time 120 วินาทีซึ่งควรยกเลิกเธรดที่การดำเนินการใช้เวลานานกว่า

ไม่ใช่ - ถ้าเธรดการดำเนินการอยู่ภายในล่าม PHP - ไม่ใช่ถ้า PHP ถูกบล็อก

ที่ดำเนินการสร้างแบบจำลองทางการเงิน

(ถอนหายใจ)

มันจะมีประโยชน์ถ้าคุณให้รายละเอียดว่าคุณกำหนดค่า Apache, threaded หรือ prefork, เวอร์ชันใด, วิธีเรียกใช้ PHP (โมดูล, cgi, fastcgi), ไม่ว่าคุณจะใช้การเชื่อมต่อแบบถาวรหรือไม่

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


2

คุณอาจแก้ไขปัญหาของคุณได้ในตอนนี้ ในฐานะชั่วคราวเพื่อป้องกันไม่ให้เซิร์ฟเวอร์สลับเปลี่ยน / thrashing ฉันเรียกใช้คำสั่งต่อไปนี้ทุก ๆ ชั่วโมงจาก cron:

#!/bin/sh 
sync; echo 3 > /proc/sys/vm/drop_caches

ฉันไม่ได้บอกว่านี่เป็นวิธีการแก้ปัญหาเพียงวิธีการทำให้สิ่งต่าง ๆ ทำงานและลด downtimw ในขณะที่คุณลงทุนสาเหตุที่แท้จริงของการรั่วไหลของหน่วยความจำ

รายละเอียดเพิ่มเติมสามารถดูได้ที่นี่

http://www.tecmint.com/clear-ram-memory-cache-buffer-and-swap-space-on-linux/


1

เห็นได้ชัดว่านี่คือวิธีการทำงานของ PHP - และถ้าคุณทำลูปยาว ๆ ที่คุณกำลังจัดสรรวัตถุและใครจะรู้ว่าคุณกำลังส่งมันผ่านการอ้างอิงดังนั้นวิธีเดียวที่จะจัดการกับมันคือหลังจากคำขอ N สำหรับกระบวนการ PHP แต่ละกระบวนการ เพื่อหยุดมัน หากคุณเรียกใช้ PHP ในฐานะ CGI คำขอทั้งหมดจะทำให้เกิดการตอบสนองดังนั้นจึงไม่มีหน่วยความจำรั่วไหลและประสิทธิภาพการทำงานอาจลดลงอย่างมาก นอกจากนี้คุณยังสามารถเรียกใช้ fast-cgi ได้เช่นที่ 1,000 คำร้องขอกระบวนการ php-fcgi นั้นถูกฆ่าและหน่วยความจำนั้นถูกปล่อยออกมา - ไม่มีการรั่วไหลของหน่วยความจำ ถ้าคุณเรียกใช้ PHP เป็นโมดูล mod_php คุณอาจลองตั้งค่า maxrequests ใน httpd.conf เพื่อดูว่ามันช่วยได้หรือไม่ ฉันจะลองตั้งค่าเช่น 10 - ถ้ามันใช้งานได้ประสิทธิภาพลดลงจะไม่สูง แต่ไม่ควรมีหน่วยความจำรั่ว


-1

ตรวจสอบหน่วยความจำในไฟล์ php.ini ทั่วโลก ไม่เพียงแค่รูปลอก valre เช่น 1 G ฯลฯ ... ฉันขอแนะนำว่า php.ini ท้องถิ่นถูกนำเข้าสู่บัญชีนั้นเพื่อไม่ให้กระทบกับเซิร์ฟเวอร์ทั้งหมด ฉันขอแนะนำให้ตั้งค่าขีด จำกัด ระดับโลก php.ini ให้อยู่ที่ประมาณ 64M เนื่องจากโดยทั่วไปจะเพียงพอสำหรับบัญชีส่วนใหญ่

ตรวจสอบการตั้งค่า apache ของคุณด้วย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.