راهنما

راهنمای کامل حل مشکل مصرف بالای منابع در ووکامرس | کشنده سبد خرید




مقدمه: یک داستان واقعی

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

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

شوکه می‌شوید! مگر چه اتفاقی افتاده؟ آیا هک شده‌اید؟ آیا حمله 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 ✅ ۸۷٪
سرعت لود صفحه اصلی ۱۲ ثانیه ۱.۸ ثانیه ✅ ۶.۷ برابر سریع‌تر
وضعیت سایت 🔴 ساسپند 🟢 فعال و پایدار ✅ نجات یافت!




سوالات متداول

خیر، سبد خرید همچنان کار می‌کند. فقط به‌روزرسانی خودکار تعداد محصولات در هدر بدون رفرش صفحه غیرفعال می‌شود. کاربر با کلیک روی سبد خرید یا رفرش صفحه، تعداد به‌روز را می‌بیند. این یک trade-off بین UX و عملکرد سرور است که برای سایت‌های پربازدید ارزشمند است.

وقتی از CDN استفاده می‌کنید، تمام ترافیک از سرورهای CDN عبور می‌کند. Webalizer نمی‌تواند IP واقعی کاربر را از هدرهای CDN استخراج کند، بنابراین تمام ترافیک از IPهای CDN نمایش داده می‌شود. برای آمار دقیق، از Google Analytics یا Matomo استفاده کنید.

خیر، هر سیستم فروشگاهی که سبد خرید پویا دارد (مثل PrestaShop، OpenCart، Magento) ممکن است با مشکل مشابه مواجه شود. راهکارهای مشابه (غیرفعال کردن AJAX polling، کش، Rate Limiting) قابل اعمال هستند.

با اعمال راهکارهای فوری (بخش ۴)، ظرف ۱۰-۱۵ دقیقه Load سرور کاهش می‌یابد. برای پایداری کامل و بهینه‌سازی بلندمدت، حدود ۱ هفته زمان نیاز است تا تمام تنظیمات اعمال و تست شوند.

برای راهکارهای فوری، نیازی به نصب افزونه نیست و کدها مستقیماً در functions.php کار می‌کنند. برای بهینه‌سازی بلندمدت، افزونه‌های کش مثل WP Rocket یا FlyingPress و Redis Object Cache پیشنهاد می‌شوند.


جمع‌بندی: درس‌هایی که گرفتیم

این تجربه به ما چند درس مهم داد:

۱

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

۲

آمار ترافیک را منظم بررسی کنید. وقتی صفحه /cart/ بیشترین بازدید را دارد، یعنی مشکلی وجود دارد.

۳

قابلیت‌های پیش‌فرض همیشه بهینه نیستند. Cart Fragments برای سایت‌های کوچک عالی است، اما برای سایت‌های پربازدید مشکل‌ساز می‌شود.

۴

CDN معجزه نمی‌کند، تنظیمات می‌خواهد. بدون تنظیمات درست Rate Limiting و Bot Management، CDN هم نمی‌تواند کمک کند.

امیدواریم این مقاله به شما کمک کند تا از این مشکل پیشگیری کنید یا در صورت بروز، سریع‌تر آن را حل کنید. 🚀

این مقاله مفید بود؟

با اشتراک‌گذاری آن، به دیگران هم کمک کنید

۰ اشتراک‌گذاری
اشتراک‌گذاری با ایمیل

عملیات موفق

لینک مقاله کپی شد

منو
حساب کاربری فروشگاه