Eşzamansız işlevleri yeniden deneyin

Bu belge, hata durumunda yeniden denemek için eşzamansız (HTTPS olmayan) arka plan işlevlerini nasıl talep edebileceğinizi açıklar.

Yeniden denemenin anlamı

Cloud Functions, bir olay kaynağı tarafından yayılan her olay için olaya dayalı bir fonksiyonun en az bir kez yürütülmesini garanti eder. Ancak, varsayılan olarak, bir işlev çağrısı bir hatayla sona ererse, işlev tekrar çağrılmayacak ve olay bırakılacaktır. Olaya dayalı bir işlevde yeniden denemeleri etkinleştirdiğinizde, Cloud Functions, başarıyla tamamlanana veya yeniden deneme penceresi sona erene kadar (varsayılan olarak 7 gün sonra) başarısız bir işlev çağrısını yeniden dener.

Varsayılan olan bir işlev için yeniden denemeler etkinleştirilmediğinde, işlev her zaman başarıyla yürütüldüğünü bildirir ve günlüklerinde 200 OK yanıt kodu görünebilir. Bu, işlev bir hatayla karşılaşsa bile oluşur. İşleviniz bir hatayla karşılaştığında bunu netleştirmek için hataları uygun şekilde bildirdiğinizden emin olun.

Olaya dayalı işlevler neden tamamlanamıyor?

Nadir durumlarda, dahili bir hata nedeniyle bir işlev zamanından önce çıkabilir ve varsayılan olarak işlev otomatik olarak yeniden denenebilir veya denenmeyebilir.

Daha tipik olarak, olaya dayalı bir işlev, işlev kodunun kendisinde meydana gelen hatalar nedeniyle başarıyla tamamlanamayabilir. Bunun olmasının nedenlerinden bazıları şunlardır:

  • İşlev bir hata içeriyor ve çalışma zamanı bir istisna oluşturuyor.
  • İşlev, bir hizmet uç noktasına ulaşamaz veya uç noktaya ulaşmaya çalışırken zaman aşımına uğrar.
  • İşlev kasıtlı olarak bir istisna atar (örneğin, bir parametre doğrulamada başarısız olduğunda).
  • Node.js'de yazılan işlevler reddedilen bir söz verdiğinde veya bir geri çağırmaya null olmayan bir değer ilettiğinde.

Yukarıdaki durumlardan herhangi birinde, işlev varsayılan olarak çalışmayı durdurur ve olay atılır. Bir hata oluştuğunda işlevi yeniden denemek isterseniz , "hata durumunda yeniden dene" özelliğini ayarlayarak varsayılan yeniden deneme ilkesini değiştirebilirsiniz. Bu, işlev başarıyla tamamlanana kadar olayın birden çok gün boyunca tekrar tekrar denenmesine neden olur.

Yeniden denemeleri etkinleştirme ve devre dışı bırakma

GCP Konsolunu Kullanma

GCP Konsolu'nda yeniden denemeleri aşağıdaki şekilde etkinleştirebilir veya devre dışı bırakabilirsiniz:

  1. Bulut Platformu Konsolu'ndaki Bulut İşlevlerine Genel Bakış sayfasına gidin.

  2. İşlev oluştur 'u tıklayın. Alternatif olarak, ayrıntılar sayfasına gitmek için mevcut bir işlevi tıklayın ve Düzenle'yi tıklayın.

  3. İşleviniz için gerekli alanları doldurun.

  4. Tetikleyici alanının, Cloud Pub/Sub veya Cloud Storage gibi olay tabanlı bir tetikleyici türüne ayarlandığından emin olun.

  5. Diğer'i tıklayarak gelişmiş ayarları genişletin.

  6. Başarısızlıkta yeniden dene etiketli kutuyu işaretleyin veya işaretini kaldırın.

fonksiyon kodunda

Firebase için Cloud Functions ile bir işlev için kodda yeniden denemeleri etkinleştirebilirsiniz. Bunu functions.foo.onBar(myHandler); , runWith kullanın ve bir hata ilkesi yapılandırın:

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

Gösterildiği gibi true ayarı, arıza durumunda yeniden denenecek bir işlevi yapılandırır.

En iyi uygulamalar

Bu bölüm, yeniden denemeleri kullanmak için en iyi uygulamaları açıklar.

Geçici hataları işlemek için yeniden denemeyi kullanın

İşleviniz, başarılı yürütmeye kadar sürekli olarak yeniden denendiğinden, yeniden denemeleri etkinleştirmeden önce test yoluyla hatalar gibi kalıcı hataların kodunuzdan kaldırılması gerekir. Yeniden denemeler, kesintili hizmet uç noktası veya zaman aşımı gibi yeniden denemede yüksek bir çözüm olasılığı olan kesintili/geçici hataları işlemek için en iyi şekilde kullanılır.

Sonsuz yeniden deneme döngülerinden kaçınmak için bir bitiş koşulu ayarlayın

Yeniden denemeleri kullanırken işlevinizi sürekli döngüye karşı korumak en iyi uygulamadır. Bunu, 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ıldığında ve bitiş koşulunu değerlendirebildiğinde işe yaradığını unutmayın.

Basit ama etkili bir yaklaşım, belirli bir zamandan daha eski zaman damgalarına sahip olayları atmaktır. Bu, hatalar kalıcı olduğunda veya beklenenden daha uzun ömürlü olduğunda aşırı yürütmelerin önlenmesine yardımcı olur.

Örneğin, bu kod parçacığı, 10 saniyeden eski tüm olayları atar:

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;
}

Sözlerle catch kullanın

İşleviniz yeniden denemeleri etkinleştirdiyse, işlenmeyen herhangi bir hata yeniden denemeyi tetikler. Kodunuzun yeniden denemeyle sonuçlanmaması gereken hataları yakaladığından emin olun.

İşte yapmanız gerekenlere bir örnek:

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

Yeniden denenebilir olaya dayalı işlevleri önemsiz hale getirin

Yeniden denenebilen olaya dayalı işlevler bağımsız olmalıdır. Böyle bir işlevi önemsiz kılmak için bazı genel yönergeler şunlardır:

  • Birçok harici API (Stripe gibi), parametre olarak bir bağımsız anahtar sağlamanıza izin verir. Böyle bir API kullanıyorsanız, bağımsız anahtar olarak olay kimliğini kullanmalısınız.
  • Idempotency, en az bir kez teslimatla iyi çalışır, çünkü yeniden denemeyi güvenli hale getirir. Bu nedenle, güvenilir kod yazmak için genel bir en iyi uygulama, bağımsızlığı yeniden denemelerle birleştirmektir.
  • Kodunuzun dahili olarak bağımsız olduğundan emin olun. Örneğin:
    • Sonucu değiştirmeden mutasyonların birden fazla olabileceğinden emin olun.
    • Durumu değiştirmeden önce bir işlemde veritabanı durumunu sorgulayın.
    • Tüm yan etkilerin kendilerinin önemsiz olduğundan emin olun.
  • Koddan bağımsız olarak işlevin dışında bir işlem denetimi uygulayın. Örneğin, belirli bir olay kimliğinin zaten işlendiğini kaydeden bir yerde ısrar durumu.
  • Bant dışı yinelenen işlev çağrılarıyla ilgilenin. Örneğin, yinelenen işlev çağrılarından sonra temizleyen ayrı bir temizleme işlemine sahip olun.