Aracılığıyla paylaş


Mikro hizmet mimarisinde iletişim

Tavsiye

Bu içerik, .NET Docs veya çevrimdışı olarak okunabilen ücretsiz indirilebilir bir PDF olarak sağlanan Kapsayıcılı .NET Uygulamaları için .NET Mikro Hizmet Mimarisi adlı e-Kitap'tan bir alıntıdır.

.NET Mikro Hizmetler Mimarisi Kapsayıcılı .NET Uygulamaları için eKitabın kapak küçük resmi .

Tek bir işlem üzerinde çalışan monolitik bir uygulamada, bileşenler dil düzeyinde yöntem veya işlev çağrıları kullanarak birbirleri çağırır. Kodla nesne oluşturuyorsanız (örneğin, new ClassName()) bunlar güçlü bir şekilde birleştirilebilir veya somut nesne örnekleri yerine soyutlamalara başvurarak Bağımlılık Ekleme'yi kullanıyorsanız ayrıştırılmış bir şekilde çağrılabilir. Her iki durumda da, nesneler aynı işlem içinde çalışır. Monolitik bir uygulamadan mikro hizmet tabanlı bir uygulamaya geçiş yaparken karşılaşılan en büyük zorluk, iletişim mekanizmasını değiştirmektir. İşlem içi yöntem çağrılarından hizmetlere yapılan RPC çağrılarına doğrudan dönüştürme, dağıtılmış ortamlarda iyi performans göstermeyecek bir sohbete ve verimli olmayan bir iletişime neden olur. Dağıtılmış sistemi düzgün tasarlamanın zorlukları, geliştiricilerin monolitik tasarımlardan dağıtılmış tasarımlara geçerken sıklıkla yaptığı varsayımları listeleyen dağıtılmış bilgi işlemin Hataları olarak bilinen bir canon bile olduğunu yeterince iyi bilinmektedir.

Tek bir çözüm yoktur, ancak birkaç çözüm vardır. Çözümlerden biri, iş mikro hizmetlerini mümkün olduğunca yalıtmadır. Ardından, iç mikro hizmetler arasında eşzamansız iletişim kullanarak, nesneler arasındaki işlem içi iletişimde tipik olan ince ayarlı iletişimi, daha kaba iletişimle değiştirirsiniz. Bunu yapmak için çağrıları gruplandırabilir ve birden çok iç çağrının sonuçlarını toplayan verileri istemciye döndürebilirsiniz.

Mikro hizmet tabanlı bir uygulama, genellikle birden çok sunucu veya konakta (host) bile olabilen, birden çok işlem veya hizmet üzerinde çalışan dağıtılmış bir sistemdir. Her hizmet örneği genellikle bir işlemdir. Bu nedenle, hizmetlerin her hizmetin niteliğine bağlı olarak HTTP, AMQP veya TCP gibi bir ikili protokol kullanarak işlemler arası iletişim protokolü kullanarak etkileşim kurması gerekir.

Mikro hizmet topluluğu "akıllı uç noktalar ve aptal borular" felsefesini teşvik eder. Bu slogan, mikro hizmetler arasında mümkün olduğunca ayrılmış ve tek bir mikro hizmet içinde mümkün olduğunca uyumlu bir tasarım teşvik eder. Daha önce açıklandığı gibi, her mikro hizmet kendi verilerine ve kendi etki alanı mantığına sahiptir. Ancak uçtan uca uygulama oluşturan mikro hizmetler genellikle merkezi iş süreci düzenleyicileri yerine WS* gibi karmaşık protokoller ve esnek olay odaklı iletişimler yerine REST iletişimleri kullanılarak koreografiye alınır.

Yaygın olarak kullanılan iki protokol, çoğunlukla sorgulama yaparken kaynak API'leri ile HTTP istek/yanıtı, ve birden çok mikroservis arasında güncellemeleri iletirken hafif zaman uyumsuz mesajlaşmadır. Bunlar aşağıdaki bölümlerde daha ayrıntılı olarak açıklanmıştır.

İletişim türleri

İstemci ve hizmetler, her biri farklı bir senaryo ve hedefleri hedefleyen birçok farklı iletişim türü aracılığıyla iletişim kurabilir. Başlangıçta, bu tür iletişimler iki eksende sınıflandırılabilir.

İlk eksen, protokolün zaman uyumlu mu yoksa zaman uyumsuz mu olduğunu tanımlar:

  • Zaman uyumlu protokol. HTTP zaman uyumlu bir protokoldür. İstemci bir istek gönderir ve hizmetten yanıt bekler. Bu, istemci kodu yürütmesinin zaman uyumlu (iş parçacığı bloke edilir) veya zaman uyumsuz (iş parçacığı bloke edilmez ve yanıt eninde sonunda bir geri çağırma noktasına ulaşır) olmasından bağımsızdır. Buradaki önemli nokta, protokolün (HTTP/HTTPS) zaman uyumlu olması ve istemci kodunun yalnızca HTTP sunucusu yanıtını aldığında görevine devam etmesidir.

  • Asenkron protokol. AMQP (birçok işletim sistemi ve bulut ortamı tarafından desteklenen bir protokol) gibi diğer protokoller zaman uyumsuz iletiler kullanır. İstemci kodu veya ileti gönderen genellikle yanıt beklemez. Yalnızca bir RabbitMQ kuyruğuna veya başka bir ileti aracısına ileti gönderirken olduğu gibi iletiyi gönderir.

İkinci eksen, iletişimin tek bir alıcısı mı yoksa birden çok alıcısı mı olduğunu tanımlar:

  • Tek alıcı. Her istek tam olarak bir alıcı veya hizmet tarafından işlenmelidir. Bu iletişimin bir örneği , Komut düzenidir.

  • Birden çok alıcı. Her istek sıfırdan birden çok alıcıya kadar işlenebilir. Bu iletişim türü zaman uyumsuz olmalıdır. Olay temelli mimari gibi desenlerde kullanılan yayımlama/abone olma mekanizması buna örnek olarak verilmiştir. Bir olay veri yolu arabirimine ya da ileti aracısına dayalı olan bu yapı, birden çok mikro hizmet arasında veri güncelleştirmelerini olaylar üzerinden yayarken genellikle konular ve abonelikler kullanılarak bir Service Bus veya Azure Service Bus gibi benzer araçlar aracılığıyla uygulanır.

Mikro hizmet tabanlı bir uygulama genellikle bu iletişim stillerinin bir bileşimini kullanır. En yaygın tür, normal bir Web API HTTP hizmeti çağrılırken HTTP/HTTPS gibi zaman uyumlu bir protokolle tek alıcılı iletişimdir. Mikro hizmetler genellikle mikro hizmetler arasındaki zaman uyumsuz iletişim için mesajlaşma protokollerini de kullanır.

Bu eksenleri bilmek iyidir, bu nedenle olası iletişim mekanizmaları hakkında netlik elde edebilirsiniz, ancak mikro hizmetler oluştururken önemli endişeler bunlar değildir. Mikro hizmetler tümleştirildiğinde istemci iş parçacığı yürütmenin zaman uyumsuz yapısı veya seçilen protokolün zaman uyumsuz yapısı önemli noktalar değildir. Önemli olan, aşağıdaki bölümde açıklandığı gibi mikro hizmetlerin bağımsızlığını korurken mikro hizmetlerinizi zaman uyumsuz olarak tümleştirebilmektir.

Asenkron mikrohizmet tümleştirmesi mikrohizmetin özerkliğini sağlar

Belirtildiği gibi, mikro hizmet tabanlı bir uygulama oluştururken önemli nokta, mikro hizmetlerinizi tümleştirme yönteminizdir. İdeal olarak, iç mikro hizmetler arasındaki iletişimi en aza indirmeyi denemelisiniz. Mikro hizmetler arasındaki iletişim sayısı ne kadar az olursa o kadar iyidir. Ancak çoğu durumda mikro hizmetleri bir şekilde tümleştirmeniz gerekir. Bunu yapmanız gerektiğinde buradaki kritik kural, mikro hizmetler arasındaki iletişimin zaman uyumsuz olması gerektiğidir. Bu, belirli bir protokol (örneğin, zaman uyumsuz mesajlaşma veya zaman uyumlu HTTP) kullanmak zorunda olduğunuz anlamına gelmez. Bu yalnızca mikro hizmetler arasındaki iletişimin yalnızca verileri zaman uyumsuz olarak yayarak yapılması gerektiği, ancak ilk hizmetin HTTP isteği/yanıt işleminin bir parçası olarak diğer iç mikro hizmetlere bağımlı olmaması gerektiği anlamına gelir.

Mümkünse, sorgular için bile olsa, hiçbir zaman birden çok mikro hizmet arasındaki zaman uyumlu iletişime (istek/yanıt) bağımlı olmamalıdır. Her mikro hizmetin amacı, uçtan uca uygulamanın parçası olan diğer hizmetler çalışmıyor veya iyi durumda olmasa bile otonom ve istemci tüketicinin kullanımına açık olmaktır. İstemci uygulamasına yanıt verebilmek için bir mikro hizmetten diğer mikro hizmetlere (veri sorgusu için HTTP isteği gerçekleştirmek gibi) çağrı yapmanız gerektiğini düşünüyorsanız, bazı mikro hizmetler başarısız olduğunda dayanıklı olmayacak bir mimariniz vardır.

Ayrıca, Şekil 4-15'in ilk bölümünde gösterildiği gibi HTTP istek zincirleriyle uzun istek/yanıt döngüleri oluştururken olduğu gibi mikro hizmetler arasında HTTP bağımlılıkları olması, mikro hizmetlerinizin otonom olmamasının yanı sıra bu zincirdeki hizmetlerden biri iyi performans göstermediği anda performanslarını da etkiler.

Sorgu istekleri gibi mikro hizmetler arasında zaman uyumlu bağımlılıklar ne kadar çok eklerseniz, istemci uygulamaları için genel yanıt süresi o kadar kötü olur.

Mikro hizmetler arasında üç iletişim türünü gösteren diyagram.

Şekil 4-15. Mikro hizmetler arasındaki iletişimde desenler ve anti-desenler

Yukarıdaki diyagramda gösterildiği gibi, zaman uyumlu iletişimde istemci isteği sunulurken mikro hizmetler arasında bir "istek zinciri" oluşturulur. Bu bir olumsuz model. Zaman uyumsuz iletişimde mikro hizmetler, diğer mikro hizmetlerle iletişim kurmak için asenkron iletiler veya HTTP yoklaması kullanır, ancak istemci isteği anında karşılanır.

Mikro hizmetinizin başka bir mikro hizmette ek bir eylem oluşturması gerekiyorsa, mümkünse, bu eylemi zaman uyumlu olarak ve özgün mikro hizmet isteği ve yanıt işleminin bir parçası olarak gerçekleştirmayın. Bunun yerine, bunu zaman uyumsuz olarak yapın (zaman uyumsuz mesajlaşma veya tümleştirme olayları, kuyruklar vb. kullanarak). Ancak, mümkün olduğunca, eylemi özgün zaman uyumlu istek ve yanıt işleminin bir parçası olarak zaman uyumlu olarak çağırmayın.

Ve son olarak (ve mikro hizmetler geliştirirken sorunların çoğu burada ortaya çıkar), ilk mikro hizmetiniz aslında diğer mikro hizmetlere ait verilere ihtiyaç duyuyorsa, bu veriler için zaman uyumlu istekler yapmayı tercih etmemelisiniz. Bunun yerine, sonunda tutarlılığı sağlayarak (genellikle gelecek bölümlerde açıklandığı gibi tümleştirme olaylarını kullanarak) bu verileri (yalnızca ihtiyacınız olan öznitelikleri) ilk hizmetin veritabanında çoğaltın veya yaygınlaştırın.

Daha önce her mikro hizmet için etki alanı modeli sınırlarını tanımlama bölümünde belirtildiği gibi, bazı verilerin birkaç mikro hizmette çoğaltılması yanlış bir tasarım değildir; tam tersine, bunu yaparken verileri söz konusu ek etki alanının veya Sınırlanmış Bağlamın belirli diline veya koşullarına çevirebilirsiniz. Örneğin, eShopOnContainers uygulamasında kullanıcı verilerinin çoğundan sorumlu olan adlı identity-api bir mikro hizmetiniz ve adlı Userbir varlığınız vardır. Ancak, kullanıcı hakkındaki verileri mikro hizmet içinde Ordering depolamanız gerektiğinde, bunu adlı Buyerfarklı bir varlık olarak depolarsınız. Varlık Buyer, özgün User varlıkla aynı kimliği paylaşır, ancak etki alanı Ordering için gereken birkaç özniteliğe sahip olabilir, tüm kullanıcı profilini değil.

Nihai tutarlılığa sahip olmak için mikro hizmetler arasında verileri zaman uyumsuz olarak iletmek ve yaymak için herhangi bir protokol kullanabilirsiniz. Belirtildiği gibi, tümleştirme olaylarını bir olay veri yolu veya ileti aracısı kullanarak kullanabilir veya bunun yerine diğer hizmetleri yoklayarak HTTP kullanabilirsiniz. Önemli değil. Önemli kural, mikro hizmetleriniz arasında zaman uyumlu bağımlılıklar oluşturmamaktır.

Aşağıdaki bölümlerde mikro hizmet tabanlı bir uygulamada kullanmayı düşünebileceğiniz birden çok iletişim stili açıklanmaktadır.

İletişim stilleri

Kullanmak istediğiniz iletişim türüne bağlı olarak iletişim için kullanabileceğiniz birçok protokol ve seçenek vardır. Zaman uyumlu istek/yanıt tabanlı iletişim mekanizması kullanıyorsanız, özellikle hizmetlerinizi Docker konağı veya mikro hizmet kümesi dışında yayımlıyorsanız HTTP ve REST yaklaşımları gibi protokoller en yaygın olanıdır. Hizmetler arasında dahili olarak (Docker konağınızda veya mikro hizmetler kümenizde) iletişim kuruyorsanız, ikili biçimli iletişim mekanizmalarını da (TCP ve ikili biçim kullanan WCF gibi) kullanmak isteyebilirsiniz. Alternatif olarak, AMQP gibi zaman uyumsuz, ileti tabanlı iletişim mekanizmalarını kullanabilirsiniz.

JSON veya XML gibi birden çok ileti biçimi, hatta daha verimli olabilecek ikili biçimler de vardır. Seçtiğiniz ikili biçim standart değilse, hizmetlerinizi bu biçimi kullanarak genel olarak yayımlamak iyi bir fikir değildir. Mikro hizmetleriniz arasındaki iç iletişim için standart olmayan bir biçim kullanabilirsiniz. Bunu, Docker konağınızdaki veya mikro hizmet kümenizdeki mikro hizmetler (örneğin, Docker düzenleyicileri) veya mikro hizmetlerle konuşan özel istemci uygulamaları arasında iletişim kurarken yapabilirsiniz.

HTTP ve REST ile istek/yanıt iletişimi

İstemci istek/yanıt iletişimini kullandığında bir hizmete istek gönderir, ardından hizmet isteği işler ve bir yanıt gönderir. İstek/yanıt iletişimi, istemci uygulamalarından gerçek zamanlı kullanıcı arabirimi (canlı kullanıcı arabirimi) için verileri sorgulamak için özellikle uygundur. Bu nedenle, bir mikro hizmet mimarisinde, Şekil 4-16'da gösterildiği gibi büyük olasılıkla çoğu sorgu için bu iletişim mekanizmasını kullanacaksınız.

Canlı sorgular ve güncelleştirmeler için istek/yanıt iletişimlerini gösteren diyagram.

Şekil 4-16. HTTP isteği/yanıt iletişimi kullanma (zaman uyumlu veya zaman uyumsuz)

İstemci istek/yanıt iletişimini kullandığında, yanıtın kısa bir süre içinde (genellikle bir saniyeden az veya en fazla birkaç saniye) geleceğini varsayar. Gecikmeli yanıtlar için, sonraki bölümde açıkladığımız farklı bir yaklaşım olan mesajlaşma desenlerine ve mesajlaşma teknolojilerine dayalı zaman uyumsuz iletişim uygulamanız gerekir.

İstek/yanıt iletişimi için popüler bir mimari stil REST'tir. Bu yaklaşım GET, POST ve PUT gibi HTTP fiillerini benimseden HTTP protokolüne dayalıdır ve buna sıkı bir şekilde bağlıdır. REST, hizmet oluştururken en yaygın kullanılan mimari iletişim yaklaşımıdır. ASP.NET Core Web API hizmetleri geliştirirken REST hizmetleri uygulayabilirsiniz.

Arabirim tanımı diliniz olarak HTTP REST hizmetlerini kullanırken ek bir değer vardır. Örneğin, hizmet API'nizi açıklamak için Swagger meta verilerini kullanırsanız, hizmetlerinizi doğrudan bulup kullanabilen istemci saptamaları oluşturan araçları kullanabilirsiniz.

Ek kaynaklar

HTTP tabanlı anında iletme ve gerçek zamanlı iletişim

Diğer bir olasılık da (genellikle REST'ten farklı amaçlar için), ASP.NET SignalR gibi üst düzey çerçeveler ve WebSockets gibi protokollerle gerçek zamanlı ve bire çok iletişimdir.

Şekil 4-17'de gösterildiği gibi, gerçek zamanlı HTTP iletişimi, sunucunun bir istemcinin yeni veri istemesini beklemek yerine, veriler kullanılabilir hale geldikçe bağlı istemcilere içerik gönderen sunucu kodunuz olabileceği anlamına gelir.

SignalR tabanlı gönderim ve gerçek zamanlı iletişimleri gösteren diyagram.

Şekil 4-17. Birden çoğa gerçek zamanlı asenkron mesaj iletişimi

SignalR, bir arka uç sunucusundan istemcilere içerik göndermek için gerçek zamanlı iletişim kurmanın iyi bir yoludur. İletişim gerçek zamanlı olduğundan, istemci uygulamaları değişiklikleri neredeyse anında gösterir. Bu genellikle WebSockets gibi bir protokol tarafından, birçok WebSockets bağlantısı (istemci başına bir bağlantı) kullanılarak işlenir. Tipik bir örnek, bir hizmetin bir spor oyununun puanındaki değişikliği aynı anda birçok istemci web uygulamasına iletmesidir.