بهینه سازی تنظیمات PHP-FPM

بهینه سازی تنظیمات PHP-FPM

اگر از یک وب سرور با PHP-FPM استفاده می کنید، به احتمال زیاد باید تنظیمات اولیه ی مربوط به PHP-FPM را بر اساس نیازمندی ها و وضعیت سرور خود تغییر دهید. ما در این مقاله می خواهیم به شما روشی را معرفی کنیم که بهترین کانفیگ PHP-FPM را برای خود بدست آورید.

آنچه گذشت ...

اینکه PHP-FPM دقیقا چیست و چه کمکی به ما می کند و چه تنظیماتی می تواند داشته باشد را در چند مقاله‌ی قبل به صورت کامل توضیح دادیم که اگر خواستید از ابتدای بحث با ما همراه شوید، بهتر است لینک های زیر را دنبال کنید:

و اما درباره ی موضوع این مقاله ...

کشف یک هشدار جدید در لاگ های FPM

ممکن است در حین بررسی لاگ های PHP-FPM به خطا یا هشداری مشابه زیر برخورد کرده باشید:

[26-Mar-2018 10:10:04] WARNING: [pool www] server reached pm.max_children setting (35), consider raising it
[26-Mar-2018 12:04:52] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers)

این خطا یعنی اینکه شما پردازشگرهای کافی برای php-fpm در دسترس ندارید و به احتمال زیاد باید سری به تنظیمات FPM بزنید.

در قسمت بررسی لاگ FPM در مقاله ی قبل دیدیم که چگونه لاگ، از وضعیت سرور و شلوغی و محدودیت هایش به ما خبر می دهد و هر کدام چه معنایی دارد.

دلایل احتمالی زیادی وجود دارد که PHP-FPM شما به max_children برسد:

  • تعداد زیادی بازدید کننده همزمان سایت
  • اجرای آهسته اسکریپت های PHP به دلیل منابع سرور یا اسکریپت های دارای اشکال
  • در نظر گرفتن عدد بسیار پایین برای max_children در کانفیگ  php-fpm

تعیین تعداد صحیح پردازش ها برای  PHP-FPM

بر اساس دیتایی که از لاگ ها به صورت realtime به دست می آید، تعیین تنظیمات مناسب برای پیکربندی php-fpm در سرور شما کار راحت تری است. 

با بررسی لاگ ها و در کنار آن اطلاع داشتن از حافظه و پردازشگر سرور خودمان می توانیم به عدد های دقیق تری از تنظیمات برسیم.

بر اساس مقاله‌ی قبلی کانفیگ های زیر، اصلی ترین مواردی هستند که در فایل etc/php7.3/fpm/pool.d/www.conf/  قرار گرفتند و برای این موضوع باید تنظیم شوند:

pm.max_children = 25 
pm.start_servers = 8 
pm.min_spare_servers = 6 
pm.max_spare_servers = 10

برای یافتن مقادیر صحیح، باید اندازه گیری کنید که یک فرآیند چقدر حافظه مصرف می کند. توجه داشته باشید، این فقط در سروری امکان پذیر است که وب سایت، دارای حافظه پایدار در هر فرآیند باشد، به عبارت دیگر برای یک محیط هاست اشتراکی با وب سایت های مختلف و کدهای توسعه یافته ی متفاوت روی آن، میزان استفاده از حافظه در هر فرآیند به طور جدی دچار نوسان می شود!

خط زیر را با کاربر root در کنسول سرور خود اجرا کنید. خروجی ارزشمندی را به شما می دهد:

ps -ylC php-fpm7.3 --sort:rss

نام php-fpm با نام فرآیند شما مطابقت دارد. ممکن است نام دیگری روی سرور شما داشته باشد که بستگی به PHP مورد استفاده در سرور شما دارد.

در خروجی این دستور، ستون RSS حاوی میانگین مصرف حافظه بر حسب کیلوبایت در هر فرآیند است.

S   UID   PID  PPID  C PRI  NI   RSS    SZ WCHAN  TTY          TIME CMD
S     0 24439     1  0  80   0  6364 57236 -      ?        00:00:00 php-fpm7.3
S    33 24701 24439  2  80   0 61588 63335 -      ?        00:04:07 php-fpm7.3
S    33 25319 24439  2  80   0 61620 63314 -      ?        00:02:35 php-fpm7.3

در این مثال 61588 کیلوبایت یا حدود 60 مگابایت در هر فرآیند استفاده می شود. 

روش دیگر، دریافت میانگین فرآیند php-fpm است که با دستور زیر آن را برای شما محاسبه می کند:

ps --no-headers -o "rss,cmd" -C php-fpm7.3 | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"Mb") }'

مقدار صحیح برای pm.max_children

برای به دست آوردن مقدار صحیح برای تعداد pm.max_children، باید بررسی کنیم که سرور ما چه مقدار حافظه می تواند برای فرآیند php-fpm  استفاده کند و کل آن را بر میانگین اندازه فرآیند تقسیم کنیم.

به عنوان مثال: اگر سرور ما 4 گیگابایت رم دارد و یک سرویس پایگاه داده MariaDB نیز در حال اجرا است که حداقل 1 گیگابایت مصرف می کند و سایر پردازش ها را نیز نیم گیگ در نظر بگیریم، بهترین هدف ما این است که 2.5 گیگابایت یا 2560 مگابایت رم برای کل فرآیند های FPM در نظر بگیریم.

pm.max_children :  2560 Mb / 60 Mb = 42 max_children

مقدار صحیح برای تعداد Spare Children

در بررسی لاگی که در مقاله ی قبل داشتیم اشاره شد که در مواقعی ممکن است سرور به یکباره درگیر و مشغول شود و بخواهد تعداد پردازشگر ها را افزایش دهد و چون ساختن و از بین بردن یک پردازش سربار دارد همیشه تعدادی پردازش آماده ی کار نگه می دارد. 

اگر در لاگ ها با چنین هشداری به مراتب برخوردید، پس بدانید تعداد min و max ها برای spare را باید افزایش دهید:

WARNING: pid 32638, fpm_pctl_perform_idle_server_maintenance(), line 399: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children

درباره ی اینکه این اعداد را چگونه محاسبه کنیم، به موارد مختلفی بستگی دارد که یکی از آنها عدد max_children  می باشد. برای مثال وقتی که max_children را  40 در نظر گرفتیم دیگر تعداد min_spare_servers عدد خیلی کمی نباید باشد. 

یکی از پیشنهادهایی که برای این موضوع شده است این است که عدد این موارد، ضریبی از تعداد هسته های پردازشگر سرور شما باشد.

pm                              dynamic 
pm.max_children                (total RAM - (DB , etc) / process size)
pm.start_servers               (cpu cores * 4)
pm.min_spare_servers           (cpu cores * 2)
pm.max_spare_servers           (cpu cores * 4)

که برای مثال بالایی که زدیم و با تعداد 4 هسته CPU به صورت زیر می شود:

pm                                 dynamic 
pm.max_children                    40
pm.start_servers                   16
pm.min_spare_servers               8
pm.max_spare_servers               16

جمع بندی

با توجه به روش هایی که گفته شد می توانیم به عدد ایده آلی برای تنظیمات PHP-FPM نزدیک شویم ولی در هر صورت از بررسی لاگ FPM غافل نشوید زیرا اطلاعات خوبی از رفتار سرور شما می دهد که می توانید از آنها در بهبود تنظیمات استفاده کنید. 

منابع: 

https://www.kinamo.be/en/support/faq/determining-the-correct-number-of-child-processes-for-php-fpm-on-nginx

https://community.webcore.cloud/tutorials/how_to_solve_php_fpm_server_reached_max_children/

 

از بهترین نوشته‌های کاربران سکان آکادمی در سکان پلاس