Dayanıklı İşlevler'de sürüm oluşturma (Azure İşlevleri)
Bir uygulamanın ömrü boyunca işlevlerin eklenmesi, kaldırılması ve değiştirilmesi kaçınılmazdır. Dayanıklı İşlevler, zincirleme işlevlerini daha önce mümkün olmayan yollarla birbirine bağlamaya olanak tanır ve bu zincirleme, sürüm oluşturma işlemini nasıl yönetebileceğinizi etkiler.
Hataya neden olan değişiklikleri işleme
Farkında olmanız gereken hataya neden olan değişikliklerin birkaç örneği vardır. Bu makalede en yaygın olanlar ele alınmaktadır. Bunların ardındaki ana tema, hem yeni hem de mevcut işlev düzenlemelerinin işlev kodundaki değişikliklerden etkilenmesidir.
Etkinlik veya varlık işlevi imzalarını değiştirme
İmza değişikliği, işlevin adında, girişinde veya çıkışında yapılan bir değişikliği ifade eder. Bir etkinlik veya varlık işlevinde bu tür bir değişiklik yapılırsa, buna bağlı olan herhangi bir düzenleyici işlevi bozulabilir. Bu özellikle tür açısından güvenli diller için geçerlidir. Düzenleyici işlevini bu değişikliğe uyum sağlamak için güncelleştirirseniz mevcut uçuş içi örnekleri bozabilirsiniz.
Örneğin, aşağıdaki orchestrator işlevine sahip olduğumuzu varsayalım.
[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
bool result = await context.CallActivityAsync<bool>("Foo");
await context.CallActivityAsync("Bar", result);
}
Bu basit işlev Foo'nun sonuçlarını alır ve Çubuk'a geçirir. Daha çeşitli sonuç değerlerini desteklemek için Foo'nun boole değerini Dize olarak değiştirmemiz gerektiğini varsayalım. Sonuç şuna benzer:
[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
string result = await context.CallActivityAsync<string>("Foo");
await context.CallActivityAsync("Bar", result);
}
Bu değişiklik orchestrator işlevinin tüm yeni örnekleri için düzgün çalışır ancak tüm uçuş içi örnekleri bozabilir. Örneğin, bir düzenleme örneğinin adlı Foo
bir işlevi çağırdığı durumu göz önünde bulundurun, boole değerini geri alır ve ardından denetim noktaları alır. İmza değişikliği bu noktada dağıtılırsa, denetim noktası yapılan örnek çağrıyı Foo
sürdürür ve yeniden yürütürken hemen başarısız olur. Bu hatanın nedeni, geçmiş tablosundaki sonucun bir Boole değeri olması ancak yeni kodun dize değeri olarak seri durumdan çıkarmaya çalışması ve bunun sonucunda tür açısından güvenli diller için beklenmeyen davranış ve hatta çalışma zamanı özel durumu ortaya çıkar.
Bu örnek, bir işlev imzası değişikliğinin var olan örnekleri bozabilmesinin birçok farklı yönteminden yalnızca biridir. Genel olarak, bir düzenleyicinin işlevi çağırma şeklini değiştirmesi gerekiyorsa, değişiklik büyük olasılıkla sorunlu olacaktır.
Düzenleyici mantığını değiştirme
Sürüm oluşturma sorunlarının diğer sınıfı, orchestrator işlev kodunun uçuş içi örneklerin yürütme yolunu değiştirecek şekilde değiştirilmesinden gelir.
Aşağıdaki orchestrator işlevini göz önünde bulundurun:
[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
bool result = await context.CallActivityAsync<bool>("Foo");
await context.CallActivityAsync("Bar", result);
}
Şimdi mevcut iki işlev çağrısı arasına yeni bir işlev çağrısı eklemek için bir değişiklik yapmak istediğinizi varsayalım.
[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
bool result = await context.CallActivityAsync<bool>("Foo");
if (result)
{
await context.CallActivityAsync("SendNotification");
}
await context.CallActivityAsync("Bar", result);
}
Bu değişiklik, Foo ve Bar arasında SendNotification'a yeni bir işlev çağrısı ekler. İmza değişikliği yok. Mevcut bir örnek Çubuk çağrısından devam ettiğinde sorun oluşur. Yeniden yürütme sırasında, Foo'ya yapılan özgün çağrı döndürdüyse true
orchestrator replay, yürütme geçmişinde bulunmayan SendNotification'ı çağırır. Çalışma zamanı bu tutarsızlığı algılar ve Bar çağrısı görmeyi beklediğinde SendNotification çağrısıyla karşılaştığından belirlenemeyen bir düzenleme hatası oluşturur. Dayanıklı süreölçerler oluşturma, dış olayları bekleme, alt düzenleme çağırma gibi diğer dayanıklı işlemlere API çağrıları eklerken de aynı tür bir sorun oluşabilir.
Azaltma stratejileri
Sürüm oluşturma zorluklarıyla başa çıkmaya yönelik stratejilerden bazıları şunlardır:
- Hiçbir şey yapma (önerilmez)
- Tüm uçuş içi örnekleri durdurma
- Yan yana dağıtımlar
Hiçbir şey yapma
Sürüm oluşturmanın basit yaklaşımı hiçbir şey yapmamak ve uçuş içi düzenleme örneklerinin başarısız olmasına izin vermektir. Değişikliğin türüne bağlı olarak aşağıdaki hata türleri oluşabilir.
- Düzenleme işlemleri belirlenemeyen bir düzenleme hatasıyla başarısız olabilir.
- Düzenleme işlemleri süresiz olarak takılabilir ve durumu
Running
bildirebilir. - Bir işlev kaldırılırsa, onu çağırmaya çalışan herhangi bir işlev hatayla başarısız olabilir.
- Bir işlev çalıştırılacak şekilde zamanlandıktan sonra kaldırılırsa, uygulama Dayanıklı Görev Çerçevesi altyapısında düşük düzeyli çalışma zamanı hatalarıyla karşılaşabilir ve bu da ciddi performans düşüşüyle sonuçlanabilir.
Bu olası hatalar nedeniyle "hiçbir şey yapma" stratejisi önerilmez.
Tüm uçuş içi örnekleri durdurma
Bir diğer seçenek de tüm uçuş içi örnekleri durdurmaktır. Dayanıklı İşlevler için varsayılan Azure Depolama sağlayıcısını kullanıyorsanız, iç denetim kuyruğunun ve workitem-queue kuyruklarının içeriği temizlenerek tüm örneklerin durdurulması gerçekleştirilebilir. Alternatif olarak işlev uygulamasını durdurabilir, bu kuyrukları silebilir ve uygulamayı yeniden başlatabilirsiniz. Uygulama yeniden başlatıldıktan sonra kuyruklar otomatik olarak yeniden oluşturulur. Önceki düzenleme örnekleri süresiz olarak "Çalışıyor" durumunda kalabilir, ancak günlüklerinizi hata iletileriyle karmaşık hale getirmez veya uygulamanıza zarar vermeyecektir. Bu yaklaşım, yerel geliştirme de dahil olmak üzere hızlı prototip geliştirme için idealdir.
Not
Bu yaklaşım, temel alınan depolama kaynaklarına doğrudan erişim gerektirir ve benim Dayanıklı İşlevler tarafından desteklenen tüm depolama sağlayıcıları için uygun değildir.
Yan yana dağıtımlar
Hataya neden olan değişikliklerin güvenli bir şekilde dağıtılmasını sağlamanın en başarısızlığa dayanıklı yolu, bunları eski sürümlerinizle yan yana dağıtmaktır. Bu, aşağıdaki tekniklerden herhangi biri kullanılarak yapılabilir:
- Tüm güncelleştirmeleri tamamen yeni işlevler olarak dağıtın ve mevcut işlevleri olduğu gibi bırakın. Yeni işlev sürümlerinin çağıranlarının özyinelemeli olarak güncelleştirilmesiyle ilgili karmaşıklık nedeniyle bu genellikle önerilmez.
- Tüm güncelleştirmeleri farklı bir depolama hesabıyla yeni bir işlev uygulaması olarak dağıtın.
- İşlev uygulamasının yeni bir kopyasını aynı depolama hesabıyla ancak güncelleştirilmiş görev hub'ı adıyla dağıtın. Bu, uygulamanızın yeni sürümü tarafından kullanılabilecek yeni depolama yapıtlarının oluşturulmasına neden olur. Uygulamanızın eski sürümü, önceki depolama yapıtları kümesi kullanılarak yürütülmeye devam eder.
Yan yana dağıtım, işlev uygulamalarınızın yeni sürümlerini dağıtmak için önerilen tekniktir.
Not
Yan yana dağıtım stratejisine yönelik bu kılavuz Azure Depolama'ya özgü terimleri kullanır, ancak genellikle desteklenen tüm Dayanıklı İşlevler depolama sağlayıcıları için geçerlidir.
Dağıtım yuvaları
Azure İşlevleri veya Azure App Service'da yan yana dağıtımlar yaparken, işlev uygulamasının yeni sürümünü yeni bir Dağıtım yuvasına dağıtmanızı öneririz. Dağıtım yuvaları, işlev uygulamanızın birden çok kopyasını yalnızca biri etkin üretim yuvası olarak yan yana çalıştırmanızı sağlar. Yeni düzenleme mantığını mevcut altyapınızda kullanıma sunmaya hazır olduğunuzda, yeni sürümü üretim yuvasına değiştirmek kadar basit olabilir.
Not
Bu strateji, düzenleyici işlevleri için HTTP ve web kancası tetikleyicilerini kullandığınızda en iyi şekilde çalışır. Kuyruklar veya Event Hubs gibi HTTP olmayan tetikleyiciler için tetikleyici tanımı, değiştirme işleminin bir parçası olarak güncelleştirilen bir uygulama ayarından türetilmelidir .