كلُّ عاملِ PHP يمسك ذاكرةً مشغولًا كان أو خاملًا. فإن قلّوا اصطفّت الطلبات خلف بعضها، وإن كثروا نفدت ذاكرةُ الجهاز وبدأ يبدّل إلى القرص فصار أبطأ ممّا كان سيكون بعددٍ أقلّ.
قِس عاملًا واحدًا
ps -ylC php-fpm8.3 --sort:rss | awk '{sum+=$8; n++} END {print sum/n/1024 " MB average"}'
من 30 إلى 80 ميغابايت عادةً. وإطارُ عملٍ ثقيل أو طقمُ إضافاتٍ كبير يرفعه، والذي يعنيك رقمُك أنت لا رقمٌ معتاد.
الحساب
max_children = (RAM available to PHP) / (average worker size)
# 8GB box, 2GB for the database and the system, 50MB a worker:
# 6000 / 50 = 120 - then be conservative and use 80
اترك متّسعًا. فالعاملُ الذي يصادف صفحةً ثقيلة يستهلك أضعافَ المتوسّط، والحوضُ المقيسُ على الحدّ بالضبط سيتجاوزه لحظةَ يصير الازدحام غير معتاد — وهي بعينها اللحظةُ التي تحتاجه فيها أن يصمد.
ثابت أم متغيّر أم عند الطلب
- static — العمّال كلُّهم يبدؤون عند الإقلاع. الأسرع، ويستهلك الذاكرة مشغولًا كان أو لا. صوابٌ لجهازٍ مخصَّص تحت حِملٍ ثابت.
- dynamic — يُبقي احتياطًا وينمو حتى الحدّ. وهو الافتراض المعقول.
- ondemand — يبدأ عند الطلب ويقتل بعد مهلة. أقلُّ ذاكرةً، وتأخّرٌ يسير في الطلب الأوّل. صوابٌ لمواقع صغيرة كثيرة على جهازٍ واحد.
pm = dynamic
pm.max_children = 80
pm.start_servers = 12
pm.min_spare_servers = 8
pm.max_spare_servers = 24
pm.max_requests = 500
max_requests تأمينٌ ضدّ التسرّب
يُحال العاملُ بعد ذلك العدد من الطلبات ويحلّ مكانه عاملٌ جديد. ولا يكلّف ذلك شيئًا يُذكَر، ويحتوي تسرّبًا بطيئًا في أيّ مكتبةٍ لا تملكها.
افحص أنافدون أنت أم لا
grep "server reached pm.max_children" /var/log/php8.3-fpm.log
ذلك السطر يعني أنّ طلباتٍ اصطفّت. فإن لم يظهر قطّ فالحوضُ كبيرٌ كفاية، ورفعُه لن يجعل شيئًا أسرع.
على استضافة EGPHP يُقاس الحوضُ ويُراقَب عنك. وهذا لخادمٍ افتراضيّ تديره أنت، حيث نادرًا ما يكون الافتراضُ صحيحًا لذلك الجهاز.
