الموقع بطيء أو السيرفر تحت حمل مرتفع: كيف تعرف السبب
لمعرفة سبب بطء الموقع، ابدأ بقياس الوقت حتى وصول أول بايت (TTFB). إذا كان TTFB مرتفعًا (أكثر من ثانية بفارق واضح)، فالسيرفر يستغرق وقتًا طويلًا في توليد الصفحة. في هذه الحالة افحص حدود الموارد، وحمل السيرفر، واستعلامات قاعدة البيانات البطيئة، وعمليات PHP العاملة (workers)، وترافيك البوتات. أما إذا كان TTFB سريعًا والصفحة ما زالت بطيئة في التحميل، فالمشكلة في ثقل الواجهة الأمامية: صور كبيرة، أو سكربتات كثيرة، أو غياب التخزين المؤقت للصفحات. يغطي هذا الدليل الحالتين على الاستضافة المشتركة بلوحة cPanel من Cloudesta، وعلى VPS سحابي أو سيرفر مخصص يعمل بنظام Ubuntu 24.04 (الأوامر تعمل أيضًا على 22.04).
المتطلبات
- رابط URL للصفحة البطيئة، مثل
https://example.com/. - الاستضافة المشتركة: بيانات الدخول إلى cPanel.
- VPS أو سيرفر مخصص: وصول عبر SSH بحساب root أو مستخدم لديه صلاحيات sudo، وبيانات دخول root لـ MySQL/MariaDB.
- لفحص قاعدة بيانات WordPress: phpMyAdmin (في cPanel) أو WP-CLI (على VPS).
1. كيف أقيس مدى بطء موقعي فعليًا؟
اختبر الصفحة باستخدام PageSpeed Insights أو GTmetrix، وسجّل قيمة TTFB والحجم الإجمالي للصفحة وعدد الطلبات. بعد ذلك قِس TTFB بنفسك من الطرفية، حتى تتمكن من تكرار الاختبار بعد كل تغيير:
curl -o /dev/null -s -w 'TTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n' https://example.com/
شغّل الأمر ثلاث أو أربع مرات. الطلب الأول يكون غالبًا أبطأ لأن الذاكرة المؤقتة تكون فارغة. دوّن الأرقام لتكون لديك قيم مرجعية تقارن بها لاحقًا.
2. هل المشكلة في السيرفر أم في الصفحة نفسها؟
- TTFB أقل من 0.8 ثانية تقريبًا، لكن تحميل الصفحة يستغرق عدة ثوانٍ: المشكلة في ثقل الواجهة الأمامية. راجع مخطط الشلال (waterfall) في GTmetrix وابحث عن الصور الكبيرة، والسكربتات الكثيرة من أطراف خارجية، وملفات CSS/JS التي تعطّل عرض الصفحة. اضغط الصور، وحوّلها إلى صيغة WebP، وفعّل التحميل الكسول (lazy-load) لها، واحذف الإضافات أو العناصر المضمّنة غير المستخدمة.
- TTFB أعلى من 1–2 ثانية: السيرفر بطيء في بناء الصفحة. انتقل إلى القسم 3 (الاستضافة المشتركة) أو إلى القسم 4 وما بعده (VPS).
- TTFB سريع للملفات الثابتة لكنه بطيء لصفحات PHP: السبب هو PHP أو قاعدة البيانات أو غياب التخزين المؤقت للصفحات.
3. كيف أعرف السبب على الاستضافة المشتركة بلوحة cPanel؟
افحص حدود الموارد في CloudLinux
انتقل إلى cPanel » Metrics » Resource Usage. إذا وصل الحساب إلى حدود المعالج (CPU) أو الذاكرة الفعلية (PMEM) أو العمليات الداخلة (EP) أو عمليات القراءة والكتابة (IO)، فإن CloudLinux يُبطئه، وتظهر هذه التجاوزات هنا مع توقيتاتها. قارن هذه التوقيتات بالأوقات التي أبلغ فيها الزوار عن البطء. تجاوزات EP تعني عادةً وجود عدد كبير جدًا من طلبات PHP المتزامنة غير المخزّنة مؤقتًا، وغالبًا ما تسببها البوتات.
ابحث عن ترافيك البوتات في AWStats
افتح cPanel » Metrics » Awstats وراجع جدولي "Robots/Spiders visitors" و"Hosts". من الأسباب الشائعة لتجاوز حدود الموارد أن يرسل زاحف واحد أو عنوان IP واحد عشرات الآلاف من الطلبات.
فعّل LiteSpeed Cache وحسّن الصور
تعمل سيرفرات الاستضافة المشتركة في Cloudesta بخادم LiteSpeed، لذلك ثبّت على WordPress إضافة LiteSpeed Cache المجانية وفعّل التخزين المؤقت للصفحات. تُقدَّم الصفحات المخزّنة مؤقتًا دون تشغيل PHP، فينخفض TTFB واستهلاك المعالج معًا. ومن الإضافة نفسها، استخدم خاصية Image Optimization لإنشاء نسخ WebP من صورك. افتح أيضًا cPanel » Software » Select PHP Version وتأكد من تحديد إضافة opcache.
4. كيف أعرف إن كان الـ VPS تحت حمل مرتفع؟
uptime
nproc
يعرض uptime متوسط الحمل خلال 1 و5 و15 دقيقة. قارن هذا المتوسط بعدد الأنوية الذي يعرضه nproc. حمل 3.5 على سيرفر بأربع أنوية يعني أنه مشغول لكن الوضع سليم، أما حمل مستمر قدره 12 على أربع أنوية فيعني أن المهام تتراكم في الانتظار. بعد ذلك حدّد العمليات المسؤولة:
sudo apt update && sudo apt install -y htop
htop
رتّب العمليات حسب المعالج (F6) أو حسب الذاكرة. وفي top العادي، اضغط P أو M للترتيب، و1 لعرض الاستخدام لكل نواة. ارتفاع قيمة wa (iowait) يدل على بطء الوصول إلى القرص، وسببه عادةً قاعدة البيانات. والاستخدام الكثيف لمساحة swap يعني أن الذاكرة RAM غير كافية. وإذا ظهرت عمليات php-fpm أو mysqld كثيرة في أعلى القائمة، فهذا يحدد لك أي القسمين التاليين تقرأ أولًا.
5. كيف أعثر على استعلامات MySQL البطيئة؟
فعّل سجل الاستعلامات البطيئة أثناء التشغيل. تظل هذه الإعدادات سارية حتى إعادة التشغيل التالية:
sudo mysql -e "SET GLOBAL slow_query_log_file='/var/log/mysql/mysql-slow.log'; SET GLOBAL long_query_time=1; SET GLOBAL slow_query_log=1;"
اترك الموقع يعمل لمدة ساعة، ثم لخّص السجل مرتّبًا حسب إجمالي الوقت المستغرق:
sudo mysqldumpslow -s t /var/log/mysql/mysql-slow.log | head -30
لجعل الإعداد دائمًا، أضف slow_query_log = 1 وlong_query_time = 1 ومسار ملف السجل تحت قسم [mysqld]. الملف هو /etc/mysql/mysql.conf.d/mysqld.cnf في MySQL، أو /etc/mysql/mariadb.conf.d/50-server.cnf في MariaDB. بعد ذلك احصل على اقتراحات لضبط أحجام الذاكرة المؤقتة (buffers):
sudo apt install -y mysqltuner
sudo mysqltuner
6. هل نفدت عمليات PHP-FPM العاملة؟
إصدار PHP هو 8.3 على Ubuntu 24.04 و8.1 على 22.04، فعدّل المسارات التالية بما يناسب إصدارك. افحص السجل أولًا:
sudo grep -i "max_children" /var/log/php8.3-fpm.log
إذا ظهرت لك رسالة "server reached pm.max_children"، فهذا يعني أن الطلبات تنتظر توفر عملية عاملة شاغرة. وللاطلاع على الأرقام بشكل مباشر، أزل علامة التعليق عن السطر pm.status_path = /status في الملف /etc/php/8.3/fpm/pool.d/www.conf، وأضف الكتلة التالية داخل كتلة server { } في إعدادات Nginx:
location = /status {
allow 127.0.0.1;
deny all;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
sudo nginx -t && sudo systemctl reload nginx php8.3-fpm
curl -H "Host: example.com" http://127.0.0.1/status
راجع قيم "active processes" و"listen queue" و"max children reached". لا ترفع قيمة pm.max_children إلا إذا توفرت ذاكرة RAM حرة، إذ تستهلك كل عملية عاملة عادةً من 40 إلى 100 MB. وإذا كانت الذاكرة محدودة، فعالج التخزين المؤقت والبوتات أولًا.
7. كيف أكتشف البوتات في سجل الوصول؟
استخدم /var/log/nginx/access.log مع Nginx أو /var/log/apache2/access.log مع Apache. تعرض الأوامر التالية أكثر عناوين IP ووكلاء المستخدم (user agents) وروابط URL تكرارًا:
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
sudo awk -F'"' '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
sudo awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
الطلبات المتكررة على /wp-login.php أو /xmlrpc.php تشير إلى محاولات تخمين كلمات المرور (brute-force). وآلاف الطلبات من زواحف تحسين محركات البحث (SEO) تشير إلى فهرسة مفرطة. لإبطاء الزواحف الملتزمة بالقواعد، أضف قواعد مثل التالية إلى robots.txt:
User-agent: AhrefsBot
Crawl-delay: 10
User-agent: MJ12bot
Disallow: /
البوتات المسيئة تتجاهل robots.txt، لذا احظرها بقاعدة جدار ناري أو استخدم fail2ban:
sudo ufw deny from 203.0.113.10
sudo apt install -y fail2ban
printf '[nginx-botsearch]\nenabled = true\n' | sudo tee /etc/fail2ban/jail.d/nginx-botsearch.local
sudo systemctl restart fail2ban
8. كيف أفعّل OPcache والتخزين المؤقت للكائنات؟
يكون OPcache مفعّلًا افتراضيًا في الغالب على Ubuntu. اضبط إعداداته في الملف /etc/php/8.3/fpm/conf.d/10-opcache.ini:
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
لإضافة Redis كذاكرة تخزين مؤقت للكائنات، تحتفظ بنتائج استعلامات قاعدة البيانات المتكررة في الذاكرة، نفّذ:
sudo apt install -y redis-server php8.3-redis
sudo systemctl restart php8.3-fpm
بعد ذلك ثبّت إضافة "Redis Object Cache" في WordPress، ثم اضغط Enable Object Cache.
9. هل تضخم قاعدة البيانات يُبطئ WordPress؟
يحمّل WordPress جميع الصفوف المحمّلة تلقائيًا (autoload) في جدول wp_options مع كل طلب. نفّذ الاستعلامات التالية في phpMyAdmin أو mysql، مع تعديل بادئة الجداول إذا لم تكن wp_:
SELECT ROUND(SUM(LENGTH(option_value))/1024) AS autoload_kb
FROM wp_options WHERE autoload IN ('yes','on','auto-on','auto');
SELECT option_name, LENGTH(option_value) AS bytes
FROM wp_options WHERE autoload IN ('yes','on','auto-on','auto')
ORDER BY bytes DESC LIMIT 20;
إذا تجاوزت البيانات المحمّلة تلقائيًا 1 MB تقريبًا فهذه مشكلة، والإدخالات الكبيرة تعود عادةً إلى إضافات سبق أن حذفتها. لمسح البيانات المؤقتة (transients) منتهية الصلاحية، نفّذ الأمر التالي من مجلد الموقع:
wp transient delete --expired
wp_options. وعلى الاستضافة المشتركة، يمكنك أيضًا الاستعادة من JetBackup إذا حدث خطأ ما.10. متى يكون الترافيك ببساطة أكبر من قدرة باقتي؟
قد تكون فعّلت التخزين المؤقت وحظرت البوتات وأصلحت الاستعلامات البطيئة، ومع ذلك يظل المعالج أو عدد العمليات الداخلة عند الحد الأقصى في أوقات ترافيك الزوار العادي. في هذه الحالة يكون الموقع قد تجاوز قدرة باقته. يمكن نقل حسابات الاستضافة المشتركة إلى باقة استضافة مشتركة أكبر، أما التطبيقات المزدحمة أو المخصصة فالأنسب لها VPS سحابي بموارد مخصصة. يتولى فريق Cloudesta ترقية الباقات، لذا افتح تذكرة دعم لطلب الترقية.
التحقق من النتيجة
- أعد تشغيل اختبار TTFB باستخدام
curlوقارن النتيجة بالقيم المرجعية. - أعد الاختبار في PageSpeed Insights أو GTmetrix.
- على VPS، تأكد من أن متوسط الحمل في
uptimeيظل أقل من قيمةnprocفي أوقات الذروة. - على الاستضافة المشتركة، تأكد من عدم ظهور تجاوزات جديدة في Resource Usage.
مشكلات شائعة
- الموقع يعرض الخطأ "508 Resource Limit Reached" على الاستضافة المشتركة: نفدت العمليات الداخلة (EP). فعّل LiteSpeed Cache واحظر البوتات التي ظهرت لك في AWStats.
- الحمل مرتفع لكن المعالج خامل في أغلب الوقت: السيرفر ينتظر القرص (iowait) أو يستخدم swap. افحص الاستعلامات البطيئة واستهلاك الذاكرة.
- الصفحات تعرض الخطأ 502 أو 504 تحت الحمل: وصل PHP-FPM إلى حد
pm.max_children. أضف التخزين المؤقت، أو ارفع الحد إذا سمحت ذاكرة RAM بذلك. - Redis مثبّت لكن لم يتغير شيء: لم تتم إعادة تشغيل PHP-FPM، أو لم يتم تفعيل إضافة التخزين المؤقت للكائنات في WordPress.
- الموقع بطيء فقط للمستخدمين المسجّلين دخولهم: يتم تجاوز التخزين المؤقت للصفحات في الجلسات المسجّلة. أضف تخزينًا مؤقتًا للكائنات وقلّل عدد إضافات لوحة الإدارة.
الأسئلة الشائعة
ما قيمة TTFB الجيدة؟
تُعد القيمة الأقل من 0.8 ثانية جيدة بوجه عام. وغالبًا ما يكون TTFB للصفحة المخزّنة مؤقتًا على LiteSpeed أو Nginx أقل من 0.2 ثانية.
ما متوسط الحمل الذي يُعد مرتفعًا أكثر من اللازم؟
إذا ظل الحمل أعلى من عدد أنوية المعالج لمدة 5 إلى 15 دقيقة، فهذا يعني أن العمليات تتراكم في الانتظار. أما الارتفاعات القصيرة فهي أمر طبيعي.
هل يضر حظر البوتات بترتيب موقعي في محركات البحث (SEO)؟
لا، ما دمت لم تحظر Googlebot وBingbot. حظر زواحف الأطراف الخارجية المفرطة وترافيك الهجمات لا يؤثر على ترتيب الموقع في محركات البحث.
تحتاج إلى مساعدة؟ إذا لم تتمكن من تحديد السبب، أو كنت تحتاج إلى ترقية باقتك، افتح تذكرة دعم واذكر فيها نطاقك، والأوقات التي حدث فيها البطء، ومخرجات الفحوصات السابقة.