این سند توضیح میدهد که چگونه میتوانید عملکردهای پسزمینه ناهمزمان (غیر HTTPS) را برای امتحان مجدد در صورت شکست درخواست کنید.
معناشناسی تلاش مجدد
Cloud Functions حداقل یک بار اجرای یک تابع رویداد محور را برای هر رویداد منتشر شده توسط یک منبع رویداد تضمین می کند. با این حال، به طور پیش فرض، اگر فراخوانی یک تابع با یک خطا خاتمه یابد، تابع دوباره فراخوانی نمی شود و رویداد حذف می شود. وقتی تلاشهای مجدد را روی یک تابع رویداد محور فعال میکنید، Cloud Functions یک فراخوانی عملکرد ناموفق را تا زمانی که با موفقیت کامل شود یا پنجره امتحان مجدد منقضی شود دوباره امتحان میکند. برای توابع نسل دوم، پنجره تلاش مجدد پس از 24 ساعت منقضی می شود. برای توابع نسل اول، پس از 7 روز منقضی می شود. توابع مبتنی بر رویداد جدید ایجاد شده با استفاده از یک استراتژی عقبنشینی نمایی، با حداقل عقبنشینی 10 ثانیه و حداکثر عقبنشینی 600 ثانیه یا ده دقیقه، دوباره امتحان میکنند. این خط مشی برای اولین باری که توابع جدید را اجرا می کنید اعمال می شود. این به طور عطف به ماسبق برای توابع موجود که برای اولین بار قبل از اعمال تغییرات شرح داده شده در این یادداشت انتشار اجرا شده اند، اعمال نمی شود، حتی اگر توابع را مجدداً مستقر کنید.
هنگامی که تلاش های مجدد برای یک تابع، که پیش فرض است، فعال نمی شود، تابع همیشه گزارش می دهد که با موفقیت اجرا شده است و ممکن است 200 OK
در گزارش های آن ظاهر شود. این اتفاق می افتد حتی اگر تابع با خطا مواجه شود. برای اینکه مشخص شود عملکرد شما با خطا مواجه می شود، حتماً خطاها را به طور مناسب گزارش کنید .
چرا توابع رویداد محور تکمیل نمی شوند
در موارد نادر، یک تابع ممکن است به دلیل یک خطای داخلی زودتر از موعد خارج شود، و به طور پیش فرض ممکن است عملکرد به طور خودکار دوباره امتحان شود یا نباشد.
به طور معمول، یک تابع رویداد محور ممکن است به دلیل خطاهایی که در خود کد تابع وجود دارد، با موفقیت تکمیل نشود. برخی از دلایلی که ممکن است این اتفاق بیفتد به شرح زیر است:
- تابع حاوی یک اشکال است و زمان اجرا یک استثنا ایجاد می کند.
- این تابع نمی تواند به یک نقطه پایانی سرویس برسد، یا در حین تلاش برای رسیدن به نقطه پایانی، زمان آن تمام می شود.
- تابع عمداً یک استثنا ایجاد می کند (مثلاً وقتی پارامتری اعتبار سنجی را انجام نمی دهد).
- هنگامی که توابع نوشته شده در Node.js یک وعده رد شده را برمی گردانند یا یک مقدار غیر
null
را به یک callback ارسال می کنند.
در هر یک از موارد فوق، اجرای تابع به طور پیش فرض متوقف می شود و رویداد کنار گذاشته می شود. اگر میخواهید در صورت بروز خطا، عملکرد را دوباره امتحان کنید، میتوانید با تنظیم ویژگی «تعداد مجدد در صورت شکست»، خطمشی تکرار پیشفرض را تغییر دهید. این باعث می شود که رویداد به طور مکرر تا چند روز تکرار شود تا اینکه عملکرد با موفقیت کامل شود.
فعال و غیرفعال کردن تلاش های مجدد
با استفاده از کنسول GCP
میتوانید تلاشهای مجدد را در کنسول GCP به صورت زیر فعال یا غیرفعال کنید:
به صفحه بررسی اجمالی توابع Cloud در کنسول Cloud Platform بروید.
روی ایجاد تابع کلیک کنید. یا، روی یک تابع موجود کلیک کنید تا به صفحه جزئیات آن بروید و روی ویرایش کلیک کنید.
فیلدهای لازم را برای عملکرد خود پر کنید.
مطمئن شوید که فیلد Trigger روی یک نوع محرک مبتنی بر رویداد، مانند Cloud Pub/Sub یا Cloud Storage تنظیم شده است.
تنظیمات پیشرفته را با کلیک کردن روی بیشتر گسترش دهید.
کادر با عنوان «تکرار مجدد در صورت شکست» را علامت بزنید یا علامت آن را بردارید.
در کد تابع
با 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 دقیقه کوتاه کنید.
- حداقل و حداکثر زمان عقبنشینی را برای استراتژی تلاش مجدد نمایی عقبنشینی تغییر دهید.
- استراتژی امتحان مجدد را تغییر دهید تا فوراً دوباره امتحان کنید.
- یک موضوع مرده را پیکربندی کنید.
- حداکثر و حداقل تعداد تلاش برای تحویل را تنظیم کنید.
برای پیکربندی خط مشی سعی مجدد:
- یک تابع HTTP بنویسید.
- از Pub/Sub API برای ایجاد اشتراک Pub/Sub استفاده کنید و URL تابع را به عنوان هدف مشخص کنید.
برای اطلاعات بیشتر در مورد پیکربندی مستقیم Pub/Sub، به مستندات Pub/Sub در رسیدگی به خرابی ها مراجعه کنید.