وقتی سایت یا نرم افزار سازمانی کند می شود، اولین پیشنهادی که شنیده می شود ارتقای پلن سرور است. گاهی همین کار جواب می دهد، ولی خیلی وقت ها رم و CPU بیشتر مشکل را حل نمی کند و فقط هزینه را بالا می برد. برای افزایش سرعت سرور مجازی اول باید تشخیص داد کدام منبع زیر فشار است و چه چیزی آن را مصرف می کند.
مثال ها برای سرورهای لینوکسی (AlmaLinux و Ubuntu) است. ترتیب مطلب هم همان ترتیبی است که خودمان در بررسی عملکرد جلو می رویم: نشانه ها، منابع سخت افزاری، و آخر سر لایه های نرم افزاری مثل دیتابیس و وب سرور.
علت کند شدن سرور چیست؟
کندی سرور تقریبا همیشه به یکی از این گروه ها برمی گردد و اگر این دسته بندی را در ذهن داشته باشید، کمتر پیش می آید که بی هدف تنظیمات را عوض کنید.
- کمبود CPU، که معمولا از پردازش های سنگین PHP، کوئری های بدون ایندکس، کرون جاب های پرمصرف یا ربات هایی است که صفحات را پشت سر هم باز می کنند.
- کمبود رم. وقتی رم پر شود سیستم عامل سراغ swap می رود و دیسک که چند برابر کندتر از رم است عملا جای حافظه را می گیرد.
- گلوگاه دیسک (IO) به خاطر دیسک کند، دیسک پر یا بکاپی که وسط روز کاری اجرا می شود.
- مشکل میزبان. در سرور مجازی منابع فیزیکی بین چند ماشین تقسیم شده است و اگر میزبان بیش از حد فروخته شده باشد، ماشین شما منتظر CPU یا دیسک می ماند.
- تنظیمات نرم افزار، مثل دیتابیس با تنظیمات پیش فرض، PHP-FPM با تعداد پردازش نامناسب یا نبودن کش.
- شبکه، یعنی فاصله جغرافیایی سرور تا کاربران، فایل های حجیم بدون فشرده سازی یا حمله و ترافیک ناخواسته.
قبل از هر تغییری: کندی را اندازه بگیرید
با جمله «سایت کند است» نمی شود کاری کرد. اول مشخص کنید کدام صفحه، در چه ساعتی و برای چه کسانی کند است. زمان پاسخ اولیه سرور (TTFB) را با یک دستور ساده بسنجید:
curl -o /dev/null -s -w "connect: %{time_connect}s ttfb: %{time_starttransfer}s total: %{time_total}s\n" https://example.com/
اگر اتصال سریع است ولی TTFB بالاست، مشکل در خود سرور و برنامه است. اگر TTFB پایین است ولی صفحه دیر کامل می شود، سراغ حجم فایل ها، تصاویر و کدهای سمت کاربر بروید. همین تفکیک ساده خیلی از دوباره کاری ها را حذف می کند.
بررسی CPU و load average
دستور uptime سه عدد load average را برای یک، پنج و پانزده دقیقه اخیر نشان می دهد. این عدد را با تعداد هسته ها مقایسه کنید که خروجی nproc است. اگر load مدام از تعداد هسته ها بالاتر باشد، پردازش ها در صف مانده اند.
nproc
uptime
top -o %CPU
در خروجی top به ردیف %Cpu(s) دقت کنید:
usبالا یعنی برنامه ها (PHP، دیتابیس، جاوا) CPU را مصرف می کنند.waبالا یعنی CPU بیکار است ولی منتظر دیسک مانده. در این حالت خرید CPU بیشتر فایده ای ندارد.stیا steal time یعنی میزبان مجازی سازی سهم CPU شما را به ماشین دیگری داده است. اگر این عدد به طور پایدار بالا باشد، مشکل از ارائه دهنده سرور است و با تنظیمات داخل سرور حل نمی شود.
وقتی یک پردازش مشخص مقصر است، ببینید چه کسی آن را اجرا کرده. برای سایت ها معمولا ردپای آن در لاگ دسترسی وب سرور پیدا می شود؛ مثلا یک IP یا یک ربات که هزاران درخواست به صفحه جست و جو می فرستد.
# پرتکرارترین IPها در لاگ Nginx
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
بررسی رم و swap
ستون available در دستور free -h مهم تر از free است، چون لینوکس رم خالی را برای کش فایل ها استفاده می کند و این مصرف قابل آزاد شدن است. برای دیدن فعالیت swap از vmstat استفاده کنید:
free -h
vmstat 1 10
journalctl -k | grep -i "out of memory"
اگر ستون های si و so در vmstat به طور مداوم غیر صفر باشند، سرور در حال جابه جایی حافظه با دیسک است و کندی محسوس خواهد بود. پیام out of memory در لاگ کرنل هم یعنی سیستم عامل مجبور شده پردازشی را ببندد؛ اغلب قربانی این اتفاق MySQL یا MariaDB است.
بررسی دیسک و IO
پر شدن دیسک زیاد پیش می آید و زیاد هم از چشم می افتد. هم فضای خالی و هم inode را بررسی کنید، چون هزاران فایل کوچک session یا کش می توانند inodeها را تمام کنند در حالی که فضای خالی باقی است.
df -h
df -i
# AlmaLinux: dnf install sysstat iotop | Ubuntu: apt install sysstat iotop
iostat -x 2 5
iotop -o
در خروجی iostat -x به %util و ستون های r_await و w_await نگاه کنید. استفاده نزدیک به صد درصد همراه با زمان انتظار بالا یعنی دیسک گلوگاه است. iotop نشان می دهد کدام پردازش بیشترین خواندن و نوشتن را دارد.
برای مقایسه کارایی دیسک با آنچه ارائه دهنده وعده داده، می توانید از fio استفاده کنید. این تست یک فایل یک گیگابایتی می سازد و به دیسک فشار می آورد؛ آن را در ساعت کم ترافیک اجرا کنید و فایل را بعدا پاک کنید:
fio --name=randrw --rw=randrw --bs=4k --size=1G --iodepth=32 \
--runtime=60 --time_based --direct=1 --ioengine=libaio --group_reporting
دیتابیس: جایی که بیشتر کندی ها پنهان است
در بسیاری از سایت های وردپرسی و فروشگاهی و نرم افزارهای تحت وب، بخش بزرگی از زمان پاسخ صرف دیتابیس می شود. اول این سه کار را انجام دهید:
1. فعال کردن slow query log
در MariaDB روی AlmaLinux فایل تنظیمات معمولا /etc/my.cnf.d/mariadb-server.cnf است و در MySQL روی Ubuntu فایل /etc/mysql/mysql.conf.d/mysqld.cnf. این خطوط را در بخش [mysqld] اضافه کنید و سرویس را ری استارت کنید:
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
مسیر لاگ باید وجود داشته باشد و کاربر mysql اجازه نوشتن در آن را داشته باشد. بعد از چند ساعت، با mysqldumpslow -s t /var/log/mysql/slow.log | head کندترین کوئری ها را ببینید. اغلب راه حل یک ایندکس درست یا حذف یک افزونه ناکارآمد است.
2. بررسی کوئری های در حال اجرا
mysql -e "SHOW FULL PROCESSLIST;"
اگر ده ها کوئری در وضعیت Locked یا Sending data مانده اند، یک جدول یا یک کوئری کل سیستم را معطل کرده است.
3. اندازه buffer pool
پارامتر innodb_buffer_pool_size تعیین می کند چه مقدار از داده و ایندکس در رم نگهداری شود. مقدار پیش فرض برای سرورهای امروزی کوچک است. روی سروری که فقط دیتابیس دارد می توان سهم زیادی از رم را به آن داد، ولی روی سروری که وب سرور و PHP هم دارد باید برای آنها جا گذاشت. MySQLTuner برای شروع پیشنهادهای خوبی می دهد، به شرطی که سرور مدتی بدون ری استارت کار کرده باشد تا آمار معناداری جمع شده باشد.
وب سرور و PHP-FPM
در سرورهای PHP زیاد پیش می آید که تعداد پردازش های PHP-FPM بدون محاسبه تعیین شده باشد. اگر pm.max_children کم باشد، درخواست ها در صف می مانند. اگر زیاد باشد، رم تمام می شود و سرور به swap می افتد. نشانه حالت اول این پیام در لاگ است:
grep -i "max_children" /var/log/php-fpm/*.log # AlmaLinux
grep -i "max_children" /var/log/php8.3-fpm.log # Ubuntu 24.04
برای محاسبه تقریبی، میانگین مصرف رم هر پردازش را اندازه بگیرید و رم در دسترس برای PHP را بر آن تقسیم کنید:
ps --no-headers -o rss -C php-fpm8.3 | awk '{s+=$1; n++} END {print s/n/1024 " MB"}'
روی AlmaLinux نام پردازش php-fpm است. چند نکته دیگر در این لایه:
- OPcache را فعال نگه دارید (
opcache.enable=1) وopcache.memory_consumptionرا متناسب با حجم کد تنظیم کنید. - نسخه PHP را به نسخه پشتیبانی شده به روز کنید؛ نسخه های قدیمی هم کندترند و هم وصله امنیتی نمی گیرند.
- برای سایت های محتوایی از کش صفحه استفاده کنید تا بیشتر درخواست ها اصلا به PHP و دیتابیس نرسند.
- فشرده سازی gzip یا brotli و HTTP/2 را در Nginx یا LiteSpeed فعال کنید.
- فایل های استاتیک را با هدر کش طولانی سرو کنید و در صورت نیاز از CDN کمک بگیرید.
عوامل خارج از سرور
گاهی سرور سالم است و کندی از جای دیگری می آید. اگر کاربران شما در ایران هستند و سرور در دیتاسنتر خارجی است، تاخیر شبکه بخشی از زمان پاسخ را تشکیل می دهد. با mtr مسیر و تاخیر را از دید کاربر بسنجید. ترافیک ربات ها و اسکنرها هم می تواند منابع را بگیرد؛ محدود کردن نرخ درخواست در وب سرور یا فایروال و بستن مسیرهایی مثل xmlrpc.php در وردپرس، اگر استفاده نمی شوند، کمک می کند. اگر هم مصرف CPU بدون دلیل روشنی بالاست، احتمال آلودگی سرور به ماینر یا بدافزار را کنار نگذارید.
بخشی از کندی از وب سرور و نبودن کش می آید (نصب Nginx روی اوبونتو)، بخشی را CDN برمی دارد (CDN چیست) و برای دیدن روند مصرف منابع در طول زمان، نصب Grafana و Prometheus را ببینید. سرور تازه ای که از همان اول درست تنظیم شده باشد هم کمتر مشکل می دهد (راه اندازی سرور مجازی).
چک لیست افزایش سرعت سرور مجازی
| بخش | چه چیزی را بررسی کنیم | ابزار یا دستور |
|---|---|---|
| اندازه گیری | TTFB صفحات اصلی در ساعات مختلف | curl -w |
| CPU | load در برابر تعداد هسته، مقدار wa و st | uptime، top |
| رم | ستون available، فعالیت swap، پیام OOM | free -h، vmstat، journalctl -k |
| دیسک | فضای خالی، inode، زمان انتظار IO | df -h، df -i، iostat -x |
| دیتابیس | کوئری های کند، قفل ها، buffer pool | slow query log، SHOW PROCESSLIST، MySQLTuner |
| PHP | خطای max_children، OPcache، نسخه PHP | لاگ PHP-FPM، php -v |
| وب سرور | فشرده سازی، HTTP/2، کش فایل های استاتیک | تنظیمات Nginx یا LiteSpeed |
| ترافیک | ربات ها، IPهای پرتکرار، حمله | لاگ دسترسی، awk |
| زمان بندی | بکاپ و کرون جاب های سنگین در ساعت کاری | crontab -l |
کی ارتقای سرور منطقی است؟
ارتقا وقتی تصمیم درستی است که بررسی ها نشان دهد نرم افزار درست تنظیم شده و کوئری های کند رفع شده اند، ولی منابع باز هم در ساعات اوج به سقف می رسند. با steal time بالا یا دیسکی که از حد انتظار کندتر است، رفتن به ارائه دهنده یا پلن دیگری با منابع اختصاصی تر بیشتر از افزودن رم فایده دارد. اگر ترافیک همچنان رشد می کند، قدم بعدی معمولا جدا کردن دیتابیس از وب سرور است.
تغییرات تنظیمات را یکی یکی اعمال کنید و بعد از هر کدام دوباره اندازه بگیرید. اگر چند پارامتر را با هم عوض کنید، معلوم نمی شود کدام اثر داشته و کدام مشکل تازه ساخته است.
بررسی عملکرد سرور توسط تیم ما
منابع و مستندات رسمی
- مستندات رسمی Nginx
- مستندات رسمی PHP درباره تنظیمات PHP FPM
- مستندات رسمی PostgreSQL درباره بهینه سازی کارایی
اگر وقت یا دسترسی لازم برای این بررسی ها را ندارید، می توانید از ارزیابی رایگان سرعت سایت و عملکرد سرور استفاده کنید. این بررسی با دسترسی فقط خواندنی انجام می شود: منابع، دیتابیس و وب سرور را نگاه می کنیم و گزارشی از علت های احتمالی کندی و پیشنهادهای رفعش می فرستیم. هیچ تغییری روی سرور اعمال نمی شود. اگر کندی ناگهانی است و سرویس عملا از دسترس خارج شده، مسیر رفع مشکل دیتابیس و سیستم عامل مناسب تر است. جزئیات بیشتر درباره محدوده بررسی در صفحه ارزیابی عملکرد آمده است.



