راهنمای کامل حل مشکل مصرف بالای منابع در ووکامرس | کشنده سبد خرید
مقدمه: یک داستان واقعی
تصور کنید یک سایت فروشگاهی موفق دارید. همه چیز خوب پیش میرود، فروش دارید، مشتریها راضی هستند. ناگهان یک روز صبح، ایمیلی از شرکت هاستینگ دریافت میکنید:
مصرف شما از حد مجاز عبور کرده است. برای فعالسازی مجدد، با پشتیبانی تماس بگیرید.
شوکه میشوید! مگر چه اتفاقی افتاده؟ آیا هک شدهاید؟ آیا حمله DDoS بوده؟ یا مشکلی در کد سایت وجود دارد؟
در این مقاله، تجربه واقعی خودمان را از مواجهه با این مشکل، نحوه تشخیص، تحلیل و در نهایت حل آن را با شما به اشتراک میگذاریم. در پایان این مقاله، شما:
-
میتوانید مشکل را در سایت خودتان تشخیص دهید -
راهکارهای فوری و عملی برای حل مشکل را یاد میگیرید -
با تنظیمات پیشگیری آشنا میشوید تا دیگر این اتفاق نیفتد -
کدهای آماده برای کپی و استفاده مستقیم دریافت میکنید
علائم مشکل: چگونه تشخیص دهیم؟
قبل از هر چیز، باید بدانید این مشکل چه علائمی دارد. اگر سایت شما یک یا چند مورد از علائم زیر را دارد، احتمالاً با همین مشکل مواجه هستید:
کندی شدید سایت
زمان لود صفحات از ۱۰ ثانیه بیشتر میشود و کاربران نمیتوانند از سایت استفاده کنند.
مصرف بالای پهنای باند
مصرف پهنای باند بهطور غیرعادی بالا رفته و از حد مجاز عبور میکند.
CPU در ۱۰۰٪
Load Average سرور به شدت بالا رفته و PHP-FPM processes در ۱۰۰٪ CPU گیر کردهاند.
ترافیک غیرعادی روی /cart/
آمار نشان میدهد بیشترین بازدید از صفحه سبد خرید است، نه صفحه اصلی یا محصولات!
خطاهای ۵۰۳ و ۵۰۰
کاربران با خطاهای Service Unavailable یا Internal Server Error مواجه میشوند.
ساسپند شدن سایت
شرکت هاستینگ به دلیل مصرف بالای منابع، سایت را معلق میکند.
آمار واقعی یک فاجعه: اعداد چه میگویند؟
بیایید آمار واقعی سایتی که با این مشکل مواجه شد را بررسی کنیم. این آمار از Webalizer (آمارگیر cPanel) استخراج شده و نشاندهنده عمق فاجعه است:
| شاخص | مقدار | درصد از کل | تفسیر |
|---|---|---|---|
| بازدید صفحه /cart/ | ۱,۱۳۸,۴۷۷ | ۶۴.۱۸٪ | بیشترین بازدید! |
| پهنای باند مصرفی /cart/ | ۱۰۲ گیگابایت | ۸۷.۵٪ | عامل اصلی ساسپند |
| بازدید صفحه /checkout/ | ۸۵,۹۴۳ | ۴.۸۵٪ | دومین صفحه پربازدید |
| بازدید صفحه اصلی | ۱,۴۰۴ | ۰.۰۸٪ | ناچیز در مقایسه! |
| کل پهنای باند (۶ روز) | ۱۱۷ گیگابایت | – | فراتر از حد مجاز |
در یک سایت طبیعی، صفحه اصلی و صفحات محصولات باید بیشترین بازدید را داشته باشند. وقتی صفحه سبد خرید ۶۴٪ ترافیک را مصرف میکند، یعنی مشکلی جدی وجود دارد!
علت اصلی: WooCommerce Cart Fragments چیست؟
تعریف ساده
Cart Fragments یک قابلیت AJAX در ووکامرس است که بهصورت خودکار محتوای سبد خرید را در هدر سایت بهروزرسانی میکند. مثلاً وقتی کاربر محصولی به سبد اضافه میکند، بدون نیاز به رفرش صفحه، تعداد محصولات در آیکون سبد خرید بهروز میشود.
نحوه عملکرد Cart Fragments
لود صفحه
کاربر هر صفحهای از سایت را باز میکند
درخواست AJAX
اسکریپت wc-cart-fragments.js یک درخواست AJAX به سرور میفرستد
پردازش PHP
سرور باید کل صفحه سبد خرید را پردازش کند تا تعداد محصولات را برگرداند
تکرار برای هر بازدیدکننده
این فرآیند برای هر بازدیدکننده و در هر صفحه تکرار میشود!
چرا این مشکلساز میشود؟
عدم کشپذیری
صفحه /cart/ و /checkout/ به دلیل ماهیت پویا (وابسته به session کاربر) نمیتوانند کش شوند. هر درخواست = پردازش کامل PHP + دیتابیس.
خزش رباتها
رباتهای گوگل، متا، Ahrefs و سایر خزندهها هم صفحه /cart/ را crawl میکنند و هر بار یک درخواست کامل PHP تولید میکنند.
Polling مکرر
برخی قالبها و افزونهها هر چند ثانیه یکبار سبد خرید را رفرش میکنند تا تعداد محصولات را بهروز نگه دارند.
CDN و IP یکسان
وقتی از CDN استفاده میکنید، تمام ترافیک از IPهای CDN دیده میشود و ممکن است در آمار، به اشتباه به عنوان یک IP واحد نمایش داده شود.
در سرور ما، ۷ پروسه PHP-FPM هر کدام در ۱۰۰٪ CPU گیر کرده بودند و Load Average به ۱۴.۹۵ رسیده بود! این یعنی سرور در آستانه کرش کامل بود.
راهکارهای فوری: نجات سایت در ۵ دقیقه
غیرفعال کردن Cart Fragments (حیاتیترین کار!)
این کد را در فایل functions.php قالب خود اضافه کنید:
/**
* غیرفعال کردن WooCommerce Cart Fragments
* این قابلیت باعث تولید هزاران ریکوئست غیرضروری میشود
*/
add_action('wp_enqueue_scripts', 'disable_wc_cart_fragments', 99);
function disable_wc_cart_fragments() {
// حذف اسکریپت cart-fragments
wp_dequeue_script('wc-cart-fragments');
// حذف استایلهای غیرضروری بلوکهای ووکامرس
wp_dequeue_style('wc-blocks-style');
}
/**
* غیرفعال کردن AJAX سبد خرید در صفحات غیرضروری
*/
add_action('wp_footer', 'remove_cart_ajax_on_non_shop');
function remove_cart_ajax_on_non_shop() {
if (!is_woocommerce() && !is_cart() && !is_checkout() && !is_product()) {
wp_dequeue_script('wc-cart');
wp_dequeue_script('wc-add-to-cart');
}
}
/**
* حذف کامل cart fragments از صف اسکریپتها
*/
add_action('wp_print_scripts', 'remove_cart_fragments_completely', 9999);
function remove_cart_fragments_completely() {
global $wp_scripts;
if (isset($wp_scripts->registered['wc-cart-fragments'])) {
unset($wp_scripts->registered['wc-cart-fragments']);
}
}
با این کد، حدود ۹۰٪ ترافیک غیرضروری حذف میشود و CPU سرور به شدت کاهش مییابد.
محدود کردن رباتها با robots.txt
فایل robots.txt را در ریشه سایت ایجاد یا ویرایش کنید:
User-agent: *
Disallow: /cart/
Disallow: /checkout/
Disallow: /my-account/
Disallow: /wp-admin/
Disallow: /wp-json/
Disallow: /?s=
Disallow: /*?add-to-cart=
Disallow: /*?*add-to-cart=
# اجازه به موتورهای اصلی
User-agent: Googlebot
Allow: /
User-agent: Bingbot
Allow: /
# بلاک رباتهای سنگین
User-agent: meta-externalagent
Disallow: /
User-agent: AhrefsBot
Disallow: /
User-agent: SemrushBot
Disallow: /
User-agent: MJ12bot
Disallow: /
Sitemap: https://example.com/sitemap_index.xml
Rate Limiting در .htaccess
# غیرفعال کردن XML-RPC (درگاه حمله)
<Files xmlrpc.php>
order deny,allow
deny from all
</Files>
# بلاک رباتهای مشکوک از صفحات حساس
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} "(meta-externalagent|AhrefsBot|SemrushBot|MJ12bot)" [NC]
RewriteCond %{REQUEST_URI} ^/(cart|checkout|my-account) [NC]
RewriteRule .* - [F,L]
</IfModule>
# کش فایلهای استاتیک
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
</IfModule>
Restart فوری PHP-FPM
اگر به SSH دسترسی دارید، این دستور را اجرا کنید:
# Restart PHP-FPM
systemctl restart php84-fpm
# یا در DirectAdmin:
service php-fpm-84 restart
# بررسی وضعیت بعد از restart
systemctl status php84-fpm
راهکارهای بلندمدت: بهینهسازی حرفهای
سبد خرید Lazy Load
به جای لود خودکار سبد خرید در هر صفحه، آن را فقط با کلیک کاربر لود کنید:
/**
* لود سبد خرید فقط با تعامل کاربر
*/
add_action('wp_footer', 'lazy_cart_loading');
function lazy_cart_loading() {
if (!is_cart() && !is_checkout()) {
?>
<script>
document.addEventListener('DOMContentLoaded', function() {
var cartElements = document.querySelectorAll('.cart-icon, .mini-cart, .header-cart');
var cartLoaded = false;
cartElements.forEach(function(element) {
element.addEventListener('mouseenter', loadCart);
element.addEventListener('click', loadCart);
});
function loadCart() {
if (cartLoaded) return;
cartLoaded = true;
// فراخوانی AJAX ووکامرس فقط وقتی لازم است
fetch(wc_cart_fragments_params.wc_ajax_url.replace('%%endpoint%%', 'get_refreshed_fragments'), {
method: 'POST',
credentials: 'same-origin'
})
.then(response => response.json())
.then(data => {
// آپدیت UI سبد خرید
if (data.fragments) {
Object.keys(data.fragments).forEach(function(selector) {
var elements = document.querySelectorAll(selector);
elements.forEach(function(el) {
el.innerHTML = data.fragments[selector];
});
});
}
})
.catch(error => console.log('Cart load error:', error));
}
});
</script>
<?php
}
}
کش تعداد سبد خرید با Transient
/**
* کش کردن تعداد اقلام سبد خرید
*/
add_filter('woocommerce_add_to_cart_fragments', 'cached_cart_fragments');
function cached_cart_fragments($fragments) {
$cache_key = 'cart_count_' . get_current_user_id();
$cart_count = get_transient($cache_key);
if ($cart_count === false) {
$cart_count = WC()->cart ? WC()->cart->get_cart_contents_count() : 0;
set_transient($cache_key, $cart_count, 300); // کش ۵ دقیقهای
}
$fragments['span.cart-count'] = '<span class="cart-count">' . $cart_count . '</span>';
return $fragments;
}
/**
* پاک کردن کش هنگام تغییر سبد خرید
*/
function clear_cart_transient() {
$cache_key = 'cart_count_' . get_current_user_id();
delete_transient($cache_key);
}
add_action('woocommerce_add_to_cart', 'clear_cart_transient');
add_action('woocommerce_cart_item_removed', 'clear_cart_transient');
add_action('woocommerce_cart_item_updated', 'clear_cart_transient');
add_action('woocommerce_cart_emptied', 'clear_cart_transient');
بهینهسازی PHP-FPM
تنظیمات PHP-FPM را برای سایتهای پربازدید بهینه کنید:
; در فایل /usr/local/php84/etc/php-fpm.d/your-site.conf
pm = dynamic
pm.max_children = 50
pm.start_servers = 15
pm.min_spare_servers = 10
pm.max_spare_servers = 25
pm.max_requests = 1000
pm.process_idle_timeout = 10s
; جلوگیری از پروسههای گیر کرده
request_terminate_timeout = 30s
request_slowlog_timeout = 10s
slowlog = /var/log/php-fpm/your-site-slow.log
; محدودیت منابع
php_admin_value[memory_limit] = 256M
php_admin_value[max_execution_time] = 30
مقادیر بالا برای سرور با ۱۶ گیگابایت RAM مناسب است. اگر سرور کوچکتری دارید، مقادیر را کاهش دهید.
تنظیمات CDN: Arvan Cloud و Cloudflare
اگر از CDN استفاده میکنید، این تنظیمات را حتماً اعمال کنید:
تنظیمات Arvan Cloud
| تنظیم | مسیر | مقدار |
|---|---|---|
| Bot Management | CDN → Security → Bot Management | فعال (Aggressive) |
| Rate Limiting | CDN → Security → Rate Limiting | 30 req/min برای /cart/ |
| Cache Static Files | CDN → Cache → Rules | TTL: 30 days |
| Bypass Cart/Checkout | CDN → Cache → Rules | Bypass Cache |
| DDoS Protection | CDN → Security → DDoS | فعال |
تنظیمات Cloudflare (جایگزین)
# Rule 1: Block Bot Scraping
(if http.user_agent contains "meta-externalagent" or "AhrefsBot")
→ Challenge
# Rule 2: Rate Limit Cart
(if http.request.uri.path contains "/cart")
→ Rate Limit: 30 requests/minute
# Rule 3: Block xmlrpc
(if http.request.uri.path contains "xmlrpc.php")
→ Block
# Rule 4: Cache Static Assets
(if http.request.uri.path ends with ".css" or ".js" or ".png")
→ Cache: 30 days
مانیتورینگ دائمی: اسکریپت هشدار خودکار
این اسکریپت را روی سرور قرار دهید تا در صورت بالا رفتن Load، به صورت خودکار هشدار دریافت کنید:
#!/bin/bash
# /root/monitor-woocommerce.sh
# اسکریپت مانیتورینگ لود سرور
LOAD=$(awk '{print $1}' /proc/loadavg)
THRESHOLD=8
ADMIN_EMAIL="admin@example.com"
TELEGRAM_BOT_TOKEN="YOUR_BOT_TOKEN"
TELEGRAM_CHAT_ID="YOUR_CHAT_ID"
if (( $(echo "$LOAD > $THRESHOLD" | bc -l) )); then
# ارسال ایمیل هشدار
echo "⚠️ Load High: $LOAD - Server may crash soon!" | \
mail -s "Alert: High Load Detected" $ADMIN_EMAIL
# ارسال نوتیفیکیشن تلگرام
curl -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
-d "chat_id=$TELEGRAM_CHAT_ID" \
-d "text=🚨 Load High: $LOAD
Site: example.com
Action: Restarting PHP-FPM"
# Restart خودکار PHP-FPM
systemctl restart php84-fpm
# لاگ کردن رخداد
echo "$(date): Load $LOAD - PHP-FPM restarted" >> /var/log/load-monitor.log
fi
سپس آن را به crontab اضافه کنید تا هر ۵ دقیقه اجرا شود:
# ویرایش crontab
crontab -e
# اضافه کردن این خط (اجرا هر ۵ دقیقه)
*/5 * * * * /root/monitor-woocommerce.sh
# ذخیره و خروج
افزونههای مانیتورینگ پیشنهادی
Wordfence
مانیتورینگ real-time، اسکن امنیتی، فایروال
Jetpack
آمار ترافیک، مانیتورینگ دسترسی، بکاپ
UptimeRobot
مانیتورینگ دسترسی سایت، هشدار در صورت قطعی
چکلیست نهایی: اقدامات به ترتیب اولویت
فوری (همین الان – ۵ دقیقه)
-
غیرفعال کردن Cart Fragments (کد بخش ۱) -
ایجاد/ویرایش robots.txt (کد بخش ۲) -
غیرفعال کردن XML-RPC در .htaccess -
Restart PHP-FPM از طریق SSH یا پنل هاستینگ
امروز (۳۰ دقیقه)
-
تنظیمات PHP-FPM (کد بخش ۷) -
تنظیمات CDN (Arvan/Cloudflare) -
بررسی لاگهای خطا:/var/log/apache2/error.log
هفته اول
-
نصب افزونه کش (WP Rocket یا FlyingPress) -
فعالسازی Object Cache (Redis/Memcached) -
راهاندازی اسکریپت مانیتورینگ (بخش ۸) -
نصب Wordfence یا Sucuri برای امنیت
نتایج: قبل و بعد از بهینهسازی
| شاخص | قبل از بهینهسازی | بعد از بهینهسازی | بهبود |
|---|---|---|---|
| Load Average | 14.95 | < 2.5 | ✅ ۸۳٪ |
| CPU Usage | 100% | 20-30% | ✅ ۷۰٪ |
| ریکوئستهای /cart/ | ۱,۱۳۸,۴۷۷ | ~۵۰,۰۰۰ | ✅ ۹۵٪ |
| پهنای باند روزانه | ۱۹.۶ GB | ~۲.۵ GB | ✅ ۸۷٪ |
| سرعت لود صفحه اصلی | ۱۲ ثانیه | ۱.۸ ثانیه | ✅ ۶.۷ برابر سریعتر |
| وضعیت سایت | 🔴 ساسپند | 🟢 فعال و پایدار | ✅ نجات یافت! |
سوالات متداول
جمعبندی: درسهایی که گرفتیم
این تجربه به ما چند درس مهم داد:
همیشه مانیتورینگ داشته باشید. اگر سیستم هشدار زودرس داشتیم، قبل از ساسپند شدن متوجه مشکل میشدیم.
آمار ترافیک را منظم بررسی کنید. وقتی صفحه /cart/ بیشترین بازدید را دارد، یعنی مشکلی وجود دارد.
قابلیتهای پیشفرض همیشه بهینه نیستند. Cart Fragments برای سایتهای کوچک عالی است، اما برای سایتهای پربازدید مشکلساز میشود.
CDN معجزه نمیکند، تنظیمات میخواهد. بدون تنظیمات درست Rate Limiting و Bot Management، CDN هم نمیتواند کمک کند.
امیدواریم این مقاله به شما کمک کند تا از این مشکل پیشگیری کنید یا در صورت بروز، سریعتر آن را حل کنید. 🚀