Eşzamansız işlevleri yeniden deneme

Bu belgede, başarısız olduğunda yeniden denemesi için asenkron (HTTPS olmayan) arka plan işlevlerini nasıl isteyeceğiniz açıklanmaktadır.

Olay odaklı işlevler neden tamamlanamaz?

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

Daha yaygın olarak, olaya dayalı bir işlev, işlev kodunun kendisinde oluşan hatalardan dolayı başarıyla tamamlanamayabilir. Bunun olası nedenleri şunlardır:

  • İşlevde bir hata var ve çalışma zamanı bir istisna atıyor.
  • İş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 atar (örneğin, bir parametre doğrulama işlemini geçemediğinde).
  • Node.js işlevi, reddedilen bir promise döndürür veya bir geri çağırma işlevine null olmayan bir değer iletir.

Yukarıdaki durumlardan herhangi birinde işlev yürütülmeyi durdurur ve hata döndürür. Mesajları üreten etkinlik tetikleyicilerinin, işlevinizin ihtiyaçlarını karşılamak için özelleştirebileceğiniz yeniden deneme politikaları vardır.

Yeniden deneme semantiği

Cloud Functions, bir etkinlik kaynağı tarafından yayınlanan her etkinlik için etkinlik odaklı bir işlevin en az bir kez yürütülmesini sağlar. Yeniden denemelerin yapılandırılma şekli, işlevinizi nasıl oluşturduğunuza bağlıdır:

  • Google Cloud Console'da veya Cloud Run Admin API ile oluşturulan işlevler için etkinlik tetikleyicilerini ayrı olarak oluşturup yönetmeniz gerekir. Tetikleyicilerin, işlevinizin ihtiyaçlarına göre özelleştirebileceğiniz varsayılan yeniden deneme davranışları vardır.
  • Cloud Functions v2 API ile oluşturulan işlevler, Pub/Sub konuları veya Eventarc tetikleyicileri gibi gerekli etkinlik tetikleyicilerini dolaylı olarak oluşturur. Varsayılan olarak, bu tetikleyiciler için yeniden denemeler devre dışıdır ve Cloud Functions v2 API kullanılarak yeniden etkinleştirilebilir.

Cloud Run ile oluşturulan olay odaklı işlevler

Google Cloud Console'da veya Cloud Run Admin API ile oluşturulan işlevler, etkinlik tetikleyicilerini ayrı olarak oluşturmanızı ve yönetmenizi gerektirir. Her tetikleyici türünün varsayılan davranışını incelemenizi önemle tavsiye ederiz:

Cloud Functions v2 API ile oluşturulan etkinlik odaklı işlevler

Cloud Functions v2 API kullanılarak oluşturulan işlevler (ör. Cloud Functions gcloud CLI, REST API veya Terraform kullanılarak) sizin adınıza etkinlik tetikleyicileri oluşturur ve yönetir. Varsayılan olarak, bir işlev çağrısı hatayla sonlandırılırsa işlev yeniden ç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 bir işlev çağrısını başarılı bir şekilde tamamlanana veya yeniden deneme aralığının süresi dolana kadar yeniden dener.

Bir işlev için yeniden denemeler etkinleştirilmediğinde (varsayılan ayar budur) işlev her zaman başarıyla yürütüldüğünü bildirir ve günlüklerinde 200 OK yanıt kodları görünebilir. Bu durum, işlev bir hatayla karşılaşsa bile gerçekleşir. İşleviniz bir hatayla karşılaştığında bunu açıkça belirtmek için hataları uygun şekilde bildirdiğinizden emin olun.

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

Yeniden denemeleri konsoldan yapılandırma

Yeni bir işlev oluşturuyorsanız:

  1. İşlev Oluştur ekranındaki Tetikleyici bölümünde, işleviniz için tetikleyici görevi görecek etkinlik türünü seçin.
  2. Yeniden denemeleri etkinleştirmek için Başarısız olması durumunda yeniden dene onay kutusunu işaretleyin.

Mevcut bir işlevi güncelliyorsanız:

  1. Cloud Functions Genel Bakış sayfasında, güncellediğiniz işlevin adını tıklayarak İşlev ayrıntıları ekranını açın, ardından menü çubuğundan Düzenle'yi seçerek Tetikleyici bölmesini görüntüleyin.
  2. Yeniden denemeleri etkinleştirmek veya devre dışı bırakmak için Başarısız olması durumunda yeniden dene onay kutusunu işaretleyin veya kutunun işaretini kaldırın.

İşlev kodunuzdan yeniden denemeleri yapılandırma

Cloud Functions for Firebase ile bir işlevin kodunda yeniden denemeleri etkinleştirebilirsiniz. functions.foo.onBar(myHandler); gibi bir arka plan işlevi için bunu yapmak üzere runWith kullanın ve bir hata politikası yapılandırın:

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

true değerini gösterildiği gibi ayarlamak, işlevi başarısızlık durumunda yeniden deneyecek şekilde yapılandırır.

Tekrar deneme penceresi

2. nesil işlevler için bu yeniden deneme aralığının süresi 24 saattir. 1. nesil işlevler için süre 7 gün sonra sona erer. Cloud Functions, yeni oluşturulan etkinlik odaklı işlevleri, 10 ila 600 saniye arasında artan bir geri yükleme süresiyle eksponansiyel geri yükleme stratejisi kullanarak yeniden dener. Bu politika, yeni işlevleri ilk kez dağıttığınızda uygulanır. Bu değişiklik, işlevleri yeniden dağıtsanız bile bu sürüm notunda açıklanan değişiklikler yürürlüğe girmeden önce ilk kez dağıtılan mevcut işlevlere geriye dönük olarak uygulanmaz.

En iyi uygulamalar

Bu bölümde, yeniden denemelerin kullanılmasıyla ilgili en iyi uygulamalar açıklanmaktadır.

Geçici hataları işlemek için yeniden deneme özelliğini kullanma

İşleviniz başarılı bir şekilde yürütülene kadar sürekli olarak yeniden denendiği için yeniden denemelerin etkinleştirilmesinden önce hatalar gibi kalıcı hataların test yoluyla kodunuzdan kaldırılması gerekir. Yeniden denemelerin en iyi kullanımı, yeniden deneme sonrasında çözüm olasılığı yüksek olan aralıklı veya geçici hatalar (ör. kararsız hizmet uç noktası veya zaman aşımı) içindir.

Sonsuz yeniden deneme döngülerini önlemek için bir bitiş koşulu ayarlayın

Yeniden deneme özelliğini 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ılırsa ve bitiş koşulunu değerlendirebiliyorsa çalıştığını unutmayın.

Basit ancak etkili bir yaklaşım, belirli bir zamandan eski zaman damgaları olan etkinlikleri atmaktır. Bu, hatalar kalıcı olduğunda veya beklenenden daha uzun süre devam ettiğinde aşırı yürütme işlemlerinin yapılmasını önlemeye yardımcı olur.

Örneğin, bu kod snippet'i 10 saniyeden eski tüm etkinlikleri 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;
}

catch'ü Promises ile kullanma

İşlevinizde yeniden deneme etkinse ele alınmayan tüm hatalar yeniden deneme tetiklenir. Kodunuzun, yeniden denemeyle sonuçlanmaması gereken tüm hataları yakaladığından emin olun.

Yapmanız gerekenleri aşağıdaki örnekte görebilirsiniz:

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

Tekrarlanabilir olay odaklı işlevleri tekil hale getirme

Yeniden denenebilen olay odaklı işlevler idempotent olmalıdır. Bu tür bir işlevi tekil hale getirmeyle ilgili bazı genel yönergeler aşağıda verilmiştir:

  • Birçok harici API (ör. Stripe), parametre olarak tekilleştirme anahtarı sağlamanıza olanak tanır. Bu tür bir API kullanıyorsanız tekilleştirme anahtarı olarak etkinlik kimliğini kullanmanız gerekir.
  • Tekrar denemeyi güvenli hale getirdiği için tekilleştirme, en az bir kez yayınlama ile iyi çalışır. Bu nedenle, güvenilir kod yazmayla ilgili genel bir en iyi uygulama, tekilliği yeniden denemelerle birleştirmektir.
  • Kodunuzun dahili olarak tekil olduğundan emin olun. Örneğin:
    • Sonuçları değiştirmeden mutasyonların birden fazla kez gerçekleşebildiğinden emin olun.
    • Durumu değiştirmeden önce bir işlemde veritabanı durumunu sorgulayın.
    • Tüm yan etkilerin de idempotent olduğundan emin olun.
  • İşlevin dışında, koddan bağımsız bir işlem denetimi uygulayın. Örneğin, belirli bir etkinlik kimliğinin daha önce işlendiğini kaydeden bir yerde durumu sürdürün.
  • Bant dışı yinelenen işlev çağrılarıyla ilgilenme. Örneğin, yinelenen işlev çağrılarından sonra temizlik yapan ayrı bir temizleme işlemi kullanı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ğıdakilerin herhangi bir kombinasyonunu ayarlayabilirsiniz:

  • Yeniden deneme aralığını 7 günden en az 10 dakikaya kısaltın.
  • Üslü geri çekilme yeniden deneme stratejisi için minimum ve maksimum geri çekilme süresini değiştirin.
  • Yeniden deneme stratejisini hemen yeniden deneyecek şekilde değiştirin.
  • Geçersiz konu yapılandırın.
  • Maksimum ve minimum teslimat denemesi sayısını ayarlayın.

Yeniden deneme politikasını yapılandırmak için:

  1. Bir HTTP işlevi yazın.
  2. Hedef olarak işlevin URL'sini belirterek Pub/Sub aboneliği oluşturmak için Pub/Sub API'yi kullanın.

Pub/Sub'u doğrudan yapılandırma hakkında daha fazla bilgi için Pub/Sub'un hataları ele almayla ilgili belgelerine bakın.