Monolitik bir uygulamadan mikro hizmet mimarisine geçtikçe yeni zorluklarla karşı karşıya kalıyoruz.
Monolitik bir uygulamada hatanın sistemin hangi kısmında oluştuğunu belirlemek genellikle oldukça kolaydır. Büyük olasılıkla sorun monolitin kodunda veya veritabanındadır. Ancak mikro hizmet mimarisinde sorun aramaya başladığımızda artık her şey o kadar açık değil. İsteğin baştan sona izlediği yolun tamamını bulmamız ve onu yüzlerce mikro hizmet arasından seçmemiz gerekiyor. Üstelik birçoğunun kendi depolama tesisleri de var ve bu da mantıksal hataların yanı sıra performans ve hata toleransı sorunlarına da neden olabiliyor.
Uzun zamandır bu tür sorunların üstesinden gelmeye yardımcı olacak bir araç arıyordum (bunun hakkında Habré'de yazdım:
Dağıtılmış izleme, dağıtılmış sistemlerde hataları bulma sorununa yaygın bir çözümdür. Peki ya ağ etkileşimleri hakkında bilgi toplamaya yönelik bu yaklaşım sistemde henüz uygulanmadıysa veya daha kötüsü, sistemin bir kısmı zaten düzgün çalışıyorsa, ancak eski hizmetlere eklenmediği için kısmen çalışmıyorsa ne olur? ? Bir sorunun kesin kök nedenini belirlemek için sistemde olup bitenlerin tam bir resmine sahip olmak gerekir. İş açısından kritik önemli yollarda hangi mikro hizmetlerin yer aldığını anlamak özellikle önemlidir.
Burada, ağ bilgilerini toplamaya yönelik tüm makineleri, hizmetlerin çalıştığı seviyeden daha düşük bir düzeyde ele alacak olan hizmet ağı yaklaşımı yardımımıza gelebilir. Bu yaklaşım, tüm trafiği yakalamamıza ve anında analiz etmemize olanak tanır. Üstelik uygulamaların bu konuda hiçbir şey bilmesine bile gerek yok.
Hizmet ağı yaklaşımı
Servis ağı yaklaşımının ana fikri, servisler arası etkileşim ile her şeyi yapmamızı sağlayacak şekilde ağ üzerine başka bir altyapı katmanı eklemektir. Uygulamaların çoğu şu şekilde çalışır: her mikro hizmete, hizmetin tüm gelen ve giden trafiğinin içinden geçirildiği, şeffaf bir proxy içeren ek bir sepet konteyneri eklenir. Ve burası tam da istemci dengeleme yapabileceğimiz, güvenlik politikalarını uygulayabileceğimiz, istek sayısına kısıtlamalar getirebileceğimiz ve üretimdeki hizmetlerin etkileşimi hakkında önemli bilgiler toplayabileceğimiz yerdir.
Çözümler
Bu yaklaşımın halihazırda birkaç uygulaması vardır:
Sonuç olarak, şu anda tam olarak hangi yeteneklere ihtiyacımız olduğuna baktık ve bu tür çözümleri uygulamaya başlamamızın ana nedeninin, izleme bilgilerini tüm sistemden şeffaf bir şekilde toplayabilme yeteneği olduğuna karar verdik. Ayrıca servislerin etkileşimi üzerinde kontrol sahibi olmak ve servisler arasında aktarılan başlıklarla çeşitli manipülasyonlar yapmak istedik.
Sonuç olarak şu karara vardık:
Netrameş
Yeni çözümün ana hedefleri düşük kaynak yükü ve yüksek performanstı. Ana özelliklerden, izleme aralıklarını anında Jaeger sistemimize şeffaf bir şekilde gönderebilmek istedik.
Günümüzde çoğu bulut çözümü Golang'da uygulanmaktadır. Ve elbette bunun nedenleri de var. Golang'da, G/Ç ile eş zamanlı olmayan şekilde çalışan ve ihtiyaç halinde çekirdekler arasında ölçeklenen ağ uygulamaları yazmak kullanışlı ve oldukça basittir. Ve çok önemli olan, performansın bu sorunu çözmeye yeterli olmasıdır. Bu yüzden biz de Golang'ı seçtik.
Proizvoditelnost
Çabalarımızı maksimum üretkenliğe ulaşmaya odakladık. Hizmetin her örneğinin yanına dağıtılan bir çözüm için küçük bir RAM ve CPU zamanı tüketimi gerekir. Ve tabii ki yanıt gecikmesi de küçük olmalıdır.
Bakalım ne gibi sonuçlar elde ettik.
RAM
Netramesh, trafik olmadan ~10 Mb ve örnek başına 50 RPS'ye kadar yük ile maksimum 10000 Mb tüketir.
Istio elçi proxy'si, binlerce örnekle kümelerimizde her zaman ~300 Mb tüketir. Bu, kümenin tamamına ölçeklendirilmesine izin vermez.
Netramesh ile bellek tüketiminde ~10 kat azalma elde ettik.
işlemci
Yük altında CPU kullanımı nispeten eşittir. Sepete birim zaman başına yapılan istek sayısına bağlıdır. Zirvede saniyede 3000 istekteki değerler:
Önemli bir nokta daha var: Netramesh - kontrol düzlemi olmayan ve yüksüz bir çözüm, CPU zamanını tüketmez. Istio ile sepetler her zaman hizmet uç noktalarını günceller. Sonuç olarak bu resmi yüksüz olarak görebiliriz:
Hizmetler arasındaki iletişim için HTTP/1 kullanıyoruz. Elçi aracılığıyla proxy yaparken Istio'nun yanıt süresindeki artış 5-10 ms'ye kadar çıktı; bu, bir milisaniyede yanıt vermeye hazır hizmetler için oldukça fazla bir rakam. Netramesh ile bu süre 0.5-2 ms'ye düştü.
ölçeklenebilirlik
Her proxy tarafından tüketilen kaynakların az miktarda olması, onu her hizmetin yanına yerleştirmeyi mümkün kılar. Netramesh, her sepeti hafif tutmak için kasıtlı olarak bir kontrol düzlemi bileşeni olmadan oluşturuldu. Genellikle servis ağı çözümlerinde kontrol düzlemi, servis keşif bilgilerini her sepete dağıtır. Bununla birlikte zaman aşımları ve dengeleme ayarları hakkında bilgi gelir. Bütün bunlar pek çok yararlı şey yapmanıza olanak tanır, ancak ne yazık ki sepetlerin boyutunu şişirir.
Hizmet keşfi
Netramesh, hizmet keşfi için herhangi bir ek mekanizma eklemez. Tüm trafik, netra sepet aracılığıyla şeffaf bir şekilde proxy edilir.
Netramesh, HTTP/1 uygulama protokolünü destekler. Bunu tanımlamak için yapılandırılabilir bir bağlantı noktası listesi kullanılır. Tipik olarak sistem, HTTP iletişiminin gerçekleştiği birkaç bağlantı noktasına sahiptir. Örneğin hizmetler ve harici istekler arasındaki etkileşim için 80, 8890, 8080 kullanıyoruz. Bu durumda bunlar bir ortam değişkeni kullanılarak ayarlanabilir. NETRA_HTTP_PORTS
.
Kubernetes'i bir orkestratör olarak ve hizmetler arasındaki küme içi iletişim için Hizmet varlığı mekanizmasını kullanırsanız mekanizma tamamen aynı kalır. Öncelikle mikro hizmet kube-dns kullanarak bir hizmet IP adresi alır ve ona yeni bir bağlantı açar. Bu bağlantı ilk olarak yerel netra sepeti ile kurulur ve tüm TCP paketleri başlangıçta netra'ya ulaşır. Daha sonra netra-secar orijinal hedefle bağlantı kurar. Düğümdeki pod IP'sindeki NAT, netra olmadan tamamen aynı kalır.
Dağıtılmış izleme ve bağlam iletme
Netramesh, HTTP etkileşimleriyle ilgili izleme aralıklarını göndermek için gereken işlevselliği sağlar. Netra-sidecar, HTTP protokolünü ayrıştırır, istek gecikmelerini ölçer ve gerekli bilgileri HTTP başlıklarından çıkarır. Sonuçta tüm izleri tek bir Jaeger sisteminde elde ediyoruz. Ayrıntılı yapılandırma için resmi kitaplık tarafından sağlanan ortam değişkenlerini de kullanabilirsiniz.
Ama bir problem var. Hizmetler özel bir uber başlığı oluşturup gönderene kadar sistemde bağlı izleme aralıklarını görmeyeceğiz. Sorunların nedenini hızla bulmamız gereken şey de budur. Burada yine Netramesh'in bir çözümü var. Proxy'ler HTTP başlıklarını okur ve uber izleme kimliğini içermiyorlarsa bir tane oluşturur. Netramesh ayrıca gelen ve giden isteklerle ilgili bilgileri bir sepette saklar ve bunları gerekli giden istek başlıklarıyla zenginleştirerek eşleştirir. Servislerde yapmanız gereken tek şey sadece bir başlık göndermek X-Request-Id
bir ortam değişkeni kullanılarak yapılandırılabilen NETRA_HTTP_REQUEST_ID_HEADER_NAME
. Netramesh'te bağlamın boyutunu kontrol etmek için aşağıdaki ortam değişkenlerini ayarlayabilirsiniz: NETRA_TRACING_CONTEXT_EXPIRATION_MILLISECONDS
(bağlamın saklanacağı süre) ve NETRA_TRACING_CONTEXT_CLEANUP_INTERVAL
(bağlam temizleme sıklığı).
Sisteminizde birden fazla yolu özel bir oturum belirteci ile işaretleyerek birleştirmek de mümkündür. Netra yüklemenizi sağlar HTTP_HEADER_TAG_MAP
HTTP başlıklarını karşılık gelen izleme aralığı etiketlerine dönüştürmek için. Bu özellikle test için yararlı olabilir. Fonksiyonel testi geçtikten sonra ilgili oturum anahtarı sayesinde sistemin hangi kısmının filtrelemeden etkilendiğini görebilirsiniz.
İstek Kaynağının Belirlenmesi
İsteğin nereden geldiğini belirlemek için kaynağa otomatik olarak başlık ekleme işlevini kullanabilirsiniz. Ortam değişkeni kullanma NETRA_HTTP_X_SOURCE_HEADER_NAME
Otomatik olarak yüklenecek bir başlık adı belirleyebilirsiniz. Kullanarak NETRA_HTTP_X_SOURCE_VALUE
tüm giden istekler için X-Source başlığının ayarlanacağı değeri ayarlayabilirsiniz.
Bu, bu yararlı başlığın dağıtımının ağ boyunca eşit şekilde dağıtılmasına olanak tanır. Daha sonra bunu hizmetlerde kullanabilir ve günlüklere ve ölçümlere ekleyebilirsiniz.
Trafik yönlendirme ve Netramesh dahili bileşenleri
Netramesh iki ana bileşenden oluşur. Birincisi, netra-init, trafiği engellemek için ağ kurallarını belirler. O kullanır INBOUND_INTERCEPT_PORTS, OUTBOUND_INTERCEPT_PORTS
.
Aracın ayrıca ilginç bir özelliği de var: olasılığa dayalı yönlendirme. Netramesh'i yalnızca izleme aralıklarını toplamak için kullanıyorsanız, üretim ortamında kaynakları kaydedebilir ve değişkenleri kullanarak olasılıksal yönlendirmeyi etkinleştirebilirsiniz. NETRA_INBOUND_PROBABILITY
и NETRA_OUTBOUND_PROBABILITY
(0'dan 1'e). Varsayılan değer 1'dir (tüm trafik kesilir).
Başarılı bir müdahalenin ardından netra sepet yeni bağlantıyı kabul eder ve kullanır SO_ORIGINAL_DST
Orijinal hedefi almak için soket seçeneği. Netra daha sonra orijinal IP adresine yeni bir bağlantı açar ve üzerinden geçen tüm trafiği dinleyerek taraflar arasında iki yönlü TCP iletişimi kurar. Bağlantı noktası HTTP olarak tanımlanmışsa Netra onu ayrıştırmaya ve izlemeye çalışır. HTTP ayrıştırması başarısız olursa Netra, TCP'ye geri döner ve baytları şeffaf bir şekilde proxy olarak kullanır.
Bağımlılık grafiği oluşturma
Jaeger'de büyük miktarda izleme bilgisi aldıktan sonra sistemdeki etkileşimlerin tam bir grafiğini elde etmek istiyorum. Ancak sisteminiz oldukça yüklüyse ve günde milyarlarca izleme aralığı birikiyorsa, bunları bir araya getirmek o kadar da kolay bir iş olmaz. Bunu yapmanın resmi bir yolu var:
İzleme aralıklarını depolamak için Elasticsearch'ü kullanıyorsanız şunu kullanabilirsiniz:
Netramesh nasıl kullanılır?
Netra, herhangi bir orkestratörü çalıştıran herhangi bir hizmete kolayca eklenebilir. Bir örnek görebilirsiniz
Şu anda Netra, sepetleri hizmetlere otomatik olarak uygulama yeteneğine sahip değil, ancak uygulamaya yönelik planlar var.
Netramesh'in geleceği
Ana amaç
Gelecekte Netramesh, HTTP'nin yanı sıra diğer uygulama katmanı protokollerini de destekleyecektir. L7 yönlendirmesi yakın gelecekte kullanıma sunulacaktır.
Benzer sorunlarla karşılaşırsanız Netramesh'i kullanın, soru ve önerilerinizi bize yazın.
Kaynak: habr.com