توابع ناهمزمان را دوباره امتحان کنید

این سند توضیح می‌دهد که چگونه می‌توانید عملکردهای پس‌زمینه ناهمزمان (غیر HTTPS) را برای امتحان مجدد در صورت شکست درخواست کنید.

معناشناسی تلاش مجدد

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

برای توابع نسل دوم، این پنجره تلاش مجدد پس از 24 ساعت منقضی می شود. برای توابع نسل اول، پس از 7 روز منقضی می شود. توابع ابری، توابع مبتنی بر رویداد جدید ایجاد شده را با استفاده از یک استراتژی عقب‌نشینی نمایی، با افزایش بازپس‌گیری بین 10 تا 600 ثانیه، دوباره امتحان می‌کند. این خط مشی برای اولین باری که توابع جدید را اجرا می کنید اعمال می شود. این به طور عطف به ماسبق برای توابع موجود که برای اولین بار قبل از اعمال تغییرات شرح داده شده در این یادداشت انتشار اجرا شده اند، اعمال نمی شود، حتی اگر توابع را مجدداً مستقر کنید.

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

چرا توابع رویداد محور تکمیل نمی شوند

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

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

  • تابع حاوی یک اشکال است و زمان اجرا یک استثنا ایجاد می کند.
  • این تابع نمی تواند به یک نقطه پایانی سرویس برسد، یا در حین تلاش برای انجام این کار، زمان آن تمام می شود.
  • تابع عمداً یک استثنا ایجاد می کند (مثلاً وقتی پارامتری اعتبار سنجی را انجام نمی دهد).
  • یک تابع Node.js یک وعده رد شده را برمی گرداند، یا یک مقدار غیر null را به یک فراخوان ارسال می کند.

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

فعال یا غیرفعال کردن تلاش های مجدد

تلاش های مجدد را از کنسول GCP پیکربندی کنید

اگر در حال ایجاد یک تابع جدید هستید:

  1. از صفحه Create Function ، Add trigger را انتخاب کنید و نوع رویداد را انتخاب کنید تا به عنوان یک ماشه برای عملکرد شما عمل کند.
  2. در پنجره راه‌اندازی Eventarc ، کادر بررسی مجدد در صورت شکست را انتخاب کنید تا تلاش‌های مجدد فعال شود.

اگر یک تابع موجود را به روز می کنید:

  1. از صفحه نمای کلی توابع Cloud ، روی نام تابعی که به‌روزرسانی می‌کنید کلیک کنید تا صفحه جزئیات عملکرد آن باز شود، سپس ویرایش را از نوار منو برای نمایش پنجره‌های راه‌انداز HTTPS و Eventarc انتخاب کنید.
  2. در قسمت ماشه Eventarc ، روی نماد ویرایش کلیک کنید تا تنظیمات تریگر خود را ویرایش کنید.
  3. در پنجره راه‌اندازی Eventarc ، برای فعال یا غیرفعال کردن تلاش‌های مجدد، کادر بررسی مجدد در صورت شکست را انتخاب یا پاک کنید.

تلاش های مجدد را از کد تابع خود پیکربندی کنید

با Cloud Functions for Firebase، می‌توانید تلاش‌های مجدد را در کد یک تابع فعال کنید. برای انجام این کار برای یک تابع پس زمینه مانند functions.foo.onBar(myHandler); ، از runWith استفاده کنید و یک خط مشی شکست را پیکربندی کنید:

functions.runWith({failurePolicy: true}).foo.onBar(myHandler);

تنظیم true همانطور که نشان داده شده است، یک تابع را برای امتحان مجدد در صورت شکست پیکربندی می کند.

بهترین شیوه ها

این بخش بهترین روش ها را برای استفاده از تلاش های مجدد توضیح می دهد.

برای رسیدگی به خطاهای گذرا از تلاش مجدد استفاده کنید

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

برای جلوگیری از بی نهایت حلقه های تلاش مجدد، یک شرط پایان تنظیم کنید

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

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

برای مثال، این قطعه کد همه رویدادهای قدیمی‌تر از 10 ثانیه را کنار می‌گذارد:

const eventAgeMs = Date.now() - Date.parse(event.timestamp);
const eventMaxAgeMs = 10000;
if (eventAgeMs > eventMaxAgeMs) {
  console.log(`Dropping event ${event} with age[ms]: ${eventAgeMs}`);
  callback();
  return;
}

catch با Promises استفاده کنید

اگر عملکرد شما تلاش های مجدد را فعال کرده باشد، هر گونه خطای کنترل نشده باعث تلاش مجدد می شود. اطمینان حاصل کنید که کد شما خطاهایی را که نباید منجر به تلاش مجدد شود، ثبت کند.

در اینجا نمونه ای از کارهایی است که باید انجام دهید:

return doFooAsync().catch((err) => {
    if (isFatal(err)) {
        console.error(`Fatal error ${err}`);
    }
    return Promise.reject(err);
});

توابع رویداد محور قابل امتحان مجدد را بی توان کنید

توابع مبتنی بر رویداد که می توانند دوباره امتحان شوند، باید فاقد قدرت باشند. در اینجا چند دستورالعمل کلی برای ایجاد چنین عملکردی بی‌توان آورده شده است:

  • بسیاری از APIهای خارجی (مانند Stripe) به شما امکان می دهند یک کلید idempotency به عنوان یک پارامتر ارائه دهید. اگر از چنین API استفاده می کنید، باید از شناسه رویداد به عنوان کلید idempotency استفاده کنید.
  • Idempotency با حداقل یک بار تحویل به خوبی کار می کند، زیرا باعث می شود دوباره امتحان کنید. بنابراین بهترین روش کلی برای نوشتن کد قابل اعتماد، ترکیب ناتوانی با تلاش مجدد است.
  • اطمینان حاصل کنید که کد شما از لحاظ داخلی ناتوان است. مثلا:
    • اطمینان حاصل کنید که جهش ها می توانند بیش از یک بار بدون تغییر در نتیجه اتفاق بیفتند.
    • قبل از تغییر وضعیت، وضعیت پایگاه داده را در یک تراکنش جستجو کنید.
    • اطمینان حاصل کنید که همه عوارض جانبی خود ناتوان هستند.
  • یک بررسی تراکنشی خارج از تابع، مستقل از کد اعمال کنید. به عنوان مثال، در جایی ضبط کنید که شناسه رویداد معین قبلاً پردازش شده است.
  • با فراخوانی های تابع تکراری خارج از باند مقابله کنید. به عنوان مثال، یک فرآیند پاکسازی جداگانه داشته باشید که پس از فراخوانی عملکرد تکراری پاکسازی می شود.

خط مشی سعی مجدد را پیکربندی کنید

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

  • پنجره تلاش مجدد را از 7 روز به 10 دقیقه کوتاه کنید.
  • حداقل و حداکثر زمان عقب‌نشینی را برای استراتژی تلاش مجدد نمایی عقب‌نشینی تغییر دهید.
  • استراتژی امتحان مجدد را تغییر دهید تا فوراً دوباره امتحان کنید.
  • یک موضوع مرده را پیکربندی کنید.
  • حداکثر و حداقل تعداد تلاش برای تحویل را تنظیم کنید.

برای پیکربندی خط مشی سعی مجدد:

  1. یک تابع HTTP بنویسید.
  2. از Pub/Sub API برای ایجاد اشتراک Pub/Sub استفاده کنید و URL تابع را به عنوان هدف مشخص کنید.

برای اطلاعات بیشتر در مورد پیکربندی مستقیم Pub/Sub، به مستندات Pub/Sub در رسیدگی به خرابی ها مراجعه کنید.