Bu belgede, başarısızlık durumunda yeniden denemek için nasıl eşzamansız (HTTPS olmayan) arka plan işlevleri isteyebileceğiniz açıklanmaktadır.
Etkinliğe dayalı işlevlerin tamamlanamamasının nedenleri
Nadiren de olsa bir işlev, dahili bir hata nedeniyle erken çıkabilir ve varsayılan olarak işlev otomatik olarak yeniden denenmeyebilir.
Daha yaygın olarak, etkinliğe dayalı bir işlev, işlev kodunda oluşan hatalar nedeniyle başarıyla tamamlanamayabilir. Bunun olası nedenleri şunlardır:
- İşlevde bir hata var ve çalışma zamanı bir istisna oluşturuyor.
- İşlev, bir hizmet uç noktasına ulaşamıyor veya bunu yapmaya çalışırken zaman aşımına uğruyor.
- İşlev, kasıtlı olarak istisna oluşturur (örneğin, bir parametre doğrulanamadığında).
- Bir Node.js işlevi, reddedilen bir sözü döndürüyor veya geri çağırmaya
nullolmayan bir değer iletiyor.
Yukarıdaki durumlardan herhangi birinde işlevin yürütülmesi durdurulur ve hata döndürülür. İletileri oluşturan etkinlik tetikleyicilerinin, işlevinizin ihtiyaçlarını karşılayacak şekilde özelleştirebileceğiniz yeniden deneme politikaları vardır.
Yeniden deneme anlamsal yapısı
Cloud Functions, bir etkinlik kaynağı tarafından yayınlanan her etkinlik için etkinliğe dayalı bir işlevin en az bir kez yürütülmesini sağlar. Varsayılan olarak, bir işlev çağrısı hatayla sonlanırsa işlev tekrar çağrılmaz ve etkinlik bırakılır. Etkinliğe dayalı bir işlevde yeniden denemeleri etkinleştirdiğinizde, Cloud Functions başarısız olan işlev çağrısı başarıyla tamamlanana veya yeniden deneme penceresinin süresi dolana kadar yeniden denenir.
Bir işlev için yeniden denemeler etkinleştirilmediğinde (varsayılan ayar), işlev her zaman başarılı bir şekilde yürütüldüğünü bildirir ve günlüklerinde 200 OK yanıt kodları görünebilir. Bu durum, işlevde hata oluşsa bile geçerlidir. İşleviniz bir hatayla karşılaştığında bunu net bir şekilde belirtmek için hataları uygun şekilde bildirdiğinizden emin olun.
Yeniden denemeleri işlev kodunuzdan yapılandırma
Cloud Functions for Firebase ile bir işlev için kodda yeniden denemeleri etkinleştirebilirsiniz. Yeni bir Firestore dokümanı oluşturma gibi arka plan etkinliği için bunu yapmak istiyorsanız failurePolicy (1. nesil) veya retry (2. nesil) politikasını true olarak ayarlayın:
1. nesil
exports.docCreated = functions
.runWith({
// retry on failure
failurePolicy: true,
})
.firestore.document("my-collection/{docId}")
.onCreate((change, context) => {
/* ... */
});
2. nesil
const { onDocumentCreated } = require("firebase-functions/firestore");
exports.docCreated = onDocumentCreated(
{
// retry on failure
retry: true,
},
"my-collection/{docId}",
(event) => {
/* ... */
},
);
Gösterildiği gibi true ayarlandığında, bir işlev başarısız olduğunda yeniden denenmek üzere yapılandırılır.
Yeniden deneme aralığı
2. nesil işlevler için bu yeniden deneme penceresinin süresi 24 saat sonra dolar. 1. nesil işlevlerin süresi 7 gün sonra dolar. Cloud Functions, yeni oluşturulan olaya dayalı işlevleri üstel geri çekilme stratejisiyle yeniden dener. Geri çekilme süresi 10 ile 600 saniye arasında artar. Bu politika, yeni işlevlere ilk kez dağıtıldıklarında uygulanır. Bu değişiklik, bu sürüm notunda açıklanan değişiklikler yürürlüğe girmeden önce ilk kez dağıtılan mevcut işlevlere, işlevleri yeniden dağıtsanız bile geriye dönük olarak uygulanmaz.En iyi uygulamalar
Bu bölümde, yeniden denemeleri kullanmayla ilgili en iyi uygulamalar açıklanmaktadır.
Geçici hataları işlemek için yeniden denemeyi kullanma
İşleviniz başarılı bir şekilde yürütülene kadar sürekli olarak yeniden denendiğinden, yeniden denemeleri etkinleştirmeden önce test yoluyla kodunuzdaki hatalar gibi kalıcı hataları ortadan kaldırmanız gerekir. Yeniden denemeler, aralıklı veya geçici hataları ele almak için en iyi yöntemdir. Bu hataların yeniden denendiğinde çözülme olasılığı yüksektir. Örneğin, güvenilmez bir hizmet uç noktası veya zaman aşımı gibi.
Sonsuz yeniden deneme döngülerini önlemek için bir bitiş koşulu ayarlayın
Yeniden denemeleri kullanırken işlevinizi sürekli döngüye girmeye karşı korumak en iyi uygulamadır. Bu işlemi, işlev işlemeye başlamadan önce iyi tanımlanmış bir bitiş koşulu ekleyerek yapabilirsiniz. Bu tekniğin yalnızca işleviniz başarıyla başlatılırsa ve bitiş koşulunu değerlendirebilirse çalıştığını unutmayın.
Basit ancak etkili bir yaklaşım, belirli bir süreden daha eski zaman damgalarına sahip etkinlikleri silmektir. Bu, hatalar kalıcı olduğunda veya beklenenden daha uzun sürdüğünde aşırı yürütme işlemlerini önlemeye yardımcı olur.
Örneğin, bu kod snippet'i 10 saniyeden eski tüm etkinlikleri siler:
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 ile Promises kullanma
İşlevinizde yeniden deneme etkinse işlenmeyen tüm hatalar yeniden denemeyi tetikler. Kodunuzun, yeniden denemeye yol açmaması gereken hataları yakaladığından emin olun.
Yapmanız gerekenlere dair bir örnek:
return doFooAsync().catch((err) => {
if (isFatal(err)) {
console.error(`Fatal error ${err}`);
}
return Promise.reject(err);
});
Yeniden denenebilir etkinliğe dayalı işlevleri idempotent yapma
Yeniden denenebilen etkinlik odaklı işlevler, idempotent olmalıdır. Bu tür bir işlevi idempotent hale getirmek için bazı genel yönergeleri aşağıda bulabilirsiniz:
- Birçok harici API (ör. Stripe), parametre olarak bir idempotentlik anahtarı sağlamanıza olanak tanır. Böyle bir API kullanıyorsanız etkinlik kimliğini, idempotentlik anahtarı olarak kullanmanız gerekir.
- İdempotency, en az bir kez teslimatla iyi çalışır. Çünkü yeniden denemeyi güvenli hale getirir. Bu nedenle, güvenilir kod yazmak için genel olarak en iyi uygulama, yeniden denemelerle birlikte idempotentliği kullanmaktır.
- Kodunuzun dahili olarak idempotent olduğundan emin olun. Örneğin:
- Mutasyonların sonucu değiştirmeden birden fazla kez gerçekleşebildiğinden emin olun.
- Durumu değiştirmeden önce bir işlemdeki veritabanı durumunu sorgulayın.
- Tüm yan etkilerin kendilerinin idempotent olduğundan emin olun.
- İşlevin dışında, koddan bağımsız bir işlemsel kontrol uygulayın. Örneğin, belirli bir etkinlik kimliğinin zaten işlendiğini kaydeden bir durumu kalıcı hale getirin.
- Yinelenen işlev çağrılarını bant dışı olarak ele alın. Örneğin, yinelenen işlev çağrılarından sonra temizlik yapan ayrı bir temizleme işlemi yapın.
Yeniden deneme politikasını yapılandırma
İşlevinizin ihtiyaçlarına bağlı olarak yeniden deneme politikasını doğrudan yapılandırmak isteyebilirsiniz. Bu sayede aşağıdaki öğelerin herhangi bir kombinasyonunu ayarlayabilirsiniz:
- Yeniden deneme aralığını 7 günden 10 dakikaya kadar kısaltın.
- Üstel geri çekilme yeniden deneme stratejisi için minimum ve maksimum geri çekilme süresini değiştirin.
- Yeniden deneme stratejisini hemen yeniden deneme olarak değiştirin.
- Bir dead-letter topic yapılandırın.
- Maksimum ve minimum teslim denemesi sayısı belirleyin.
Yeniden deneme politikasını yapılandırmak için:
- HTTP işlevi yazın.
- Hedef olarak işlevin URL'sini belirterek Pub/Sub aboneliği oluşturmak için Pub/Sub API'sini kullanın.
Pub/Sub'ı doğrudan yapılandırma hakkında daha fazla bilgi için Pub/Sub hataları işleme dokümanlarına bakın.