چند سال پیش، یکی از مشتریان فروشگاهی می‌گفت سرورش در حالت عادی منابع آزاد دارد اما در روزهای تخفیف، سایت به‌شدت کند می‌شود. بعد از بررسی، مشخص شد که همان سرور، هم وب‌سرور، هم دیتابیس، هم Redis و هم ابزارهای پشتیبان‌گیری را روی یک هسته اجرا می‌کند. در پیک، همه سرویس‌ها به‌طور هم‌زمان منابع می‌خواستند و سرور در همین کشمکش، به دیوار می‌خورد. تجربه‌ام می‌گوید تخصیص منابع سرور (server resource allocation)، پیش از خرید منابع بیشتر، یک تصمیم معماری است: کدام سرویس، چقدر از منابع را در چه زمانی می‌گیرد. در ادامه همان رویکردی را می‌گویم که در پروژه‌های واقعی برای تخصیص منابع استفاده می‌کنم.

پروفایل‌سازی: از کجا شروع کنیم؟

قبل از هر تصمیمی، بدانید سرور شما در ساعات شلوغی، منابع را در کدام سرویس مصرف می‌کند. سه ابزار ضروری:

  • top یا htop: نمای لحظه‌ای از پروسه‌های مصرف‌کننده CPU و RAM.
  • iostat: برای شناسایی گلوگاه I/O دیسک.
  • netstat یا ss: برای دیدن تعداد اتصالات و پورت‌های فعال.

مانیتورینگ تاریخی هم لازم است؛ بدون آن، فقط لحظه‌ای را می‌بینید. ابزارهایی مثل Netdata یا Prometheus + Grafana، تصویر بلندمدت می‌سازند. مفهوم کلی سرور و معماری لایه‌ای‌اش در سرور چیست و چگونه کار می‌کند آمده است.

تخصیص منابع سرور، حدس‌زدن نیست؛ پروفایل‌سازی دقیق، خودش تصمیم را می‌سازد.

تخصیص CPU

CPU، گران‌ترین منبع سرور است و مدیریت درستش، تفاوت محسوسی در عملکرد می‌سازد. سه نکته عملی:

  • محاسبه بار واقعی: Load Average را نسبت به تعداد هسته بسنجید. اگر سرور شما ۴ هسته دارد و Load Average بالای ۴ می‌رود، سرور اشباع است.
  • محدود کردن PHP-FPM: تعداد children را طوری تنظیم کنید که مجموع بار CPU بیش از ظرفیت سرور نرود. تنظیمات دقیق در بهینه‌سازی منابع VPS آمده است.
  • خاموش کردن سرویس‌های بی‌استفاده: هر سرویس روشن، CPU مصرف می‌کند. سرویس‌هایی که در production استفاده نمی‌شوند را غیرفعال کنید.

تخصیص RAM

RAM، منبعی است که اگر کم بیاید، همه چیز به‌طور هم‌زمان کند می‌شود. تخصیص RAM سه قاعده دارد:

  1. بین سرویس‌ها تقسیم کنید، نه انباشته: برای هر سرویس اصلی (PHP، MySQL، Redis، وب‌سرور) سهم مشخصی تعیین کنید و در تنظیمات همان سرویس، سقف بگذارید.
  2. برای سیستم‌عامل و کش سیستم فضای آزاد نگه دارید: حداقل ۱۵ تا ۲۰ درصد RAM سرور را آزاد نگه دارید. اگر RAM کاملاً پر باشد، هسته نمی‌تواند کش‌های داخلی بسازد و همه چیز از دیسک خوانده می‌شود.
  3. swap را جدی بگیرید: swap نه برای استفاده فعال، بلکه برای بقا در برابر لحظات اوج است. اندازه‌اش معمولاً نصف RAM کافی است.

نمونه تخصیص RAM روی سرور ۸ گیگابایتی:

سیستم عامل و کش سیستم:      2 GB
PHP-FPM (مجموع همه children): 1.5 GB
MySQL / MariaDB:             2.5 GB
Redis:                       1 GB
Nginx و سایر سرویس‌ها:        1 GB

تخصیص I/O دیسک

I/O دیسک، پنهان‌ترین گلوگاه سرور است. روی دیسک‌های اشتراکی (SAN یا EBS)، اگر یک سرویس مصرف I/O را بالا ببرد، بقیه سرویس‌ها هم کند می‌شوند. سه اقدام:

  • جدا کردن دیتابیس از فایل‌های استاتیک: اگر ممکن است، دیتابیس روی یک دیسک و فایل‌ها روی دیسک دیگر باشد.
  • استفاده از کش سمت سرور: کش صفحه، فشار خواندن را از دیسک برمی‌دارد.
  • پایش I/O wait: اگر بالای ۲۰٪ است، به‌سراغ شناسایی پروسه‌های پر I/O بروید.

تخصیص پهنای باند و شبکه

پهنای باند، منبعی است که معمولاً تا نزدیکی سقف نمی‌رود، اما در ساعات پیک یا در حمله DDoS می‌تواند مطرح شود. سه نکته:

  • کش CDN: برای فایل‌های استاتیک، CDN را فعال کنید تا پهنای باند سرور اصلی را کم کند. راه‌اندازی در راه‌اندازی CDN برای وردپرس آمده است.
  • محدودیت پهنای باند: اگر سرور شما با پهنای باند محدود کار می‌کند، آستانه هشدار روی مصرف ماهانه تعریف کنید.
  • پایش اتصالات غیرعادی: تعداد بالای اتصالات از یک IP، نشانه حمله یا اسکرپینگ است.

جداسازی سرویس‌ها

یکی از اشتباهات رایج، انباشتن همه سرویس‌ها روی یک سرور است. تجربه من می‌گوید در سایت‌های پرترافیک یا فروشگاهی، جداسازی حداقلی زیر، تفاوت محسوسی می‌سازد:

  • دیتابیس روی سرور جدا یا حداقل روی دیسک جدا.
  • Redis یا Memcached روی سرور جدا در صورت امکان.
  • فایل‌های استاتیک و uploads روی object storage یا CDN.

اگر این جداسازی کامل ممکن نیست، حداقل از Docker یا VM استفاده کنید تا هر سرویس منابعش محدود باشد. مفهوم VM و مجازی‌سازی در تفاوت سرور فیزیکی و مجازی آمده است.

محدودیت‌ها و حفاظت سرور

بدون محدودیت، یک سرویس می‌تواند منابع را از بقیه بگیرد. سه ابزار برای اعمال محدودیت:

  1. systemd cgroups: روی سرورهای مدرن، به‌سادگی می‌توانید برای هر سرویس، محدودیت CPU و RAM تعریف کنید.
  2. ulimit: محدودیت ساده روی تعداد فایل‌های باز، تعداد پروسه‌ها و مقدار حافظه.
  3. سقف در تنظیمات سرویس: مثلاً maxmemory در Redis یا max_connections در MySQL.

هدف از این محدودیت‌ها، حفاظت سرور از فروپاشی ناشی از یک سرویس پرخاشگر است؛ نه محدود کردن بی‌دلیل.

جدول مرجع

منبعروش تخصیصنکته کلیدی
CPUsystemd cgroups یا محدودیت سرویسLoad Average را به تعداد هسته بسنجید
RAMتقسیم بین سرویس‌ها با سقف مشخص۱۵–۲۰٪ RAM را آزاد نگه دارید
I/O دیسکجداسازی دیسک دیتابیس از فایل‌هاI/O wait بالای ۲۰٪ هشدار است
پهنای باندCDN + مانیتور مصرف ماهانهپایش اتصالات غیرعادی
اتصالات شبکهسقف در وب‌سرور و فایروالمحدود کردن per-IP

پرسش‌های کوتاه

آیا تخصیص دستی منابع، برای همه پروژه‌ها لازم است؟ برای سایت‌های اشتراکی و کوچک، پیش‌فرض‌های سرور کافی است. برای VPS و سرور اختصاصی، حداقل تخصیص RAM بین PHP و MySQL لازم است.

چه زمانی باید به پلن بالاتر مهاجرت کنم؟ وقتی بهینه‌سازی‌ها را اعمال کرده‌اید اما در پیک همچنان سرور اشباع می‌شود. تجربه من: قبل از هر ارتقا، حداقل دو هفته پایش دقیق، تا مطمئن شوید مشکل واقعاً کمبود منبع است. معایب پلن کوچک در مزایا و معایب VPS آمده است.

آیا systemd cgroups برای سرورهای کوچک هم قابل استفاده است؟ بله، در توزیع‌های مدرن لینوکس، cgroups به‌طور پیش‌فرض فعال است و می‌توانید برای هر سرویس، محدودیت تعریف کنید.

حرف آخر

تخصیص منابع سرور، پیش از آنکه یک کار فنی باشد، یک تصمیم معماری است. تجربه من می‌گوید سه اقدام اول بیشترین بازده را دارند: پروفایل‌سازی دقیق مصرف در ساعات شلوغی، تعریف سقف RAM برای هر سرویس، و جداسازی حداقلی سرویس‌ها روی سرورهای پرترافیک. اگر امروز فقط همین سه کار را انجام دهید، سرور شما در پیک ترافیک، رفتار قابل‌پیش‌بینی دارد. باقی مسیر، تکرار چرخه پایش و تنظیم است. اگر تجربه‌ای از جداسازی سرویس یا اعمال محدودیت دارید که رفتار سرور را جهش داده، در دیدگاه‌ها بنویسید؛ همان تجربه برای نفر بعدی ارزشمند است. 🖧