Async Tasks در وردپرس یعنی اجرای عملیات سنگین در پس‌زمینه و بدون بلاک کردن پاسخ به کاربر، و همین قابلیت است که تفاوت میان سایتی پاسخگو و سایتی کند را می‌سازد.

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

سه مکانیزم اصلی برای اجرای غیرهمگام وجود دارد: WP-Cron، Action Scheduler و درخواست‌های Loopback.

انتخاب اشتباه در هر یک از این سه، یا باعث از کار افتادن زمان‌بندی می‌شود یا بار سرور را در اوج ترافیک چند برابر می‌کند.

هدف این نوشته، رسیدن از فهم پایه تا معماری عملی برای اجرای غیرهمگام در محیط تولید است.

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

تله اجرای همگام در وردپرس

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

مسئله اینجاست که بخش بزرگی از عملیات‌هایی که وردپرس باید انجام دهد، هیچ ارتباطی به پاسخ فوری کاربر ندارند. ارسال ایمیل، تغییر اندازه تصویر، همگام‌سازی با سرویس خارجی، به‌روزرسانی آمار و تولید گزارش، همه این‌ها می‌توانند پس از ارسال پاسخ انجام شوند. اما در معماری پیش‌فرض، همه آن‌ها پیش از ارسال پاسخ اجرا می‌شوند.

نتیجه، انتظار کاربر برای عملیاتی است که هیچ سودی برای او ندارد. این انتظار در ترافیک کم محسوس نیست، اما در ساعات اوج، به انباشت درخواست‌ها و اشباع لایه‌های سرور منجر می‌شود. تصویر کامل این الگو در تنظیم PHP-FPM برای وردپرس از منظر ظرفیت سرور به‌تفصیل بررسی شده است.

تله دوم، وابستگی زنجیره‌ای است. یک عملیات همگام کند می‌تواند زمان اجرای کل درخواست را افزایش دهد و همین افزایش، فرآیند PHP را مدت بیشتری در اختیار بگیرد. وقتی تعداد این فرآیندها محدود است، صف درخواست‌ها طولانی می‌شود و کاربران بعدی نیز با تأخیر روبه‌رو می‌شوند. یک کندی کوچک در یک نقطه، به کندی گسترده در سطح سایت تبدیل می‌شود.

هر عملیاتی که در مسیر پاسخ کاربر اجرا می‌شود، هزینه‌ای است که کاربر آن را می‌پردازد؛ حتی اگر هیچ ارتباطی به خواسته او نداشته باشد.

Async Task دقیقاً چیست و چه چیزی نیست

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

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

نکته مهم این است که Async Task با مفهوم Multithreading یا Parallel Processing یکسان نیست. در وردپرس، اجرای غیرهمگام معمولاً به معنای انتقال عملیات به یک فرآیند دیگر است، نه اجرای موازی همان عملیات در چند Thread.

افزون بر این، Async Task با Cache Warming نیز یکسان نیست. اگرچه هر دو در پس‌زمینه اجرا می‌شوند، Warming یک عملیات پیشگیرانه برای پرکردن کش است و Async Task معمولاً واکنشی به یک رویداد مشخص. تفاوت‌های این دو در گرم‌کردن کش در وردپرس به‌تفصیل آمده است.

در وردپرس، اجرای غیرهمگام به چند شکل ممکن است. ساده‌ترین شکل، ثبت یک تسک در صف و اجرای آن با WP-Cron است. شکل پیشرفته‌تر، استفاده از Action Scheduler یا سیستم‌های صف تخصصی مانند Redis Queue است. شکل دیگر، ارسال یک درخواست HTTP به خود سایت با استفاده از Loopback است.

چرا غیرهمگام‌سازی در وردپرس حیاتی است

پاسخ این پرسش در سه سطح قابل بررسی است: سطح تجربه کاربر، سطح ظرفیت سرور و سطح پایداری سیستم.

در سطح تجربه کاربر، تفاوت میان یک عملیات همگام و غیرهمگام می‌تواند به اندازه چند ثانیه باشد. این تفاوت در معیارهایی مانند TTFB (Time To First Byte) و LCP (Largest Contentful Paint) مستقیماً دیده می‌شود. اثر این معیارها روی نرخ تبدیل، موضوعی است که در تأثیر سرعت سایت بر نرخ تبدیل به‌تفصیل بررسی شده است.

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

در سطح پایداری، اجرای غیرهمگام امکان تلاش مجدد در زمان خطا را فراهم می‌کند. اگر ارسال یک ایمیل در زمان همگام شکست بخورد، سرنوشت آن نامعلوم می‌ماند. در زمان غیرهمگام، شکست ثبت می‌شود و تسک می‌تواند در زمان دیگری دوباره تلاش شود.

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

WP-Cron و محدودیت‌های بنیادین آن

WP-Cron مکانیزم بومی وردپرس برای اجرای تسک‌های زمان‌بندی‌شده است. برخلاف نامش، این مکانیزم یک Cron واقعی نیست. یعنی وابسته به بازدید کاربران است و در زمان بازدید، تسک‌های موعد‌رسیده را اجرا می‌کند.

این رفتار یک پیامد جدی دارد: اگر سایت بازدیدی نداشته باشد، تسک‌ها اجرا نمی‌شوند. در سایت‌های کم‌بازدید یا سایت‌هایی که ترافیکشان در ساعات مشخصی متمرکز است، این وابستگی می‌تواند به تأخیر یا از کار افتادن تسک‌ها منجر شود.

مسئله دوم، بار سرور است. WP-Cron در زمان بازدید، تسک‌های موعد‌رسیده را در همان درخواست اجرا می‌کند. یعنی همان کاربری که برای مشاهده صفحه آمده، منتظر اجرای تسک‌های پس‌زمینه می‌ماند. در سایت‌هایی که تسک‌های سنگین دارند، این رفتار می‌تواند به تأخیر محسوس منجر شود.

// Disable default WP-Cron
define( "DISABLE_WP_CRON", true );

// Then add a real cron job on the server
// */5 * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

غیرفعال‌کردن WP-Cron پیش‌فرض و جایگزینی آن با یک Cron واقعی، اولین قدم در مسیر استفاده جدی از این مکانیزم است. این تغییر، اجرای تسک‌ها را از بازدید کاربران جدا می‌کند و پایداری را افزایش می‌دهد.

اما حتی با این تغییر، WP-Cron محدودیت‌های بنیادین دارد. این مکانیزم برای تسک‌های ساده و سبک طراحی شده و برای صف‌های پیچیده با نیاز به تلاش مجدد، ترتیب دقیق و مشاهده دقیق وضعیت، ابزار مناسبی نیست. نکات تکمیلی این موضوع در کرون وردپرس و زمان‌بندی خودکار کارها به‌تفصیل آمده است.

مسائل عیب‌یابی WP-Cron نیز موضوعی است که در پروژه‌های واقعی پرتکرار است. اگر تسک‌ها اجرا نمی‌شوند یا به‌طور مکرر شکست می‌خورند، مسیر عیب‌یابی در رفع مشکلات کرون در وردپرس به‌طور ساختارمند آمده است.

Action Scheduler به‌عنوان جایگزین جدی

Action Scheduler یک کتابخانه صف تسک است که در اکوسیستم وردپرس به‌عنوان جایگزین جدی WP-Cron شناخته می‌شود. این کتابخانه بخشی از ووکامرس است، اما به‌طور مستقل هم استفاده می‌شود.

سه مزیت اصلی این کتابخانه را از WP-Cron متمایز می‌کند. اول، ثبت دقیق وضعیت هر تسک. دوم، امکان تلاش مجدد خودکار در زمان شکست. سوم، پشتیبانی از صف‌های بزرگ بدون بار آنی روی سرور.

Action Scheduler تسک‌ها را در یک جدول اختصاصی در پایگاه داده نگه می‌دارد. هر تسک وضعیت مشخصی دارد: در انتظار، در حال اجرا، تکمیل‌شده یا شکست‌خورده. این ثبت دقیق، عیب‌یابی را به‌شدت آسان‌تر می‌کند.

add_action( "init", function () {
    if ( ! function_exists( "as_enqueue_async_action" ) ) {
        return;
    }
    as_enqueue_async_action( "wpk_send_welcome_email", array( "user_id" => 123 ), "wpk_emails" );
} );

add_action( "wpk_send_welcome_email", function ( $user_id ) {
    $user = get_user_by( "id", $user_id );
    if ( ! $user ) {
        return;
    }
    wp_mail( $user->user_email, "Welcome", "..." );
} );

در این الگو، تسک بلافاصله ثبت می‌شود و وردپرس پاسخ را به کاربر بازمی‌گرداند. Action Scheduler در فرآیندی جداگانه، تسک را اجرا می‌کند و نتیجه را ثبت می‌کند.

نکته مهم این است که Action Scheduler خودش به یک محرک نیاز دارد. یعنی باید یک Cron واقعی وجود داشته باشد که به‌طور دوره‌ای Action Scheduler را فراخوانی کند. بدون این محرک، تسک‌ها در صف می‌مانند و اجرا نمی‌شوند.

در پروژه‌های فروشگاهی، Action Scheduler ستون فقرات پردازش‌های پس‌زمینه است. ارسال ایمیل سفارش، همگام‌سازی موجودی، به‌روزرسانی گزارش‌ها و اجرای تسک‌های بلندمدت، همه از طریق این کتابخانه مدیریت می‌شوند. پیامدهای این معماری در بهینه‌سازی سرعت ووکامرس به‌طور کامل بررسی شده است.

صف تسک بدون ثبت وضعیت، فقط یک تعویق است؛ نه یک راه‌حل مهندسی‌شده.

Loopback Requests و رفتار واقعی آن‌ها

یک Loopback Request یا درخواست بازگشتی، درخواست HTTP است که سرور به خودش می‌فرستد. این مکانیزم، ساده‌ترین راه برای انتقال یک عملیات به یک درخواست دیگر است و همین سادگی دلیل استفاده گسترده آن است.

الگوی معمول این است که پس از پاسخ به کاربر، یک درخواست HTTP به یک URL مشخص از خود سایت فرستاده می‌شود. آن درخواست در سرور جدید یا همان سرور، مسیر متفاوتی را طی می‌کند و عملیات مورد نظر را انجام می‌دهد.

function wpk_fire_async_request( $url, $args = array() ) {
    $args = wp_parse_args( $args, array(
        "timeout"   => 0.01,
        "blocking"  => false,
        "sslverify" => false,
    ) );
    return wp_remote_post( $url, $args );
}

add_action( "wpk_after_order_placed", function ( $order_id ) {
    wpk_fire_async_request( rest_url( "wpk/v1/process-order" ), array(
        "body" => array( "order_id" => $order_id ),
    ) );
} );

پارامتر blocking => false کلید این الگو است. با این تنظیم، وردپرس درخواست را می‌فرستد و بدون انتظار برای پاسخ، به اجرای خود ادامه می‌دهد. پارامتر timeout => 0.01 نیز تضمین می‌کند که حتی اگر پاسخ نرسد، درخواست اصلی بلاک نشود.

مسئله مهم در این الگو، تأخیر در ارسال واقعی است. اگرچه وردپرس بدون انتظار ادامه می‌دهد، اما پاسخ به کاربر تنها زمانی صادر می‌شود که PHP اجرای خود را به پایان برساند. در این فاصله، درخواست Loopback ممکن است هنوز در حال پردازش باشد. با فعال‌بودن fastcgi_finish_request، این فاصله می‌تواند به حداقل برسد.

if ( function_exists( "fastcgi_finish_request" ) ) {
    fastcgi_finish_request();
}

این تابع، پاسخ را به کاربر می‌فرستد و سپس PHP را آزاد می‌کند تا به اجرای خود ادامه دهد. نتیجه، جداسازی کامل پاسخ به کاربر از عملیات پس‌زمینه است. این تکنیک بخشی از پیکربندی بهینه در تنظیم PHP-FPM برای وردپرس است و در ترکیب با Loopback اثر چشمگیری دارد.

اما Loopback Requests محدودیت‌هایی هم دارند. اگر سایت روی یک شبکه داخلی با محدودیت اتصال به خودش کار کند، درخواست‌ها ممکن است رد شوند. همچنین اگر سایت تحت حفاظت لایه امنیتی باشد که درخواست‌های بدون هدر شناخته‌شده را مسدود می‌کند، این درخواست‌ها نیز مسدود می‌شوند.

سیستم‌های صف تخصصی و زمان استفاده

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

سه گزینه اصلی وجود دارد. Redis Queue یک راه‌حل سبک و سریع است که روی همان سرور یا سرور مجاور اجرا می‌شود. RabbitMQ یک سیستم صف پیام‌رسان قدرتمند است که برای معماری‌های پیچیده‌تر مناسب است. Amazon SQS و معادل‌های ابری آن، گزینه‌ای مقیاس‌پذیر و کاملاً مدیریت‌شده هستند.

در اکوسیستم وردپرس، Redis Queue بیشترین کاربرد را دارد، چون Redis معمولاً به‌عنوان کش شیء هم استفاده می‌شود و زیرساخت آن از قبل آماده است. کتابخانه‌هایی مانند WP Redis Queue یا پروژه‌های اختصاصی، اتصال وردپرس به این سیستم را ساده می‌کنند.

$redis = new Redis();
$redis->connect( "127.0.0.1", 6379 );

$redis->lPush( "wpk:queue:emails", json_encode( array(
    "type"    => "welcome",
    "user_id" => 123,
    "queued"  => time(),
) ) );

مصرف این صف نیازمند یک Worker مستقل است که به‌طور مداوم صف را بررسی کند و تسک‌ها را اجرا کند. این Worker می‌تواند یک اسکریپت PHP CLI باشد که با Supervisor یا Systemd مدیریت می‌شود.

مزیت اصلی این معماری، جداسازی کامل محیط اجرای تسک از محیط پاسخ به کاربر است. حتی اگر Worker از کار بیفتد، سایت همچنان پاسخ‌گو می‌ماند. تسک‌ها در صف منتظر می‌مانند تا Worker بازگردد.

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

REST API به‌عنوان نقطه ورود غیرهمگام

REST API وردپرس یک نقطه ورود استاندارد برای درخواست‌های غیرهمگام فراهم می‌کند. با استفاده از این لایه، می‌توان عملیاتی را به یک درخواست HTTP جداگانه منتقل کرد و نتیجه را به‌صورت مستقل مدیریت کرد.

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

add_action( "rest_api_init", function () {
    register_rest_route( "wpk/v1", "/process-order", array(
        "methods"             => "POST",
        "callback"            => "wpk_process_order_callback",
        "permission_callback" => function ( $request ) {
            return wpk_verify_internal_token( $request->get_header( "X-WPK-Token" ) );
        },
    ) );
} );

function wpk_process_order_callback( WP_REST_Request $request ) {
    $order_id = absint( $request->get_param( "order_id" ) );
    if ( ! $order_id ) {
        return new WP_Error( "invalid_order", "Order ID missing", array( "status" => 400 ) );
    }
    wpk_run_order_processing( $order_id );
    return new WP_REST_Response( array( "status" => "queued" ), 200 );
}

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

نکته دیگری که در پروژه‌ها کمتر به آن توجه می‌شود، ممنوعیت Cache برای این Endpointهاست. اگر یک Endpoint غیرهمگام از کش پاسخ بگیرد، هیچ عملیاتی اجرا نمی‌شود. سیاست‌گذاری در این لایه موضوعی است که در بی‌اعتبارسازی کش در وردپرس به‌تفصیل آمده است.

در پروژه‌های سازمانی، این Endpointها معمولاً به‌عنوان بخشی از API عمومی در نظر گرفته می‌شوند. رهنمودهای جامع این حوزه در استفاده از REST API در وردپرس به‌طور کامل بررسی شده است.

سناریوهای واقعی: ایمیل، تصویر، همگام‌سازی

سه دسته اصلی از عملیات‌ها هستند که در پروژه‌های وردپرسی بیشترین سود را از غیرهمگام‌سازی می‌برند. شناخت این دسته‌ها به تصمیم‌گیری درست کمک می‌کند.

دسته اول، ارسال ایمیل است. تابع wp_mail به‌طور پیش‌فرض همگام است و تا زمان پاسخ سرور SMTP بلاک می‌شود. این انتظار می‌تواند از چند صد میلی‌ثانیه تا چند ثانیه متغیر باشد. انتقال ارسال ایمیل به صف پس‌زمینه، این انتظار را از مسیر کاربر حذف می‌کند.

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

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

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

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

Async در فروشگاه ووکامرس

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

مرحله ثبت سفارش، نقطه حساس اصلی است. پس از ثبت سفارش، چندین عملیات باید انجام شود: ارسال ایمیل تأییدیه، کاهش موجودی انبار، اطلاع به سیستم انبار، ثبت در سیستم حسابداری و به‌روزرسانی گزارش‌ها. اگر همه این عملیات به‌صورت همگام انجام شوند، کاربر ممکن است چند ثانیه منتظر بماند.

ووکامرس به‌طور پیش‌فرض از Action Scheduler برای این کارها استفاده می‌کند. اما این استفاده همیشه کامل نیست. بعضی از عملیات‌ها هنوز همگام اجرا می‌شوند و همین بخش، گلوگاه باقی می‌ماند.

add_action( "woocommerce_checkout_order_processed", function ( $order_id ) {
    as_enqueue_async_action(
        "wpk_send_order_notifications",
        array( "order_id" => $order_id ),
        "wpk_orders"
    );
}, 10, 1 );

add_action( "wpk_send_order_notifications", function ( $order_id ) {
    $order = wc_get_order( $order_id );
    if ( ! $order ) {
        return;
    }
    wpk_notify_warehouse( $order );
    wpk_notify_accounting( $order );
    wpk_send_confirmation_email( $order );
} );

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

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

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

پیامدهای عملکردی و ظرفیت سرور

انتقال عملیات‌ها به پس‌زمینه، اثر مستقیم روی ظرفیت سرور دارد. با کاهش زمان اشغال هر فرآیند PHP، تعداد درخواست‌هایی که در واحد زمان پاسخ می‌گیرند افزایش می‌یابد. این افزایش، معادل ارتقای سخت‌افزار است.

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

پیامد دوم، مصرف حافظه است. Workerهای پس‌زمینه معمولاً به‌طور مداوم اجرا می‌شوند و حافظه مشخصی را اشغال می‌کنند. در سرورهایی با حافظه محدود، این مصرف باید در محاسبه کل ظرفیت لحاظ شود.

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

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

پایش و اشکال‌زدایی تسک‌های پس‌زمینه

پایش تسک‌های پس‌زمینه در وردپرس نیازمند ابزارهای اختصاصی است. سه سطح پایش وجود دارد: سطح صف، سطح Worker و سطح نتیجه.

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

در سطح Worker، وضعیت فرآیندهای اجرایی بررسی می‌شود. آیا Worker فعال است؟ آیا مکرراً ریستارت می‌شود؟ آیا مصرف حافظه آن در حال افزایش است؟ این پرسش‌ها به تشخیص مشکلات ظریف کمک می‌کنند.

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

wp action-scheduler run --batch=50 --batches=10
wp action-scheduler list --status=pending --per_page=20
wp action-scheduler list --status=failed --per_page=20

در سایت‌هایی که از Action Scheduler استفاده می‌کنند، این دستورات خط فرمان ابزارهای اصلی بررسی وضعیت هستند. ترکیب آن‌ها با ابزارهای مانیتورینگ سرور، تصویر کاملی از وضعیت سیستم ارائه می‌دهد.

نکته مهم در زمان اشکال‌زدایی، ثبت لاگ مناسب است. هر تسک باید اطلاعات کافی برای بازسازی شرایط اجرای خود را ثبت کند. بدون این لاگ، ریشه‌یابی شکست‌ها می‌تواند زمان‌بر و پرخطا شود.

در سطح جریان استقرار، باید اطمینان حاصل شود که تغییرات کد و پیکربندی، Workerهای پس‌زمینه را هم به‌روز می‌کنند. این موضوع بخشی از جریان کلی است که در پیاده‌سازی CI/CD برای پروژه‌های وردپرسی به‌تفصیل آمده است.

جدول تصمیم‌گیری مکانیزم اجرا

سناریومکانیزم پیشنهادیدلیلریسک
ارسال ایمیل پس از ثبت‌نامAction Schedulerتلاش مجدد خودکار و ثبت وضعیتنیاز به Cron واقعی
پردازش تصویر در زمان آپلودLoopback + FastCGI finishجداسازی سریع از مسیر کاربراحتمال مسدود شدن درخواست
همگام‌سازی با سرویس خارجیRedis Queue + Workerمقاومت در برابر خطای سرویسپیچیدگی زیرساخت
تولید گزارش‌های دوره‌ایWP-Cron با Cron واقعیسادگی و کفایت برای تسک‌های سبکوابستگی به زمان‌بندی سرور
پردازش سفارش ووکامرسAction Schedulerیکپارچگی بومی با ووکامرسانباشت در ترافیک بالا

اشتباهات رایج

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

دومین اشتباه، اعتماد به WP-Cron پیش‌فرض در محیط تولید است. این مکانیزم وابسته به بازدید است و در سایت‌های با ترافیک نامنظم، قابل اتکا نیست.

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

چهارمین اشتباه، اجرای Workerهای متعدد بدون هماهنگی است. اگر چند Worker روی یک صف مشترک کار کنند بدون هماهنگی، یک تسک می‌تواند چند بار اجرا شود.

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

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

هفتمین اشتباه، نادیده گرفتن امنیت Endpointهای غیرهمگام است. اگر این Endpointها به‌درستی محافظت نشوند، امکان سوءاستفاده از آن‌ها برای اشباع سرور فراهم می‌شود. رعایت اصول امنیتی مشابه آنچه در امن‌سازی ورود ادمین وردپرس آمده، در این حوزه هم ضروری است.

پرسش‌های پرتکرار درباره Async Tasks در وردپرس

آیا WP-Cron برای اجرای تسک‌های پس‌زمینه کافی است؟

برای تسک‌های سبک و سایت‌های با ترافیک منظم، WP-Cron با یک Cron واقعی روی سرور می‌تواند کافی باشد. برای تسک‌های سنگین، صف‌های بزرگ یا نیاز به تلاش مجدد دقیق، ابزارهای تخصصی‌تر مانند Action Scheduler یا صف‌های خارجی مناسب‌ترند.

تفاوت Action Scheduler و WP-Cron چیست؟

WP-Cron یک مکانیزم زمان‌بندی ساده است که به بازدید کاربران وابسته است. Action Scheduler یک کتابخانه صف تسک است که وضعیت هر تسک را ثبت می‌کند، امکان تلاش مجدد دارد و می‌تواند صف‌های بزرگ را مدیریت کند.

Loopback Request چیست و چه زمانی استفاده می‌شود؟

یک درخواست HTTP است که سرور به خودش می‌فرستد. این مکانیزم برای انتقال سریع یک عملیات به یک درخواست جداگانه استفاده می‌شود. برای تسک‌های کوتاه و بدون نیاز به تلاش مجدد مناسب است.

چرا Async Task می‌تواند به کندی سایت منجر شود؟

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

آیا اجرای غیرهمگام روی سئو اثر دارد؟

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

چگونه مطمئن شوم تسک‌های پس‌زمینه اجرا می‌شوند؟

با ترکیب پایش صف، پایش Worker و پایش نتیجه. ابزارهای خط فرمان Action Scheduler امکان بررسی دقیق وضعیت تسک‌ها را فراهم می‌کنند. در سطح سرور، مانیتورینگ فرآیندهای Worker بخش ضروری این کار است.

آیا برای سایت کوچک هم غیرهمگام‌سازی ضروری است؟

در سایت‌های کوچک با ترافیک محدود، انتقال عملیات سنگین به پس‌زمینه می‌تواند تجربه را بهبود دهد، اما پیچیدگی اضافه‌شده باید متناسب با سود باشد. برای بیشتر سایت‌های کوچک، Action Scheduler یک نقطه شروع معقول است.

آیا Async Task جایگزین بهینه‌سازی کد است؟

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

چگونه بین WP-Cron، Action Scheduler و صف خارجی انتخاب کنیم؟

انتخاب بر اساس سه معیار انجام می‌شود: حجم تسک‌ها، نیاز به تلاش مجدد دقیق و سطح زیرساخت در دسترس. برای سایت‌های متوسط، Action Scheduler معمولاً انتخاب متعادل‌تری است. برای حجم بسیار بالا، صف خارجی اجتناب‌ناپذیر است.

آیا استفاده از Async Task روی امنیت سایت اثر دارد؟

بله، اگر Endpointهای غیرهمگام به‌درستی محافظت نشوند. این Endpointها می‌توانند به‌عنوان نقطه ورود برای سوءاستفاده استفاده شوند. احراز هویت داخلی و محدودسازی نرخ درخواست دو اقدام ضروری هستند.

یک نکته برای ادامه مسیر

Async Tasks یک تصمیم معماری است، نه یک تنظیم. هر عملیاتی که از مسیر پاسخ کاربر حذف می‌شود، در واقع به یک زیرساخت جدید منتقل می‌شود که نیازمند طراحی، پایش و نگهداری است. تفاوت میان یک سایت سریع و یک سایت پایدار، در همین نقطه تعیین می‌شود.

اگر روی پروژه خودتان این مسیر را طی کرده‌اید، خوشحال می‌شوم بدانم کدام بخش بیشترین زمان را گرفت: انتخاب مکانیزم اجرا، جداسازی Workerها از مسیر وب، یا پایش تسک‌های شکست‌خورده. تجربه‌تان را در دیدگاه‌ها بنویسید؛ به‌ویژه اگر راه‌حل متفاوتی پیدا کرده‌اید که می‌تواند برای خواننده بعدی مفید باشد.