معرفتش تنام قبل كده عشان موقعك وقع مرة واحدة في نص الزحمة؟ أو جالك طلبات زيارة كتير (High Traffic) ولقيت السيرفر جاب إفر (Error 502 Bad Gateway) ومبقاش بيرد على حد؟ "الوجع" ده مألوف جداً لأي مبرمج أو مسؤول سيرفرات (System Administrator) شاف السيرفر بتاعه بينهار قدام عينه وهو مش عارف يعمل إيه.
المشكلة غالباً مش في كود لغة بي إتش بي (PHP) نفسه، المشكلة الحقيقية بتكون في طريقة إدارة الموارد والتواصل بين خادم الويب (NGINX) ومدير العمليات (PHP-FPM). في المقال ده، هناخدك في رحلة عميقة عشان نظبط إعدادات الـ PHP-FPM مع NGINX ونخلي سيرفرك يستحمل ضغط عالي من غير أي توقف (Downtime).
Table of contents [Show]
إيه هو PHP-FPM وإزاي بيشتغل أساساً؟
عشان تحسن أداء أي حاجة، لازم تفهم هي شغال إزاي أصلاً. لغة بي إتش بي (PHP) لوحدها لغة برمجية، ومحتاجين حاجة تنفذ الكود ده لما يجيلنا طلب من المتصفح. زمان كان بيتم استخدام (CGI) أو (mod_php)، لكن الطريقة دي كانت بتستهلك الرامات (RAM) والمعالج (CPU) بشكل مرعب مع كل زيارة.
هنا بقى جه دور (PHP-FPM) أو (FastCGI Process Manager). الفكرة باختصار إن عندنا مدير عمليات بيفتح مجموعة من العمال أو العمليات الفرعية (Workers) ويستنى الطلبات اللي جاية من خادم الويب (NGINX). لما يجيلك طلب، الـ NGINX يحوله للـ PHP-FPM، والـ Worker يخلصه ويرجعه تاني.
السحر كله بقى بيحصل في إزاي ندير العمال دول! لو فتحنا عمال زيادة عن اللزوم، الرامات هتخلص والسيرفر هيقع. ولو فتحنا عدد قليل، الزوار هيستنوا كتير (High Latency) والسيرفر هيعمل طابور.
فهم وتكوين الـ Pools وإدارة العمليات
الـ (PHP-FPM Pools) هي المسؤولة عن تقسيم الشغل. كل (Pool) بيكون ليه إعدادات خاصة بيه، وأهم إستراتيجية لإدارة العمليات دي هي (Process Manager - PM). عندنا 3 أنواع رئيسية:
- static: بيثبت عدد العمليات (Child Processes) طول الوقت بغض النظر عن الشغل. حلو لو السيرفر مخصص لموقع واحد وراماته معروفة، بس استهلاكه ثابت.
- dynamic: بيبدأ بعدد معين وقت الفتح، ويزود أو ينقص حسب عدد الزيارات (Dynamic Scaling).
- ondemand: مبيفتحش أي عمليات في الأول خالص، وأول ما يجي طلب يفتح عملية جديدة. ممتاز لو عندك مواقع كتير ومش عايز تستهلك رامات طول الوقت.
الاختيار الأشهر والأضمن للمواقع الكبيرة هو الـ dynamic أو الـ static مع حسابات دقيقة.
الحسابات المعقدة ببساطة: إزاي تحسب Max Children صح؟
نيجي بقى للمعضلة الكبرى: إزاي أكتب رقم صحيح في خانة pm.max_children من غير ما أخلي السيرفر يهجص؟ تعال نحسبها بالورقة والقلم.
الخطوة الأولى: احسب متوسط استهلاك الرامات لعملية بي إتش بي واحدة (Average PHP Process Memory). افتح الشل (Terminal) وشغل الأمر ده:
ps --no-headers -o "rss,cmd" -C php-fpm7.4 | awk '{ sum += $1 } END { print sum / NR / 1024 " MB" }'
طلعلك مثلاً إن كل عملية بتاخد حوالي 50 ميجابايت (50MB).
الخطوة الثانية: شوف إجمالي الرامات المتاحة في السيرفر للـ PHP-FPM فقط (اشيل منها رامات النظام وقواعد البيانات MySQL).
الخطوة الثالثة: طبق المعادلة دي:
pm.max_children = (إجمالي الرامات المتاحة للـ PHP) / (متوسط استهلاك العملية الواحدة)
يعني لو عندك 2 جيجا للـ PHP (يعني 2048 ميجا)، وكل عملية بتاخد 50 ميجا، يبقى 2048 / 50 = 40.9. نقدر نخلي الرقم 40 بأمان تام!
إعدادات متطورة داخل ملف الـ www.conf
عشان تظبط الأداء بشكل احترافي، افتح ملف إعدادات الـ Pool (غالباً بيكون مكانه /etc/php/7.4/fpm/pool.d/www.conf) وعدل القيم دي بناءً على حساباتنا:
pm = dynamic
pm.max_children = 40
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
خلينا نشرح السطر الأخير الخطير ده: pm.max_requests = 500. معناه إن كل عملية بي إتش بي هتخدم 500 طلب وبعدين تموت وتتولد من جديد (Restart). الحركة دي بتحمينا تماماً من مشكلة تسريب الذاكرة (Memory Leak) اللي بتدمر السيرفرات مع الوقت.
ربط NGINX مع PHP-FPM بأفضل أداء ممكن
الخطوة التونسية هنا هي إننا نظبط الـ NGINX عشان يبعث الطلبات دي بسلاسة من غير اختناق (Bottleneck). افتح ملف إعدادات الموقع في الـ NGINX وظبط البلوك الخاص بالـ PHP بالشكل ده:
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\EE)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# تحسينات التايم آوت والbuffer
fastcgi_read_timeout 300;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
استخدام الـ Unix Socket (زي unix:/var/run/php/php7.4-fpm.sock) أسرع بكتير من استخدام الـ TCP (زي 127.0.0.1:9000) لأنه بيختصر طبقات الشبكة الداخلية.
نصيحة من أخ: المراقبة هي مفتاح الاستقرار
عزيزي المبرمج، السيرفرات عاملة زي العربيات السباق، مفيش حاجة اسمها "ظبطناها ونسيناها". بعد ما تعمل الإعدادات دي، لازم تستخدم أدوات مراقبة زي (htop) أو (Prometheus مع Grafana) عشان تشوف استهلاك الرامات والمعالج وقت الذروة. جرب تعمل ضغط تجريبي على موقعك بأداة زي (Apache Bench - ab) أو (Locust) وشوف السيرفر هيرد إزاي. الصبر والفهم التجريبي هم اللي بيخلوا السيرفر بتاعك يشتغل سنين من غير ولا ثانية توقف!