Mikro hizmet sistemi mimarileri ağ darboğazlarını nasıl önler?


72

Sunucu uygulamaları için mikro hizmet mimarileri hakkında çok şey okudum ve iç ağ kullanımının bir monolith mimarisine kıyasla nasıl bir darboğaz veya önemli bir dezavantaj olmadığını merak ediyordum.

Kesinlik uğruna, iki terimin yorumlarım:

  1. Monolith mimarisi: Tüm işlevselliği, verileri vb. İşleyen tek bir dilde bir uygulama. Bir yük dengeleyici, her biri uygulamamızın bir örneğini çalıştıran son kullanıcıdan gelen istekleri birden fazla makineye dağıtır.

  2. Mikro hizmet mimarisi: İşlevsellik ve verinin küçük bir bölümünü kullanan birçok uygulama (mikro hizmet). Her bir mikro hizmet, ağ üzerinden erişilen ortak bir API'yi gösterir (aynı makinede süreçler arası iletişim veya paylaşılan belleğin aksine). API çağrıları çoğunlukla sunucuya bir sayfa oluşturmak için yerleştirilir, ancak bu çalışmanın bir kısmı mikroişlemleri tek tek sorgulayan müşteri tarafından yapılır.

Saf hayal gücüme göre, bir mikro hizmet mimarisi aynı makinedeki (bellek ve disk) daha hızlı kaynakların aksine yavaş ağ trafiği kullanıyor gibi görünüyor. İç ağ üzerinden API sorgulamanın genel yanıt süresini yavaşlatmayacağından nasıl emin olabilirsiniz?


Dahili ağ genellikle 1 Gbps, bazen daha hızlı. Bir API'den gelen JSON yanıtının ortalama boyutunu düşünün. Bir saniyede 1 Gbps bağlantı üzerinden bu tür yanıtların kaç tanesi iletilebilir?
Arseni Mourzenko

3
Mikro hizmetlere ihtiyacınız olduğunu düşünüyorsanız - ve belki de! - hazırlanacak iki mükemmel kitap: amazon.com/Building-Microservices-Sam-Newman/dp/1491950358 ve amazon.com/Release-It-Production-Ready-Pragmatic-Programmers/dp/…
Steven A. Lowe

@MainMa sorun bant genişliğinde değil, gecikmeli. Eğer gidiş dönüş yapmanız gerekirse, ne kadar az bant genişliği kullanabileceğinize
şaşıracaksınız

Yanıtlar:


61

Dahili ağlar genellikle 1 Gbps bağlantı veya daha hızlı kullanır. Optik fiber bağlantıları veya bağlar sunucular arasında çok daha yüksek bant genişliğine izin verir. Şimdi bir API'den gelen bir JSON yanıtının ortalama boyutunu düşünün. Bir saniye içinde 1 Gbps bağlantı üzerinden bu tür yanıtların ne kadarı iletilebilir?

Aslında matematik yapalım. 1 Gb / sn, saniyede 131 072 KB'dir. Ortalama bir JSON yanıtı 5 KB ise (bu oldukça fazladır !), Yalnızca bir çift makineyle kablo üzerinden saniyede 26 214 yanıt gönderebilirsiniz . Fena değil, değil mi?

Bu yüzden ağ bağlantısı genellikle tıkanıklık değildir.

Mikro-servislerin diğer bir yönü de kolayca ölçeklenebilmenizdir. Biri API'yi barındıran, diğeri onu kullanan iki sunucu düşünün. Bağlantı bir tıkanıklık olursa, iki sunucu daha ekleyin, performansı iki katına çıkarabilirsiniz.

Bu, saniyede önceki 26 214 yanıtımızın uygulamanın ölçeği için çok küçük olması durumudur. Diğer dokuz çift eklediniz ve şimdi 262 140 yanıt sunabiliyorsunuz.

Fakat haydi sunucularımıza geri dönelim ve bazı karşılaştırmalar yapalım.

  • Veritabanına önbelleğe alınmamış ortalama bir sorgu 10 ms sürerse, saniyede 100 sorgu ile sınırlandırılırsınız. 100 sorgu. 26 214 cevap. Saniyede 26 214 yanıtın hızını elde etmek, büyük miktarda önbelleğe alma ve optimizasyon gerektirir (eğer yanıt gerçekten bir şeyi yapmak istiyorsa, bir veritabanını sorgulamak gibi; "Merhaba Dünya" tarzı cevaplar uygun değildir).

  • Bilgisayarımda, şu anda, Google’ın giriş sayfası için DOMContentLoaded 394 msndı. istek gönderildikten sonra. Bu saniyede 3 istekden az. Programcılar için ana sayfa, 603 ms oldu. istek gönderildikten sonra. Saniyede 2 istek bile yok. Bu arada, 100 Mbps internet bağlantım ve hızlı bir bilgisayarım var: birçok kullanıcı daha uzun süre bekleyecek.

    Darboğaz, sunucular arasındaki ağ hızıysa, bu iki site, sayfayı sunarken farklı API'lere binlerce çağrı yapabilir.

Bu iki olgu ağ muhtemelen teoride senin darboğaz olmayacağını göstermektedir (pratikte, sen darboğaz tam yerini belirlemek için gerçek kriterler ve profil yapmalıyım sizin belirli bir donanım üzerinde barındırılan belirli sistem). Asıl işi yapmak için harcanan zaman (SQL sorguları, sıkıştırma, her neyse) ve sonucu son kullanıcıya göndermek çok daha önemlidir.

Veritabanlarını düşünün

Genellikle, veritabanları bunları kullanarak web uygulamasından ayrı olarak barındırılır. Bu bir endişeye yol açabilir: peki ya uygulamayı barındıran sunucu ile veritabanını barındıran sunucu arasındaki bağlantı hızı?

Aslında bağlantı hızının sorunlu hale geldiği, yani veritabanının kendisi tarafından işlenmesi gerekmeyen ve şu anda erişilebilir olması gereken büyük miktarda veri depoladığınızda (şu anda büyük ikili dosyalar) olması gereken durumlar olduğu anlaşılıyor. Ancak bu gibi durumlar nadirdir: çoğu durumda, aktarım hızı, sorgunun işlem hızına kıyasla çok büyük değildir.

Aktarım hızı gerçekten önemli olduğunda, bir şirket bir NAS üzerinde büyük veri setleri barındırıyorsa ve NAS'a aynı anda birden fazla müşteri tarafından erişiliyorsa. SAN bir çözüm olabilir burası. Bu söyleniyor, bu tek çözüm değil. Cat 6 kabloları 10 Gb / sn'ye kadar hızları destekleyebilir; bağlama, kabloları veya ağ adaptörlerini değiştirmeden hızı artırmak için de kullanılabilir. Birden fazla NAS'ta veri çoğaltmasını içeren başka çözümler de vardır.

Hızı unut; ölçeklenebilirlik hakkında düşün

Bir web uygulamasının önemli bir noktası ölçeklenebilmektir. Gerçek performans önemli olsa da (çünkü kimse daha güçlü sunucular için ödeme yapmak istemiyorsa) ölçeklenebilirlik çok daha önemlidir, çünkü gerektiğinde ek donanım atmanıza izin verir.

  • Özellikle hızlı bir uygulamanız yoksa, para kaybedersiniz, çünkü daha güçlü sunuculara ihtiyacınız olacaktır.

  • Ölçeklemeyen hızlı bir uygulamanız varsa, müşterileri kaybedersiniz, çünkü artan bir talebe cevap veremezsiniz.

Aynı şekilde, sanal makineler on yıl önce büyük bir performans sorunu olarak algılanmıştı. Gerçekten de, bir uygulamayı bir sunucuda barındırmak ve sanal bir makinede barındırmak önemli bir performans etkisi yarattı. Boşluk bugün çok daha küçük olsa da, hala var.

Bu performans kaybına rağmen, verdikleri esneklik nedeniyle sanal ortamlar çok popüler oldu.

Ağ hızında olduğu gibi, VM'nin gerçek darboğaz olduğunu ve gerçek skalanız olduğunu görebilirsiniz; uygulamanızı VM'ler olmadan doğrudan barındırarak milyarlarca dolar tasarruf edersiniz. Ancak uygulamaların% 99,9'unda böyle bir şey olmaz: darboğazları başka bir yerdedir ve VM nedeniyle birkaç mikrosaniyelik bir kaybın sakıncası, donanım soyutlama ve ölçeklenebilirliğin yararları ile kolayca telafi edilir.


Elbette, JSON yanıtlarının küçük olduğunu söyleyebiliriz, peki ya miktarları ? Ağır yük altındaki bir web sitesinin mikro hizmet mimarisinde yekpare bir mimariden daha fazla ağ trafiğine sahip olacağını hissediyorum (burada yalnızca ağ trafiğinin veritabanı sunucusundan / sunucularından olduğu). Önbellekleme yardımcı olabilir, ancak gerçek zamanlı ve / veya dinamik olarak oluşturulan içerik için önbelleklemenin ne kadar ileri gideceğini bilmiyorum.
James Mishra

@JamesMishra: Endişelerinizi gidermek için cevabımı düzenledim.
Arseni Mourzenko

Cevabınız mükemmel . Düşünebildiğim her itiraza sadece cevap vermekle kalmadı, düşünmediğim itirazları da cevapladın.
James Mishra

5
Gerçek dünyadaki 2 sentim: Çok konuşkan mikroservislerden oluşan bir sistem tamamen boğulmuş bir ağ nedeniyle performans sorunları yaşayabilir. Önbelleğe alma ve Event Stream tabanlı bir tasarım bu gibi durumlarda arkadaşınızdır. Ağ, CPU ve belleğin yanı sıra, mikro hizmet tabanlı bir sistemin de tasarımına esneklik katması gerekir: bir mikro hizmet çökerse ne olur? Nasıl denemeler yaparsınız, işlemlerinizi dağıtırsınız, kendini iyileştirirsiniz, izlersiniz - “mikro hizmetleri kullanmak için bu kadar uzun olmalısınız” demeyi öneriyorum
Sudhanshu Mishra

4
Lütfen hatalıysam beni düzeltin, ama bildiğim kadarıyla, 1Gbps ağınız varsa, bu ağ üzerinden teorik olarak saniyede 1Gb değerinde veri gönderebileceğiniz anlamına gelir. Ne olursa olsun bağlantı sayısı. Bağlantı sayısı arttıkça, her bağlantı için bant genişliği o kadar düşük olur. Bu nedenle, daha yüksek bir bant genişliğini desteklemek için ağınızı yükseltmeden gerçek limitiniz saniyede 26.214 yanıt olacaktır. Daha fazla sunucu eklemek ağ bant genişliğinizi artırmaz. Tek bir küme bu miktarda trafikten kurtulabiliyorsa, daha fazla veri üreten daha fazla sunucu eklemek ağınızı sıkıştıracaktır.
Sebbe,

7

Sanırım 'mikro' bölümü hakkında çok fazla şey okuyorsun. Her sınıfın bir ağ servisi ile değiştirilmesi anlamına gelmez, ancak monolitik bir uygulamayı, her biri programınızın bir yönüyle ilgilenen, makul boyutta bileşenlere ayırmak anlamına gelir. Servisler birbirleriyle konuşmuyor, bu yüzden en kötüsü büyük bir ağ talebini daha küçük olanlara böldünüz. Döndürülen veriler yine de aldıklarınızdan önemli ölçüde farklı olmayacak (daha fazla veri döndürüp istemcide bir araya getirebilirsiniz)


3
"Hizmetler birbirleriyle konuşmuyor." Mikro hizmetlerin, birinin başka bir mikro hizmete ayrılabileceği konusunda paylaşılan bağımlılıkları (belki de kimlik doğrulama, belki de?) Olabileceğini hayal ediyorum. LDAP, bir anlamda, bir kimlik doğrulama mikro servisidir ve diğer tüm mikro servislerin onunla konuştuğunu hayal ediyorum. Veya ... kimlik doğrulama yalnızca bir kez mi oluyor? Her bir mikro hizmet Doğrudan Nesne Erişimi saldırılarını önlemek için izinleri kimlik doğrulamasına karşı nasıl kontrol eder?
James Mishra

2
@ JamesMishra iyi .. bağlıdır. Mikro hizmet mimarisini en son kullandığımda, her hizmet güvenlik nedeniyle (ancak aynı zamanda kurumsal silo nedeniyle) diğerlerinden tamamen bağımsızdı. Bir mimarlık politikası tarafından kontrol edilmesine rağmen, yetkilendirme her biri tarafından ele alındı. Yine de, örneğin auth ile konuşamamaları için bir neden yok ya da sadece bir kütüphaneye dayanarak auth var. Ama .. Kendi aralarında çok fazla telefon görüşmesi yapmamalı, müşterileri olarak hizmet tüketmemeleri gerektiğini söylemeye çalışıyordum.
gbjbaanb 10:15

@JamesMishra, auth, bu ortamlarda genellikle kendi hizmetidir ve bu nedenle her hizmet tam bir uygulama yapmaktan ziyade bunu kullanmalıdır.
Paul,

2

Kodunuzu ve kaynak erişiminizi yapılandırarak, ortaya çıkan sistemin monolitik bir uygulama veya yapılandırma yoluyla dağıtılmış bir sistem olarak çalışacak kadar esnek olabileceği şekilde yapılandırın. Bazı ortak arabirimlerin arkasındaki iletişim mekanizmasını ortadan kaldırırsanız ve sisteminizi aynı anda akılda tutularak oluşturursanız, sisteminizi profillendirdikten ve gerçek şişe boyunlarını bulduktan sonra her şeyi kolayca optimize edebilirsiniz .


@Mortalapeman'ın ne anlama geldiğini varsaydığımı açıklamaya bir örnek: Tüm IProductAvailibitiy tüketicilerinin birbiriyle bağlantılı olduğu bir java / c # arayüzüne sahipsiniz. Ayrıca, bu arayüzü uygulayan bir sınıf ProductAvailibitiyImpl ve ProductAvailibitiyImpl kullanan bir ProductAvailibitiyMicroservice vardır. Tüketicilerin yerel ProductAvailibitiyImpl veya ProductAvailibitiyMicroservice uzaktan vekil ya da kullanmak için yapılandırılabilir
K3b

2

Farklı bir perspektif eklemek istiyorum, farklı bir endüstriden çok farklı varsayımlara sahip - dağıtılmış (varlık düzeyinde) simülasyon. Kavramsal olarak, bu dağıtılmış bir FPS video oyunu gibi bir çok şey var. Anahtar farklılıklar: tüm oyuncular bir durumu paylaşır: ejderhanın şu anda olduğu yerde; veritabanı çağrısı yok; her şey RAM'de hız ve düşük gecikme süresi için tutuluyor, verim daha az alakalı (ama sanırım bunu tamamen görmezden gelemezsin).

Katılan her uygulamayı, bir monolit (bir oyuncunun tüm yönlerini temsil eden) veya bir mikro hizmet (bir kalabalığın içindeki tek bir oyuncuyu temsil eden) olarak düşünebilirsiniz.

Meslektaşlarımın, tek bir katılımcı uygulamanın kendisini, paylaşılabilecek olan daha küçük mikro hizmetlere ayırmalarına, örneğin, tahkim veya görüş hattı hesaplamalarına, genellikle simülasyonlarda bir araya getirilen şeylere, ilgi duymaya başlandı.

Sorun arama gönderme ve istekleri beklemenin gecikmesidir. Diğerlerinin de belirttiği gibi, bant genişliği zaten alakasız ve bol. Ancak, bir görüş hattı hesabı 1 mikrosec ile 100 mikrosec arasındaysa (örneğin, tüm oynatıcı uygulamaları arasında paylaşılan yeni mikro hizmette kuyruğa girme nedeniyle), bu çok büyük bir kayıptır (bunun için birkaç veya daha fazla görüş hattı hesabı gerekebilir). Her güncelleme, birkaç güncelleme / saniye).

Servislerin nasıl çalıştığını, çağrıldıklarında ve hangi verilerin değiş tokuş edildiğini çok dikkatli bir şekilde düşünün. Uygulamalarımız zaten konum bilgisi almıyorlar, ölü hesaplaşma bilgilerini gönderiyorlar - x konumundayım, q yönünde y yönünde ilerliyorum. Ve bu varsayımlar değişinceye kadar bilgilerimi güncellemem gerekmiyor. Daha az sayıda güncelleme ve gecikme (hala bir sorun olsa da) orantılı olarak daha az ortaya çıkıyor.

Daha yüksek bir frekansta ince bir tanecikte bir servis talep etmek yerine, sıklığı düşürmeyi deneyin:

  1. hangi verilerin istendiğini değiştirme ve yerel hesaplamaları kullanma
  2. asenkronize bir cevap için sorgu veya tetikleyici parametrelerin gönderilmesi
  3. toplu istekleri
  4. spekülasyonlar üzerine taleplerin önceden tahmin edilmesi ve önceden bir cevap hazırlanması (tembel değerlendirmenin tersi)
  5. mümkün olan her yerde, diğer mikro servisleri çağıran mikro servislerden kaçının; Bu açıkçası, sorunu bir araya getirir. Bunun, mikro hizmetleri daha büyük hale getirme yönünde bir teşvik olduğunu ve bir şekilde noktayı yitirdiğini biliyorum, ancak mikro hizmetler gecikme için uygun değil. Belki sadece itiraf et ve üstesinden gel.

Şimdi sisteminiz hakkındaki varsayımlarınızı kontrol etmeyi unutmayın. Gecikmeden daha fazla verim ile ilgileniyorsanız veya paylaşılan bir durumunuz yoksa vb., Elbette, anlam ifade ettikleri yerlerde mikro hizmetleri kullanın. Diyorum ki belki onları anlamlandırmadıkları yerlerde kullanma.


1

Saf hayal gücün doğru. Ve genellikle bu önemli değil. Modern makineler hızlı. Mikro hizmet mimarisinin temel avantajları, geliştirme ve bakım çabası ve zamanında görülmektedir.

Ve elbette, paylaşılan hafızayı kullanamayacağınızı ya da birden fazla hizmeti tek bir çalıştırılabilir dosyaya dağıtacağınızı söyleyen hiçbir kural yoktur. Siz tasarladığınız sürece, buna bağlı olmamanız gerekir.


İşlemciler hızlı. Hafıza hızlı. SSD'ler hızlı. Fakat ağ kartları ve yönlendiriciler ve anahtarlar "hızlı" mı? Başka bir cevap da ısrar ediyor, ama emin değilim.
James Mishra

Ağ hızı problemleriyle karşılaşmak kesinlikle kolaydır. Bir servisi San Francisco'da, diğeri Amsterdam'da çalıştırın ve onları Sidney'de tüketin. Gecikme, bant genişliği değil anahtardır. Yani bunu yapma. Ve hizmetleri olabildiğince geniş
tutun

1

Birçok insanın bahsettiği gibi, bu ağ darboğazları ile ilgili değil. Ağ kırılganlığı hakkında daha fazla. Bu yüzden ilk adım, senkron iletişimden kaçınmaktır. Göründüğünden daha kolay. İhtiyacınız olan tek şey doğru sınırları olan hizmetler. Doğru sınırlar, hizmetlerin özerk, gevşek bir şekilde bağlı ve son derece uyumlu olmasıyla sonuçlanır. İyi bir servis başka bir servisten bilgiye ihtiyaç duymaz, zaten buna sahiptir. İyi hizmetlerin iletişim kurmasının tek yolu olaylardır. İyi hizmetler de zaman içinde tutarlıdır, bu nedenle dağıtılmış işlem yoktur.

Bu iyiliği elde etmenin yolu, önce iş yeteneklerinizi belirlemektir. İşletme yeteneği belirli bir işletme sorumluluğudur. Genel işletme değerine bir miktar katkı. İşte sistem sınırlarını düşününce attığım adım dizisi:

  1. Üst düzey iş sorumluluklarını belirleyin. Birkaç tane olacak. Bu hizmetleri, kuruluşunuzun iş hedefine ulaşmak için atması gereken bir adım olarak değerlendirin.
  2. Her hizmetin içinde daha derine dalın. Bir üst olanı içeren alt düzey servis hizmetlerini tanımlayın.
  3. İlk iki husus yanında servis iletişimi hakkında da düşünülüyor. Birbirlerini iş süreçlerinin sonuçları hakkında bilgilendirmek için öncelikle etkinlikler aracılığıyla yapmalılar. Olaylar veri taşıyıcı olarak değerlendirilmemelidir.

Ticari hizmetin insanlar, uygulamalar ve iş süreçleri içerdiğini unutmayın. Genellikle sadece bir kısmı teknik otorite olarak temsil edilir.

Bu biraz soyut gelebilir, bu yüzden muhtemelen hizmet sınırlarının tanımlanması için bir örnek olabilir.


0

Mevcut cevaplara eklemek için başka bir faktör. Bir ile iri taneli hizmetler . Tüm aramaların gecikmesinden kaçınmak istediğinizde, 10 arama yapmak yerine bir DTO'da gereken 10 veri parçasını alan bir arama yapabilirsiniz.

Ve unutmayın, mikro hizmetlerin insanların düşündüğü kadar mikro olmadığını unutmayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.