Düzenle

Aracılığıyla paylaş


Mikro hizmetler için hizmetler arası iletişim tasarlama

Azure DevOps

Mikro hizmetler arasındaki iletişim verimli ve sağlam olmalıdır. Tek bir iş etkinliğini tamamlamak için etkileşim kuran çok sayıda küçük hizmetle bu bir zorluk olabilir. Bu makalede, zaman uyumsuz mesajlaşma ile zaman uyumlu API'ler arasındaki dengeleri inceleyeceğiz. Daha sonra, dayanıklı hizmetler arası iletişim tasarlamanın bazı zorluklarına göz atacağız.

Zorluklar

Hizmetten hizmete iletişimden kaynaklanan başlıca zorluklardan bazıları aşağıdadır. Bu makalenin devamında açıklanan hizmet kafesleri, bu zorlukların çoğunu ele almak için tasarlanmıştır.

Dayanıklılık. Herhangi bir mikro hizmetin onlarca, hatta yüzlerce örneği olabilir. Bir örnek çeşitli nedenlerle başarısız olabilir. Donanım hatası veya VM yeniden başlatma gibi düğüm düzeyinde bir hata olabilir. Bir örnek kilitlenebilir veya isteklere boğulabilir ve yeni istekleri işleyemeyebilir. Bu olaylardan herhangi biri bir ağ çağrısının başarısız olmasına neden olabilir. Hizmet-hizmet ağ çağrılarının daha dayanıklı hale getirmesine yardımcı olabilecek iki tasarım deseni vardır:

  • Yeniden Deneme. Tek başına giden geçici bir hata nedeniyle bir ağ çağrısı başarısız olabilir. Çağıranın doğru şekilde başarısız olması yerine, genellikle işlemi belirli bir sayıda yeniden denemesi veya yapılandırılmış bir zaman aşımı süresi geçene kadar yeniden denemesi gerekir. Ancak, bir işlem bir kez etkili değilse, yeniden denemeler istenmeyen yan etkilere neden olabilir. Özgün çağrı başarılı olabilir, ancak arayan hiçbir zaman yanıt alamayabilir. Çağıran yeniden denerse, işlem iki kez çağrılabilir. Genellikle POST veya PATCH yöntemlerini yeniden denemek güvenli değildir, çünkü bunların bir kez etkili olacağı garanti edilmez.

  • Devre Kesici. Bekleyen istekler kuyrukta biriktiğinden çok fazla başarısız istek bir performans sorununa neden olabilir. Bu engellenen isteklerde bellek, iş parçacıkları, veritabanı bağlantıları ve benzeri önemli sistem kaynakları bulunabilir ve bu durum da zincirleme hatalara neden olabilir. Devre Kesici düzeni, bir hizmetin başarısız olma olasılığı olan bir işlemi tekrar tekrar denemesini engelleyebilir.

Yük dengeleme. "A" hizmeti "B" hizmetini çağırdığında, isteğin çalışan bir "B" hizmet örneğine ulaşması gerekir. Kubernetes'te kaynak türü, Service bir pod grubu için kararlı bir IP adresi sağlar. Hizmetin IP adresine yönelik ağ trafiği, iptable kuralları aracılığıyla bir pod'a iletilir. Varsayılan olarak, rastgele bir pod seçilir. Hizmet ağı (aşağıya bakın) gözlemlenen gecikme süresine veya diğer ölçümlere göre daha akıllı yük dengeleme algoritmaları sağlayabilir.

Dağıtılmış izleme. Tek bir işlem birden çok hizmete yayılabilir. Bu, sistemin genel performansını ve sistem durumunu izlemeyi zorlaştırabilir. Her hizmet günlükler ve ölçümler oluştursa bile, bunları birbirine bağlamanın bir yolu olmadan sınırlı kullanımdadır. Günlüğe kaydetme ve izleme makalesinde dağıtılmış izleme hakkında daha fazla bilgi verilmektedir, ancak burada bunu bir sınama olarak belirteceğiz.

Hizmet sürümü oluşturma. Bir ekip bir hizmetin yeni bir sürümünü dağıttığında, buna bağımlı olan diğer hizmetleri veya dış istemcileri bozmaktan kaçınması gerekir. Ayrıca, bir hizmetin birden çok sürümünü yan yana çalıştırmak ve istekleri belirli bir sürüme yönlendirmek isteyebilirsiniz. Bu sorunla ilgili daha fazla bilgi için bkz . API Sürüm Oluşturma .

TLS şifrelemesi ve karşılıklı TLS kimlik doğrulaması. Güvenlik nedenleriyle, hizmetler arasındaki trafiği TLS ile şifrelemek ve arayanların kimliğini doğrulamak için karşılıklı TLS kimlik doğrulaması kullanmak isteyebilirsiniz.

Zaman uyumlu ve zaman uyumsuz mesajlaşma karşılaştırması

Mikro hizmetlerin diğer mikro hizmetlerle iletişim kurmak için kullanabileceği iki temel mesajlaşma düzeni vardır.

  1. Zaman uyumlu iletişim. Bu düzende bir hizmet, HTTP veya gRPC gibi bir protokol kullanarak başka bir hizmetin kullanıma açık olduğu bir API'yi çağırır. Çağıran alıcıdan yanıt beklediğinden bu seçenek zaman uyumlu bir mesajlaşma düzenidir.

  2. Zaman uyumsuz ileti geçirme. Bu düzende, bir hizmet yanıt beklemeden ileti gönderir ve bir veya daha fazla hizmet iletiyi zaman uyumsuz olarak işler.

Zaman uyumsuz G/Ç ile zaman uyumsuz protokol arasında ayrım yapmak önemlidir. Zaman uyumsuz G/Ç, G/Ç tamamlanırken çağıran iş parçacığının engellenmediği anlamına gelir. Bu, performans açısından önemlidir ancak mimari açısından bir uygulama ayrıntısıdır. Zaman uyumsuz protokol, gönderenin yanıt beklemediği anlamına gelir. HTTP istemcisi istek gönderirken zaman uyumsuz G/Ç kullanabilse de HTTP zaman uyumlu bir protokoldür.

Her desen için dengeler vardır. İstek/yanıt iyi anlaşılmış bir paradigmadır, bu nedenle API tasarlamak mesajlaşma sistemi tasarlamaktan daha doğal görünebilir. Ancak, zaman uyumsuz mesajlaşmanın mikro hizmetler mimarisinde yararlı olabilecek bazı avantajları vardır:

  • Azaltılmış kavrama. İletiyi gönderenin tüketici hakkında bilgi sahibi olması gerekmez.

  • Birden çok abone. Pub/sub modeli kullanarak birden çok tüketici olayları almak için abone olabilir. Bkz. Olay temelli mimari stili.

  • Hata yalıtımı. Tüketici başarısız olursa, gönderen yine de ileti gönderebilir. İletiler, tüketici kurtarıldığında alınır. Her hizmetin kendi yaşam döngüsü olduğundan bu özellik özellikle mikro hizmet mimarisinde kullanışlıdır. Bir hizmet, herhangi bir zamanda kullanılamaz duruma gelebilir veya daha yeni bir sürümle değiştirilebilir. Zaman uyumsuz mesajlaşma, aralıklı kapalı kalma süresini işleyebilir. Öte yandan zaman uyumlu API'ler, aşağı akış hizmetinin kullanılabilir olmasını gerektirir veya işlem başarısız olur.

  • Yanıt verme hızı. Yukarı akış hizmeti, aşağı akış hizmetlerinde beklemezse daha hızlı yanıt verebilir. Bu, özellikle mikro hizmet mimarisinde kullanışlıdır. Hizmet bağımlılıkları zinciri varsa (A hizmeti B'yi çağırır, C'yi çağırır vb.), zaman uyumlu çağrıları beklemek kabul edilemez miktarda gecikme süresine neden olabilir.

  • Yük dengeleme. Kuyruk, alıcıların iletileri kendi hızlarında işleyebilmesi için iş yükünü dengelemek için arabellek görevi görebilir.

  • İş akışları. Kuyruklar, iş akışındaki her adımdan sonra iletiye işaret ederek iş akışını yönetmek için kullanılabilir.

Ancak, zaman uyumsuz mesajlaşmayı etkili bir şekilde kullanmanın bazı zorlukları da vardır.

  • Mesajlaşma altyapısıyla bağlantı. Belirli bir mesajlaşma altyapısının kullanılması, bu altyapıyla sıkı bir bağlantının olmasına neden olabilir. Daha sonra başka bir mesajlaşma altyapısına geçmek zor olacaktır.

  • Gecikme süresi. İleti kuyrukları dolarsa bir işlem için uçtan uca gecikme süresi yüksek olabilir.

  • Maliyet. Yüksek aktarım hızlarında mesajlaşma altyapısının parasal maliyeti önemli olabilir.

  • Karmaşıklık. Zaman uyumsuz mesajlaşmayı işlemek önemsiz bir görev değildir. Örneğin yinelenenleri kaldırarak veya işlemleri bir kez etkili hale getirerek yinelenen iletileri işlemeniz gerekir. Zaman uyumsuz mesajlaşmayı kullanarak istek yanıtı semantiği uygulamak da zordur. Yanıt göndermek için başka bir kuyruğa ve ayrıca istek ve yanıt iletilerini ilişkilendirmenin bir yoluna ihtiyacınız vardır.

  • Aktarım hızı. İletiler kuyruk semantiği gerektiriyorsa, kuyruk sistemde bir performans sorununa dönüşebilir. Her ileti için en az bir kuyruk işlemi ve bir dequeue işlemi gerekir. Ayrıca, kuyruk semantiği genellikle mesajlaşma altyapısı içinde bir tür kilitleme gerektirir. Kuyruk yönetilen bir hizmetse, kuyruk kümenin sanal ağı dışında olduğundan ek gecikme süresi olabilir. İletileri toplu işleyerek bu sorunları azaltabilirsiniz, ancak bu da kodu karmaşıklaştırır. İletiler kuyruk semantiği gerektirmiyorsa, kuyruk yerine olay akışı kullanabilirsiniz. Daha fazla bilgi için bkz . Olay temelli mimari stili.

İnsansız Hava Aracıyla Teslimat: Mesajlaşma düzenlerini seçme

Bu çözümde İnsansız Hava AracıYla Teslimat örneği kullanılır. Havacılık ve uçak endüstrileri için idealdir.

Geliştirme ekibi, bu konuları göz önünde bulundurarak İnsansız Hava Aracı Ile Teslimat uygulaması için aşağıdaki tasarım seçimlerini yaptı:

  • Alma hizmeti, istemci uygulamalarının teslimatları zamanlamak, güncelleştirmek veya iptal etmek için kullandığı bir genel REST API'yi kullanıma sunar.

  • Alma hizmeti, Scheduler hizmetine zaman uyumsuz iletiler göndermek için Event Hubs kullanır. Alma için gereken yük dengelemeyi uygulamak için zaman uyumsuz iletiler gereklidir.

  • Hesap, Teslimat, Paket, İnsansız Hava Aracı ve Üçüncü Taraf Taşıma hizmetlerinin tümü dahili REST API'lerini kullanıma sunar. Scheduler hizmeti, kullanıcı isteğini gerçekleştirmek için bu API'leri çağırır. Zaman uyumlu API'leri kullanmanın bir nedeni, Zamanlayıcı'nın aşağı akış hizmetlerinin her birinden yanıt alması gerektiğidir. Aşağı akış hizmetlerinden herhangi birinde hata, işlemin tamamının başarısız olduğu anlamına gelir. Ancak, olası bir sorun arka uç hizmetleri çağrılarak ortaya çıkarılan gecikme süresi miktarıdır.

  • Herhangi bir aşağı akış hizmetinde geçici olmayan bir hata varsa, işlemin tamamı başarısız olarak işaretlenmelidir. Bu durumu işlemek için Scheduler hizmeti Gözetmen'e zaman uyumsuz bir ileti gönderir, böylece Gözetmen telafi işlemleri zamanlayabilir.

  • Teslim hizmeti, istemcilerin bir teslim durumunu almak için kullanabileceği bir genel API'yi kullanıma sunar. API ağ geçidi makalesinde, bir API ağ geçidinin temel alınan hizmetleri istemciden nasıl gizleyebileceğini anlatacağız, bu nedenle istemcinin hangi hizmetlerin hangi API'leri kullanıma sunabileceğini bilmesi gerekmez.

  • İnsansız hava aracı uçuş sırasında İnsansız Hava Aracı hizmeti insansız hava aracının geçerli konumunu ve durumunu içeren olayları gönderir. Teslim hizmeti, bir teslimin durumunu izlemek için bu olayları dinler.

  • Teslimin durumu değiştiğinde, Teslim hizmeti veya DeliveryCompletedgibi DeliveryCreated bir teslim durumu olayı gönderir. Herhangi bir hizmet bu olaylara abone olabilir. Geçerli tasarımda, Teslim Geçmişi hizmeti tek abonedir, ancak daha sonra başka aboneler de olabilir. Örneğin, olaylar gerçek zamanlı bir analiz hizmetine gidebilir. Zamanlayıcı'nın yanıt beklemesi gerekmeyen bir durum olduğundan, daha fazla abone eklemek ana iş akışı yolunu etkilemez.

İnsansız hava aracı iletişiminin diyagramı

Teslimat durumu olaylarının insansız hava aracı konum olaylarından türetildiğini fark edin. Örneğin, bir insansız hava aracı bir teslimat konumuna ulaştığında ve bir paketi teslim ettiğinde, Teslim hizmeti bunu DeliveryCompleted olayına çevirir. Bu, etki alanı modelleri açısından düşünme örneğidir. Daha önce açıklandığı gibi İnsansız Hava Aracı Yönetimi ayrı sınırlanmış bir bağlama aittir. İnsansız hava aracı olayları bir insansız hava aracının fiziksel konumunu gösterir. Öte yandan, teslim olayları, farklı bir işletme varlığı olan teslim durumundaki değişiklikleri temsil eder.

Hizmet ağı kullanma

Hizmet ağı, hizmet-hizmet iletişimlerini işleyen bir yazılım katmanıdır. Hizmet kısa çizgileri, önceki bölümde listelenen endişelerin çoğunu ele almak ve bu endişelerin sorumluluğunu mikro hizmetlerden ve paylaşılan bir katmana taşımak için tasarlanmıştır. Hizmet ağı, kümedeki mikro hizmetler arasındaki ağ iletişimini kesen bir ara sunucu işlevi görür. Şu anda hizmet ağı kavramı, sunucusuz mimariler yerine kapsayıcı düzenleyicileri için geçerlidir.

Not

Hizmet ağı, Büyükelçi deseninin bir örneğidir; uygulama adına ağ istekleri gönderen bir yardımcı hizmettir.

Şu anda Kubernetes'teki bir hizmet ağı için ana seçenekler Linkerd ve Istio'dur. Bu teknolojilerin her ikisi de hızla gelişiyor. Ancak hem Linkerd hem de Istio'da ortak olan bazı özellikler şunlardır:

  • Gözlemlenen gecikme sürelerine veya bekleyen istek sayısına göre oturum düzeyinde yük dengeleme. Bu, Kubernetes tarafından sağlanan katman 4 yük dengelemesi performansını artırabilir.

  • URL yolunu, Konak üst bilgisini, API sürümünü veya diğer uygulama düzeyi kurallarını temel alan katman 7 yönlendirmesi.

  • Başarısız istekleri yeniden deneyin. Hizmet ağı HTTP hata kodlarını anlar ve başarısız istekleri otomatik olarak yeniden deneyebilir. Maksimum gecikme süresini sınırlamak için bu en fazla yeniden deneme sayısını ve zaman aşımı süresini yapılandırabilirsiniz.

  • Devre kesiliyor. Bir örnek istekleri tutarlı bir şekilde başarısız olursa hizmet ağı geçici olarak kullanılamıyor olarak işaretler. Geri alma döneminden sonra örneği yeniden dener. Devre kesiciyi ardışık hata sayısı gibi çeşitli ölçütlere göre yapılandırabilirsiniz.

  • Hizmet ağı, istek hacmi, gecikme süresi, hata ve başarı oranları ve yanıt boyutları gibi hizmetler arası çağrılarla ilgili ölçümleri yakalar. Hizmet ağı, bir istekteki her atlama için bağıntı bilgileri ekleyerek dağıtılmış izlemeyi de etkinleştirir.

  • Hizmet-hizmet çağrıları için karşılıklı TLS Kimlik Doğrulaması.

Hizmet ağı gerekiyor mu? Duruma göre değişir. Hizmet ağı olmadan, bu makalenin başında belirtilen zorlukların her birini göz önünde bulundurmanız gerekir. Yeniden deneme, devre kesici ve dağıtılmış izleme gibi sorunları bir hizmet ağı olmadan çözebilirsiniz, ancak bir hizmet ağı bu endişeleri tek tek hizmetlerin dışına ve ayrılmış bir katmana taşır. Öte yandan, bir hizmet ağı kümenin kurulumuna ve yapılandırmasına karmaşıklık ekler. İstekler artık hizmet ağı ara sunucusu üzerinden yönlendirildiğinden ve ek hizmetler artık kümedeki her düğümde çalıştığından performans etkileri olabilir. Üretimde bir hizmet ağı dağıtmadan önce kapsamlı performans ve yük testi yapmanız gerekir.

Dağıtılmış işlemler

Mikro hizmetlerde yaygın bir zorluk, birden çok hizmete yayılan işlemleri doğru şekilde işlemektir. Bu senaryoda genellikle bir işlemin başarısının tümü veya hiçi olur; katılan hizmetlerden biri başarısız olursa tüm işlemin başarısız olması gerekir.

Dikkate alınması gereken iki durum vardır:

  • Bir hizmet, ağ zaman aşımı gibi geçici bir hatayla karşılaşabilir. Bu hatalar genellikle çağrı yeniden denenerek çözülebilir. Belirli sayıda denemeden sonra işlem yine başarısız olursa, geçici olmayan bir hata olarak kabul edilir.

  • Geçici olmayan bir hata, kendi başına kaybolma olasılığı düşük olan herhangi bir hatadır. Geçici olmayan hatalar, geçersiz giriş gibi normal hata koşullarını içerir. Bunlar ayrıca uygulama kodunda işlenmeyen özel durumları veya bir işlemin kilitlenmesini içerir. Bu tür bir hata oluşursa, iş işleminin tamamı hata olarak işaretlenmelidir. Zaten başarılı olan aynı işlemdeki diğer adımları geri almak gerekebilir.

Geçici olmayan bir hatadan sonra, geçerli işlem kısmen başarısız olmuş durumda olabilir ve burada bir veya daha fazla adım başarıyla tamamlanmıştır. Örneğin, İnsansız Hava Aracı hizmeti zaten bir insansız hava aracı zamanlamışsa, insansız hava aracı iptal edilmelidir. Bu durumda, uygulamanın Telafi İşlemi kullanarak başarılı olan adımları geri alması gerekir. Bazı durumlarda, bu eylemin bir dış sistem tarafından, hatta el ile gerçekleştirilen bir işlemle yapılması gerekir. Tasarımınızda telafi önlemlerinin de hataya tabi olduğunu unutmayın.

İşlemleri telafi etme mantığı karmaşıksa, bu işlemden sorumlu ayrı bir hizmet oluşturmayı göz önünde bulundurun. İnsansız Hava Aracı Ile Teslimat uygulamasında Scheduler hizmeti başarısız işlemleri ayrılmış bir kuyruğa yerleştirir. Gözetmen adlı ayrı bir mikro hizmet, bu kuyruktan okur ve telafi edilmesi gereken hizmetler üzerinde bir iptal API'sini çağırır. Bu, Zamanlayıcı Aracısı Gözetmen düzeninin bir varyasyonudur. Gözetmen hizmeti, kullanıcıyı kısa mesaj veya e-postayla bilgilendirme veya operasyon panosuna uyarı gönderme gibi başka eylemler de gerçekleştirebilir.

Gözetmen mikro hizmetini gösteren diyagram

Scheduler hizmetinin kendisi başarısız olabilir (örneğin, bir düğüm kilitlendiğinden). Bu durumda yeni bir örnek ortaya çıkıp devralabilir. Ancak, devam etmekte olan tüm işlemler sürdürülmelidir.

Bir yaklaşım, iş akışındaki her adım tamamlandıktan sonra bir denetim noktasını dayanıklı bir depoya kaydetmektir. Scheduler hizmetinin bir örneği işlemin ortasında kilitlenirse, yeni bir örnek önceki örneğin kaldığı yerden devam etmek için denetim noktasını kullanabilir. Ancak denetim noktaları yazmak bir performans yükü oluşturabilir.

Bir diğer seçenek de tüm işlemlerin bir kez etkili olacak şekilde tasarlanmasıdır. İlk çağrıdan sonra ek yan etkiler üretmeden birden çok kez çağrılabiliyorsa bir işlem bir kez etkili olur. Temel olarak, aşağı akış hizmeti yinelenen çağrıları yoksaymalıdır, bu da hizmetin yinelenen çağrıları algılayabilmesi gerektiği anlamına gelir. Etkili yöntemler uygulamak her zaman kolay değildir. Daha fazla bilgi için bkz . Etkili işlemler.

Sonraki adımlar

Doğrudan birbiriyle konuşan mikro hizmetler için iyi tasarlanmış API'ler oluşturmak önemlidir.