Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bir hizmet kullanılamaz duruma geldiğinde veya meşgul olduğunda, sık sık yapılan istemci yeniden denemeleri hizmetin kurtarılmasını engelleyebilir ve sorunu kötüleştirebilir. İstekler genellikle yalnızca sınırlı bir süre için geçerli kaldığından, süresiz olarak yeniden deneme işlemi etkisizdir.
Bağlam ve sorun
Bulutta, hizmetler bazen sorunlarla karşılaşır ve istemciler tarafından kullanılamaz duruma gelir ya da azaltma veya hız sınırları uygular. İstemcilerin hizmetlerle başarısız bağlantıları yeniden denemesi iyi bir uygulama olsa da, çok sık veya çok uzun süre yeniden denememelidir. Hizmetin henüz normale dönmemiş olmasından dolayı, kısa bir süre içinde yeniden denemelerin başarılı olma ihtimali düşüktür. Kurtarma sırasında aşırı bağlantı girişimleri hizmeti bunaltabilir ve özgün sorunu yoğunlaştırabilir. Bu duruma bazen gümbürdenen sürü denir.
Aşağıdaki örnekte, istemcinin sunucu tabanlı API'ye bağlandığı bir senaryo gösterilmektedir. İstek başarılı olmazsa, istemci hemen isteği yeniden dener ve sonsuza kadar yeniden denemeye devam eder. Bu tür davranışlar genellikle bu örnekten daha hafiftir, ancak aynı ilke geçerlidir.
public async Task<string> GetDataFromServer()
{
while(true)
{
var result = await httpClient.GetAsync(string.Format("http://{0}:8080/api/...", hostName));
if (result.IsSuccessStatusCode) break;
}
// ... Process result.
}
Çözüm
İstemci uygulamaları, yeniden deneme saldırılarını önlemek için en iyi yöntemleri izlemelidir.
Yeniden deneme denemesi sayısını ve süresini sınırlayın.
while(true)Döngü yazmak basit görünebilir, ancak genellikle uzun bir süre yeniden denemek istemezsiniz. İsteğin başlatılmasına neden olan koşullar büyük olasılıkla değişmiştir. Çoğu uygulamanın yalnızca birkaç saniye veya dakika boyunca yeniden denemesi gerekir.Yeniden deneme girişimleri arasında duraklatın ve bekleme süresini artırın. Bir hizmet kullanılamıyorsa, hemen yeniden denemenin başarılı olma olasılığı düşüktür. Örneğin üstel geri alma stratejisini kullanarak girişimler arasındaki süreyi kademeli olarak artırın.
Hizmet hatalarını zarifçe işleyin. Hizmet yanıt vermezse, girişimi iptal edip etmeyeceğinizi belirleyin ve bileşeninizin kullanıcısına veya çağırana bir hata döndürin. Uygulamanızı tasarlarken bu hata senaryolarını göz önünde bulundurun.
Devre Kesici desenini kullanın. Bu düzen, yeniden deneme fırtınalarını önlemeye yardımcı olmak için özel olarak tasarlanmıştır.
Yanıt üst bilgilerini dikkate alın. Sunucu bir
retry-afteryanıt üst bilgisi sağlıyorsa, belirtilen süre geçene kadar yeniden denemeyin.Azure hizmetleriyle iletişim kurmak için resmi SDK'ları kullanın. Bu SDK'lar genellikle yerleşik yeniden deneme ilkelerine ve yeniden deneme fırtınalarına neden olma veya bunlara katkıda bulunmaya karşı koruma sağlar. SDK'sı olmayan bir hizmetle iletişim kurarsanız veya SDK yeniden deneme mantığını yanlış işlerse, JavaScript'in yeniden deneme mantığınızı doğru şekilde işlemesi ve kodu kendiniz yazmaktan kaçınması için .NET veya retry için Polly gibi bir kitaplık kullanmayı göz önünde bulundurun.
Kullanılabilir olduğunda bir soyutlama katmanı kullanın. Bunu destekleyen bir ortam kullanıyorsanız, giden çağrılar göndermek için bir hizmet ağı veya başka bir soyutlama katmanı kullanın. Genellikle Daprgibi bu araçlar yeniden deneme ilkelerini destekler ve yinelenen denemelerden sonra geri dönme gibi en iyi yöntemleri otomatik olarak izler. Bu yaklaşım, yeniden deneme kodunu kendiniz yazma gereğini ortadan kaldırır.
İstekleri toplu işleme ve kullanılabilir olduğunda istek havuzlamayı göz önünde bulundurun. Birçok SDK, istek toplu işlemini ve bağlantı havuzunu sizin yerinize işler ve bu da uygulamanızın yaptığı toplam giden bağlantı girişimi sayısını azaltır. Ancak bu bağlantıları çok sık yeniden denemekten kaçının.
Hizmetler de kendilerini yeniden deneme fırtınalarına karşı korumalıdır.
Olaylar sırasında bağlantıları engellemek için bir ağ geçidi katmanı ekleyin. Bu yaklaşım Bulkhead desenini izler. Azure Azure Front Door, Azure Application Gateway ve Azure API Management gibi farklı çözüm türleri için birçok ağ geçidi hizmeti sağlar.
Ağ geçidinizdeki istekleri kısıtlama. Bu yaklaşım, arka uç bileşenlerinin aşırı isteklerden etkilenmesini önler.
İstemcilere sinyal gönderin. Hız kesme sırasında, istemcilerin bağlantılarını yenileyecekleri zamanı anlamalarına yardımcı olmak için bir
retry-afterüst bilgisi geri gönderin. İstemcilerin bu üst bilgileri yerine getirmesi gerekmez, ancak birçoğu bunu yapar.
Hususlar
Hata türlerini anlama. Bazı hata türleri hizmet hatasını göstermez, bunun yerine istemciden geçersiz bir istek olduğunu gösterir. Örneğin, bir istemci uygulaması bir
400 Bad Requesthata yanıtı alırsa, sunucu isteğinizin geçerli olmadığını size zaten bildirdiğinden aynı isteği yeniden denemek büyük olasılıkla yardımcı olmaz.Uygun yeniden deneme süresini tanımlayın. İstemciler, bağlantıları yeniden kullanmak için en uygun süreyi dikkate almalıdır. Zaman penceresi, iş gereksinimleriyle ve bir kullanıcıya veya arayana makul bir şekilde hata döndürebilme özelliğiyle uyumlu olmalıdır. Çoğu uygulamanın yalnızca birkaç saniye veya dakika boyunca yeniden denemesi gerekir.
Sorunu algılama
İstemci açısından bakıldığında, bu sorunun belirtileri çok uzun yanıt veya işlem sürelerini ve bağlantıyı yeniden deneme girişimlerinin tekrarlandığını gösteren telemetriyi içerebilir.
Hizmet açısından bakıldığında, bu sorunun belirtileri kısa bir süre içinde bir istemciden gelen birkaç isteği veya kesintilerden kurtarılırken tek bir istemciden gelen birkaç isteği içerebilir. Bir hizmet, bir arızadan sonra da kendini toparlamakta zorlanabilir. Veya bir hizmette hata onarımı sonrasında devam eden art arda hatalar olabilir.
Örnek tanılama
Aşağıdaki bölümlerde hem istemci hem de hizmet perspektiflerinden olası yeniden deneme fırtınasını algılamaya yönelik bir yaklaşım gösterilmektedir.
İstemci telemetrisi kullanarak desenleri tanımlama
Application Insights uygulamalardan telemetri kaydeder ve bu verileri sorgulama ve görselleştirme için kullanılabilir hale getirir. Giden bağlantıları bağımlılık olarak izler ve bir istemcinin aynı hizmete birkaç giden istekte bulunduğu zamanları belirlemek için kullanıcıların bu bilgilere erişmesine ve bu bilgilere grafik oluşturmasına olanak tanır.
Aşağıdaki ekran görüntüsünde, Application Insights portalındaki Ölçümler sekmesindeki bir grafik gösterilmektedir. Uzak bağımlılık adına göre bölünmüş Bağımlılık hataları ölçümünü gösterir. Bu senaryoda, kısa bir süre içinde bir bağımlılıkla 21.000'den fazla başarısız bağlantı girişimi vardır.
Sunucu telemetrisi kullanarak desenleri tanımlama
Sunucu uygulamaları tek bir istemciden çok sayıda bağlantı algılayabilir. Aşağıdaki örnekte, Azure Front Door bir uygulama için ağ geçidi görevi görür ve tüm istekleri bir Log Analytics çalışma alanında kaydetmek üzere yapılandırılmıştır.
Son gün içinde uygulamaya çok sayıda istek gönderen istemci IP adreslerini tanımlamak için Log Analytics'de aşağıdaki Kusto sorgusunu çalıştırın.
AzureDiagnostics
| where ResourceType == "FRONTDOORS" and Category == "FrontdoorAccessLog"
| where TimeGenerated > ago(1d)
| summarize count() by bin(TimeGenerated, 1h), clientIp_s
| order by count_ desc
Bu sorguyu yeniden deneme fırtınası sırasında çalıştırırsanız, tek bir IP adresinden çok sayıda bağlantı girişimi gösterilir.