paint-brush
OpenTelemetri İzleri ve Minimal Kod ile Java Arka Uç Gözlemlenebilirliğiile@apanasevich
292 okumalar

OpenTelemetri İzleri ve Minimal Kod ile Java Arka Uç Gözlemlenebilirliği

ile Dmitriy Apanasevich10m2024/11/15
Read on Terminal Reader
Read this story w/o Javascript

Çok uzun; Okumak

OpenTelemetry çerçevesini Java arka uçumuza nasıl entegre ettik ve minimum kodlamayla izlemeyi nasıl sağladık.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - OpenTelemetri İzleri ve Minimal Kod ile Java Arka Uç Gözlemlenebilirliği
Dmitriy Apanasevich HackerNoon profile picture

Herkese merhaba! Ben Dmitriy Apanasevich, MY.GAMES'te Java Geliştiricisiyim, Rush Royale oyunu üzerinde çalışıyorum ve OpenTelemetry çerçevesini Java arka ucumuzla entegre etme deneyimimizi paylaşmak istiyorum. Burada ele alınacak çok şey var: Bunu uygulamak için gereken kod değişikliklerini ve ayrıca kurmamız ve yapılandırmamız gereken yeni bileşenleri ele alacağız - ve tabii ki sonuçlarımızdan bazılarını paylaşacağız.

Amacımız: Sistem gözlemlenebilirliğini sağlamak

Davamıza biraz daha bağlam verelim. Geliştiriciler olarak, izlenmesi, değerlendirilmesi ve anlaşılması kolay yazılımlar oluşturmak istiyoruz (ve bu tam olarak OpenTelemetry'yi uygulamanın amacıdır - sistem verimliliğini en üst düzeye çıkarmak gözlemlenebilirlik ).


Uygulama performansına ilişkin içgörüler toplamak için kullanılan geleneksel yöntemler genellikle olayların, ölçümlerin ve hataların manuel olarak günlüğe kaydedilmesini içerir:



Elbette, loglarla çalışmamızı sağlayan birçok framework var ve eminim ki bu yazıyı okuyan herkesin logları toplamak, saklamak ve analiz etmek için yapılandırılmış bir sistemi vardır.


Loglama da bizim için tam olarak yapılandırılmıştı, bu yüzden loglarla çalışmak için OpenTelemetry'nin sağladığı yetenekleri kullanmadık.


Sistemi izlemenin bir diğer yaygın yolu da ölçümlerden yararlanmaktır:


Metrikleri toplamak ve görselleştirmek için de tam yapılandırılmış bir sistemimiz vardı, bu nedenle burada da OpenTelemetry'nin metriklerle çalışma konusundaki yeteneklerini göz ardı ettik.


Ancak bu tür sistem verilerini elde etmek ve analiz etmek için daha az yaygın bir araç vardır izler .


Bir iz, bir isteğin ömrü boyunca sistemimizde izlediği yolu temsil eder ve genellikle sistem bir istek aldığında başlar ve yanıtla sona erer. İzler, birden fazla açıklıklar , her biri geliştirici veya tercih ettikleri kütüphane tarafından belirlenen belirli bir iş birimini temsil eder. Bu aralıklar, sistemin isteği nasıl işlediğini görselleştirmeye yardımcı olan hiyerarşik bir yapı oluşturur.


Bu tartışmada OpenTelemetry'nin izleme yönüne yoğunlaşacağız.

OpenTelemetry hakkında biraz daha arka plan bilgisi

Ayrıca, OpenTelemetry projesinin birleştirilmesiyle ortaya çıkan OpenTelemetry projesine de biraz ışık tutalım. Açıkİzleme Ve AçıkNüfus Sayımı projeler.


OpenTelemetry artık çeşitli programlama dilleri için bir dizi API, SDK ve araç tanımlayan bir standarda dayalı kapsamlı bir bileşen yelpazesi sağlıyor ve projenin birincil hedefi veri üretmek, toplamak, yönetmek ve dışa aktarmak.


Bununla birlikte OpenTelemetry, veri depolama veya görselleştirme araçları için bir arka uç sunmuyor.


Biz sadece izlemeyle ilgilendiğimiz için, izleri depolamak ve görselleştirmek için en popüler açık kaynaklı çözümleri inceledik:

  • Avcı
  • Fermuarlı
  • Grafana Temposu


Sonuç olarak, etkileyici görselleştirme yetenekleri, hızlı geliştirme hızı ve metrik görselleştirme için mevcut Grafana kurulumumuzla entegrasyonu nedeniyle Grafana Tempo'yu seçtik. Tek, birleşik bir araca sahip olmak da önemli bir avantajdı.

OpenTelemetry bileşenleri

OpenTelemetry'nin bileşenlerini de biraz inceleyelim.


Şartname:

  • API — veri türleri, işlemler, enumlar

  • SDK — şartname uygulaması, farklı programlama dillerinde API'ler. Farklı bir dil, alfa'dan kararlıya kadar farklı bir SDK durumu anlamına gelir.

  • Veri protokolü (OTLP) ve anlamsal kurallar


Java API SDK'sı:

  • Kod enstrümantasyon kütüphaneleri
  • İhracatçılar — oluşturulan izleri arka uca aktarmak için araçlar
  • Çapraz Hizmet Yayıcıları — yürütme bağlamını sürecin dışına aktarmak için bir araç (JVM)


OpenTelemetry Collector , verileri alan, işleyen ve ileten önemli bir bileşendir. Daha yakından bakalım.

OpenTelemetri Toplayıcısı

Saniyede binlerce isteği işleyen yüksek yüklü sistemler için veri hacmini yönetmek hayati önem taşır. İz verileri genellikle hacim açısından iş verilerini geride bırakır ve bu da hangi verilerin toplanıp depolanacağına öncelik verilmesini zorunlu hale getirir. İşte veri işleme ve filtreleme aracımızın devreye girdiği ve hangi verilerin depolanmaya değer olduğunu belirlemenizi sağlayan yer burasıdır. Genellikle ekipler, aşağıdakiler gibi belirli ölçütleri karşılayan izleri depolamak ister:


  • Tepki süreleri belirli bir eşiği aşan izler.
  • İşleme sırasında hatalarla karşılaşan izler.
  • Belirli bir mikro servisten geçen veya kodda şüpheli olarak işaretlenenler gibi belirli nitelikleri içeren izler.
  • Sistemin normal operasyonlarının istatistiksel bir anlık görüntüsünü sağlayan, tipik davranışı anlamanıza ve eğilimleri belirlemenize yardımcı olan düzenli izlerden rastgele bir seçim.

Hangi izlerin kaydedileceğini ve hangilerinin atılacağını belirlemek için kullanılan iki ana örnekleme yöntemi şunlardır:

  • Baş örneklemesi — bir izin tutulup tutulmayacağına başlangıçta karar verir
  • Kuyruk örneklemesi — yalnızca tüm iz kullanılabilir olduktan sonra karar verir. Bu, kararın izde daha sonra görünen verilere bağlı olduğu durumlarda gereklidir. Örneğin, hata aralıklarını içeren veriler. Bu durumlar, önce tüm izin analiz edilmesini gerektirdiğinden baş örneklemesi ile ele alınamaz


OpenTelemetry Collector, veri toplama sisteminin yalnızca gerekli verileri kaydedecek şekilde yapılandırılmasına yardımcı olur. Yapılandırmasını daha sonra ele alacağız, ancak şimdilik, iz üretmeye başlaması için kodda neyin değiştirilmesi gerektiği sorusuna geçelim.

Sıfır kodlu enstrümantasyon

İz oluşturma gerçekten asgari düzeyde kodlama gerektiriyordu; uygulamalarımızı bir java aracıyla başlatmamız ve yapılandırma :


-javaagent:/opentelemetry-javaagent-1.29.0.jar

-Dotel.javaagent.configuration-file=/otel-config.properties


OpenTelemetry çok sayıda kütüphaneler ve çerçeveler , uygulamayı ajanla başlattıktan sonra, servisler arası, DBMS'de vb. isteklerin işlenme aşamalarına ilişkin veriler içeren izleri hemen aldık.


Aracı yapılandırmamızda, izlerde görmek istemediğimiz aralıklara sahip kütüphaneleri devre dışı bıraktık ve kodumuzun nasıl çalıştığına dair veri almak için onu şu şekilde işaretledik: açıklamalar :


 @WithSpan("acquire locks") public CompletableFuture<Lock> acquire(SortedSet<Object> source) { var traceLocks = source.stream().map(Object::toString).collect(joining(", ")); Span.current().setAttribute("locks", traceLocks); return CompletableFuture.supplyAsync(() -> /* async job */); }


Bu örnekte, " acquire locks " adında yeni bir span oluşturma ihtiyacını işaret eden @WithSpan açıklaması yöntem için kullanılmış ve oluşturulan span'a yöntem gövdesinde " locks " niteliği eklenmiştir.


Yöntem çalışmayı bitirdiğinde, span kapatılır ve asenkron kod için bu ayrıntıya dikkat etmek önemlidir. Açıklamalı bir yöntemden çağrılan lambda işlevlerindeki asenkron kodun çalışmasıyla ilgili verileri elde etmeniz gerekiyorsa, bu lambdaları ayrı yöntemlere ayırmanız ve bunları ek bir açıklama ile işaretlemeniz gerekir.

İz toplama kurulumumuz

Şimdi, tüm iz toplama sisteminin nasıl yapılandırılacağından bahsedelim. Tüm JVM uygulamalarımız, verileri OpenTelemetry toplayıcısına gönderen bir Java aracısıyla başlatılır.


Ancak, tek bir toplayıcı büyük bir veri akışını işleyemez ve sistemin bu kısmı ölçeklendirilmelidir. Her JVM uygulaması için ayrı bir toplayıcı başlatırsanız, kuyruk örneklemesi bozulur, çünkü iz analizi tek bir toplayıcıda gerçekleşmelidir ve istek birkaç JVM'den geçerse, bir izin aralıkları farklı toplayıcılarda son bulur ve analizleri imkansız hale gelir.


Burada, bir toplayıcı yapılandırılmış bir dengeleyici imdada yetişiyor.


Sonuç olarak, aşağıdaki sistemi elde ederiz: Her JVM uygulaması, tek görevi farklı uygulamalardan alınan ancak belirli bir iz ile ilgili verileri aynı toplayıcı işlemciye dağıtmak olan aynı dengeleyici toplayıcıya veri gönderir. Daha sonra, toplayıcı işlemci verileri Grafana Tempo'ya gönderir.



Bu sistemdeki bileşenlerin yapılandırmasına daha yakından bakalım.

Yük dengeleme toplayıcısı

Toplayıcı-dengeleyici yapılandırmasında aşağıdaki ana parçaları yapılandırdık:


 receivers:  otlp:    protocols:      grpc: exporters:  loadbalancing:    protocol:      otlp:        tls:          insecure: true    resolver:      static:        hostnames:          - collector-1.example.com:4317          - collector-2.example.com:4317          - collector-3.example.com:4317 service:  pipelines:    traces:      receivers: [otlp]      exporters: [loadbalancing]


  • Alıcılar — yöntemlerin (verilerin toplayıcı tarafından alınabileceği) yapılandırıldığı yer. Veri alımını yalnızca OTLP biçiminde yapılandırdık. (Veri alımını şu şekilde yapılandırmak mümkündür: diğer birçok protokol (Örneğin Zipkin, Jaeger.)
  • İhracatçılar — veri dengelemenin yapılandırıldığı yapılandırmanın bir parçası. Bu bölümde belirtilen toplayıcı-işlemciler arasında, veriler izleme tanımlayıcısından hesaplanan karmaya bağlı olarak dağıtılır.
  • Servis bölümü, servisin nasıl çalışacağının yapılandırmasını belirtir: yalnızca izlerle, üstte yapılandırılmış OTLP alıcısını kullanarak ve verileri dengeleyici olarak ileterek, yani işleme tabi tutmadan.

Veri işleme ile toplayıcı

Toplayıcı-işlemcilerin yapılandırması daha karmaşıktır, o yüzden oraya bir bakalım:


 receivers:  otlp:    protocols:      grpc:        endpoint: 0.0.0.0:14317 processors:  tail_sampling:    decision_wait: 10s    num_traces: 100    expected_new_traces_per_sec: 10    policies:      [          {            name: latency500-policy,            type: latency,            latency: {threshold_ms: 500}          },          {            name: error-policy,            type: string_attribute,            string_attribute: {key: error, values: [true, True]}          },          {            name: probabilistic10-policy,            type: probabilistic,            probabilistic: {sampling_percentage: 10}          }      ]  resource/delete:    attributes:      - key: process.command_line        action: delete      - key: process.executable.path        action: delete      - key: process.pid        action: delete      - key: process.runtime.description        action: delete      - key: process.runtime.name        action: delete      - key: process.runtime.version        action: delete exporters:  otlp:    endpoint: tempo:4317    tls:      insecure: true service:  pipelines:    traces:      receivers: [otlp]      exporters: [otlp]


Toplayıcı-dengeleyici yapılandırmasına benzer şekilde, işleme yapılandırması Alıcılar, İhracatçılar ve Hizmet bölümlerinden oluşur. Ancak, verilerin nasıl işlendiğini açıklayan İşlemciler bölümüne odaklanacağız.


İlk olarak, tail_sampling bölümü şunu gösterir: yapılandırma Depolama ve analiz için gereken verilerin filtrelenmesine olanak tanır:


  • latency500-policy : bu kural, gecikmesi 500 milisaniyeyi aşan izleri seçer.

  • error-policy : bu kural, işleme sırasında hatalarla karşılaşan izleri seçer. İz aralıklarında "true" veya "True" değerlerine sahip "error" adlı bir dize niteliği arar.

  • probabilistic10-policy : Bu kural, normal uygulama çalışması, hatalar ve uzun istek işleme hakkında bilgi sağlamak için tüm izlerin %10'unu rastgele seçer.


Bu örnekte tail_sampling'e ek olarak, veri analizi ve depolama için gerekli olmayan gereksiz öznitelikleri silmek için resource/dele bölümü gösterilmektedir.

Sonuçlar

Ortaya çıkan Grafana iz arama penceresi, verileri çeşitli ölçütlere göre filtrelemenizi sağlar. Bu örnekte, oyun meta verilerini işleyen lobi hizmetinden alınan izlerin bir listesini gösteriyoruz. Yapılandırma, gecikme, hatalar ve rastgele örnekleme gibi niteliklere göre gelecekte filtrelemeye olanak tanır.


İzleme görünümü penceresi, isteği oluşturan çeşitli aralıklar dahil olmak üzere lobi hizmetinin yürütme zaman çizelgesini görüntüler.


Resimden de görebileceğiniz gibi olayların sırası şu şekildedir: kilitler alınır, ardından nesneler önbellekten alınır, ardından istekleri işleyen bir işlem yürütülür, ardından nesneler tekrar önbelleğe kaydedilir ve kilitler serbest bırakılır.


Veritabanı istekleriyle ilgili aralıklar, standart kütüphanelerin enstrümantasyonu nedeniyle otomatik olarak oluşturuldu. Buna karşılık, kilit yönetimi, önbellek işlemleri ve işlem başlatmayla ilgili aralıklar, yukarıda belirtilen açıklamalar kullanılarak iş koduna manuel olarak eklendi.



Bir aralığı görüntülerken, işleme sırasında ne olduğunu daha iyi anlamanızı sağlayan nitelikleri görebilirsiniz; örneğin, veritabanındaki bir sorguyu görebilirsiniz.



Grafana Tempo'nun ilginç özelliklerinden biri de hizmet grafiği Tüm servislerin izlerini, aralarındaki bağlantıları, isteklerin hızını ve gecikmesini grafiksel olarak görüntüleyen:


Özetleme

Gördüğümüz gibi, OpenTelemetry izlemeyle çalışmak gözlem yeteneklerimizi oldukça güzel bir şekilde geliştirdi. Minimum kod değişiklikleri ve iyi yapılandırılmış bir toplayıcı kurulumuyla, derin içgörüler elde ettik - ayrıca, Grafana Tempo'nun görselleştirme yeteneklerinin kurulumumuzu nasıl daha da tamamladığını gördük. Okuduğunuz için teşekkürler!