Hizmet İzleme, OpenTracing ve Jaeger

Hizmet İzleme, OpenTracing ve Jaeger

Projelerimizde microservice mimarisini kullanıyoruz. Performans darboğazları meydana geldiğinde, günlükleri izlemek ve ayrıştırmak için çok zaman harcanır. Bireysel işlemlerin zamanlamaları bir günlük dosyasına kaydedilirken, bu işlemlerin başlatılmasına neyin yol açtığını anlamak, eylem sırasını veya farklı hizmetlerde bir işlemin diğerine göre zaman kaymasını izlemek genellikle zordur.

El işçiliğini en aza indirmek için izleme araçlarından birini kullanmaya karar verdik. İzlemeyi nasıl ve neden kullanabileceğiniz ve bunu nasıl yaptığımız hakkında ve bu makalede tartışılacaktır.

İzleme ile hangi sorunlar çözülebilir?

  1. Hem tek bir hizmette hem de katılan tüm hizmetler arasındaki yürütme ağacının tamamında performans darboğazlarını bulun. Örneğin:
    • Servisler arasında, örneğin coğrafi kodlamaya veya bir veri tabanına yapılan ardışık birçok kısa çağrı.
    • Ağ aktarımları veya disk okumaları gibi uzun G/Ç beklemeleri.
    • Uzun veri ayrıştırma.
    • İşlemci gerektiren uzun işlemler.
    • Nihai sonucu almak için gerekli olmayan ve kaldırılabilen veya geciktirilebilen kod bölümleri.
  2. Hangi sırayla neyin çağrıldığını ve işlem yapıldığında ne olduğunu açıkça anlayın.
    Hizmet İzleme, OpenTracing ve Jaeger
    Örneğin, İstek WS hizmetine geldi -> WS hizmeti, verileri R hizmeti aracılığıyla tamamladı -> ardından V hizmetine bir istek gönderdi -> V hizmeti, WS hizmetinden çok fazla veri yükledi. R hizmeti -> P hizmetine gitti -> P hizmeti tekrar R hizmetine gitti -> hizmet V sonucu göz ardı etti ve J hizmetine gitti -> ve ancak o zaman başka bir şeyi hesaplamaya devam ederken WS hizmetine yanıt verdi arkaplan.
    Tüm süreç için böyle bir iz veya ayrıntılı belgeler olmadan, koda ilk kez bakıldığında neler olduğunu anlamak çok zordur ve kod, farklı hizmetlere dağılmış ve bir grup bölme ve arayüzün arkasına gizlenmiştir.
  3. Sonraki ertelenmiş analiz için yürütme ağacı hakkında bilgi toplanması. Yürütmenin her aşamasında, bu aşamada mevcut olan ize bilgi ekleyebilir ve ardından hangi girdi verilerinin benzer bir senaryoya yol açtığını anlayabilirsiniz. Örneğin:
    • Kullanıcı kimliği
    • Haklar
    • Seçilen yöntemin türü
    • Günlük veya yürütme hatası
  4. İzleri bir metrik alt kümesine dönüştürmek ve zaten metrik biçiminde olan daha fazla analiz.

Hangi iz günlüğe kaydedilebilir. Açıklık

İzlemede bir yayılma kavramı vardır, bu konsola bir günlüğün bir analogudur. Spada şunlar bulunur:

  • Ad, genellikle yürütülen yöntemin adı
  • Yayılmanın oluşturulduğu hizmetin adı
  • Kendi benzersiz kimliği
  • İçinde oturum açmış bir anahtar/değer biçimindeki bir tür meta bilgi. Örneğin, yöntem parametreleri veya yöntemin bir hatayla sonuçlanıp sonuçlanmadığı
  • Bu aralık için başlangıç ​​ve bitiş saatleri
  • Üst aralık kimliği

Her yayılma, yürütülmesini tamamlar tamamlamaz daha sonra incelenmek üzere veritabanında saklanmak üzere yayılma toplayıcısına gönderilir. Gelecekte, ana kimliğe göre bağlanarak tüm açıklıklardan oluşan bir ağaç oluşturabilirsiniz. Analiz ederken, örneğin bazı hizmetlerde bir süreden uzun süren tüm açıklıkları bulabilirsiniz. Ayrıca, belirli bir açıklığa giderek, bu aralığın üstündeki ve altındaki tüm ağacı görün.

Hizmet İzleme, OpenTracing ve Jaeger

Opentrace, Jagger ve bunu projelerimiz için nasıl uyguladığımız

Ortak bir standart var açık iz, herhangi bir dilde belirli bir uygulamaya izlenerek bağlanmadan, nasıl ve neyin toplanması gerektiğini açıklar. Örneğin, Java'da, izlerle yapılan tüm çalışmalar ortak Opentrace API aracılığıyla gerçekleştirilir ve bunun altında, örneğin Jaeger veya hiçbir şey yapmayan boş bir varsayılan uygulama gizlenebilir.
Kullanıyoruz Jaeger Opentrace'in bir uygulaması olarak. Birkaç bileşenden oluşur:

Hizmet İzleme, OpenTracing ve Jaeger

  • Jaeger-agent, genellikle her makineye yüklenen ve hizmetler yerel varsayılan bağlantı noktasında oturum açan yerel bir aracıdır. Aracı yoksa, bu makinedeki tüm hizmetlerin izleri genellikle devre dışı bırakılır.
  • Jaeger-collector - tüm ajanlar toplanan izleri ona gönderir ve onları seçilen veritabanına koyar
  • Veritabanı onların tercih ettiği cassandra, ancak biz elasticsearch kullanıyoruz, birkaç başka veritabanı için uygulamalar ve diske hiçbir şey kaydetmeyen bir bellek içi uygulama var.
  • Jaeger-query, veritabanına giden ve önceden toplanmış izleri analiz için döndüren bir hizmettir.
  • Jaeger-ui, izleri aramak ve görüntülemek için bir web arayüzüdür, jaeger-query'ye gider

Hizmet İzleme, OpenTracing ve Jaeger

Ayrı bir bileşen, açıklıkların jaeger-agent'a gönderildiği belirli diller için opentrace jaeger uygulaması olarak adlandırılabilir.
Jagger'ı Java'da Bağlama io.opentracing.Tracer arabiriminin uygulanmasına gelir, ardından tüm izler gerçek aracıya uçar.

Hizmet İzleme, OpenTracing ve Jaeger

Ayrıca yay bileşeni için bağlayabilirsiniz opentracing-spring-cloud-starter ve Jaeger'dan uygulama opentracing-yay-jaeger-bulut-başlangıç bu bileşenlerden geçen her şey için izlemeyi otomatik olarak yapılandırır, örneğin denetleyicilere yönelik http istekleri, jdbc aracılığıyla veritabanına yapılan istekler vb.

Java'da oturum açan izler

En üst düzeyde bir yerde, ilk Span oluşturulmalıdır, bu, örneğin bir istek alındığında yay denetleyicisi tarafından otomatik olarak veya hiç yoksa manuel olarak yapılabilir. Daha sonra aşağıdaki Kapsam aracılığıyla iletilir. Aşağıdaki yöntemlerden herhangi biri bir Span eklemek isterse, geçerli activeSpan'i Kapsam'dan alır, yeni bir Span oluşturur ve üst öğesinin elde edilen activeSpan olduğunu söyler ve yeni Span'ı aktif hale getirir. Harici servisler çağrılırken, mevcut aktif yayılma onlara iletilir ve bu servisler, bu yayılmaya referansla yeni yayılmalar oluşturur.
Tüm işler Tracer örneğinden geçer, bunu DI mekanizması aracılığıyla veya DI mekanizması çalışmazsa global bir değişken olarak GlobalTracer.get () aracılığıyla alabilirsiniz. Varsayılan olarak, izleyici başlatılmamışsa, NoopTracer hiçbir şey yapmadan geri döner.
Ayrıca, geçerli kapsam, ScopeManager aracılığıyla izleyiciden alınır, mevcut kapsamdan yeni açıklığın bağlanmasıyla yeni bir kapsam oluşturulur ve ardından oluşturulan Kapsam kapatılır, bu da oluşturulan açıklığı kapatır ve önceki Kapsamı geri döndürür. aktif durum. Kapsam bir iş parçacığına bağlıdır, bu nedenle çok iş parçacıklı programlama sırasında, bu yayılmaya referansla başka bir iş parçacığının Kapsamının daha fazla etkinleştirilmesi için etkin yayılma alanını başka bir iş parçacığına aktarmayı unutmamalısınız.

io.opentracing.Tracer tracer = ...; // GlobalTracer.get()

void DoSmth () {
   try (Scope scope = tracer.buildSpan("DoSmth").startActive(true)) {
      ...
   }
}
void DoOther () {
    Span span = tracer.buildSpan("someWork").start();
    try (Scope scope = tracer.scopeManager().activate(span, false)) {
        // Do things.
    } catch(Exception ex) {
        Tags.ERROR.set(span, true);
        span.log(Map.of(Fields.EVENT, "error", Fields.ERROR_OBJECT, ex, Fields.MESSAGE, ex.getMessage()));
    } finally {
        span.finish();
    }
}

void DoAsync () {
    try (Scope scope = tracer.buildSpan("ServiceHandlerSpan").startActive(false)) {
        ...
        final Span span = scope.span();
        doAsyncWork(() -> {
            // STEP 2 ABOVE: reactivate the Span in the callback, passing true to
            // startActive() if/when the Span must be finished.
            try (Scope scope = tracer.scopeManager().activate(span, false)) {
                ...
            }
        });
    }
}

Çok iş parçacıklı programlama için, eşzamansız görevler başlatıldığında geçerli yayılmayı iş parçacığına otomatik olarak ileten TracedExecutorService ve benzeri sarmalayıcılar da vardır:

private ExecutorService executor = new TracedExecutorService(
    Executors.newFixedThreadPool(10), GlobalTracer.get()
);

Harici http istekleri için İzlemeHttpClient

HttpClient httpClient = new TracingHttpClientBuilder().build();

Karşılaştığımız sorunlar

  • İzleyici bir hizmette veya bileşende kullanılmıyorsa Fasulye ve DI her zaman çalışmaz. otomatik kablolu Tracer çalışmayabilir ve GlobalTracer.get() kullanmanız gerekir.
  • Ek açıklamalar, bir bileşen veya hizmet değilse veya yöntem aynı sınıfın komşu bir yönteminden çağrılırsa çalışmaz. Neyin işe yaradığını kontrol etmeye dikkat etmeli ve @Traced çalışmıyorsa manuel iz oluşturmayı kullanmalısınız. Java ek açıklamaları için ek bir derleyici de ekleyebilirsiniz, o zaman her yerde çalışması gerekir.
  • Eski yay ve yay önyüklemesinde, DI'deki hatalar nedeniyle opentraing yay bulutu otomatik yapılandırması çalışmıyor, ardından yay bileşenlerindeki izlerin otomatik olarak çalışmasını istiyorsanız, bunu analoji ile yapabilirsiniz. github.com/opentracing-contrib/java-spring-jaeger/blob/master/opentracing-spring-jaeger-starter/src/main/java/io/opentracing/contrib/java/spring/jaeger/starter/JaegerAutoConfiguration.java
  • Kaynaklarla deneyin, harika bir şekilde çalışmaz, sonunda try'ı kullanmalısınız.
  • Her hizmetin, izlemelerin altına kaydedileceği kendi spring.application.name olmalıdır. Bunları birbirine karıştırmamak için satış ve test için ayrı bir isim ne işe yarar.
  • GlobalTracer ve erkek kedi kullanıyorsanız, bu erkek kedide çalışan tüm hizmetlerin bir GlobalTracer'ı vardır, bu nedenle hepsinin aynı hizmet adı olacaktır.
  • Bir metoda trace eklerken, onun bir döngüde defalarca çağrılmadığından emin olmanız gerekir. Toplam çalışma süresini garanti eden tüm aramalar için ortak bir iz eklemek gerekir. Aksi takdirde fazladan bir yük oluşacaktır.
  • Jaeger-ui'ye girdikten sonra, çok sayıda iz için çok büyük isteklerde bulunuldu ve yanıt beklemedikleri için tekrar yaptılar. Sonuç olarak, jaeger sorgusu çok fazla bellek tüketmeye ve elastik olarak yavaşlamaya başladı. Jaeger sorgusunu yeniden başlatarak yardımcı oldu

İzleri örnekleme, saklama ve görüntüleme

Üç tip var örnekleme izleri:

  1. Tüm izleri gönderen ve kaydeden Const.
  2. Belirli bir olasılıkla izleri filtreleyen olasılık.
  3. Saniyedeki iz sayısını sınırlayan hız sınırlaması. Bu ayarları istemcide, jaeger-agent'ta veya toplayıcıda yapılandırabilirsiniz. Şimdi çok fazla istek olmadığı için valuator stack'te const 1 kullanıyoruz ama uzun sürüyor. İleride bu, sisteme aşırı yük bindirecekse sınırlandırabilirsiniz.

Cassandra kullanıyorsanız, varsayılan olarak izleri yalnızca iki gün boyunca saklar. Kullanıyoruz elastik arama ve izler her zaman için saklanır ve silinmez. Her gün için ayrı bir dizin oluşturulur, örneğin jaeger-service-2019-03-04. Gelecekte, eski izlerin otomatik olarak temizlenmesini yapılandırmanız gerekir.

İzleri görüntülemek için ihtiyacınız olan:

  • İzlemeleri filtrelemek istediğiniz hizmeti seçin; örneğin, Tomcat'te çalışan ve kendi adına sahip olamayan bir hizmet için Tomcat7-default.
  • Ardından, yalnızca uzun yürütmeleri gerçekleştirmek için işlemi, zaman aralığını ve örneğin 10 saniyeden minimum işlem süresini seçin.
    Hizmet İzleme, OpenTracing ve Jaeger
  • İzlerden birine gidin ve orada neyin yavaşladığını görün.
    Hizmet İzleme, OpenTracing ve Jaeger

Ayrıca, bazı istek kimlikleri biliniyorsa, bu kimlik izleme aralığında günlüğe kaydedilmişse, bir etiket araması yoluyla bu kimliğe göre bir izleme bulabilirsiniz.

Belgeleme

Makaleler

Video

Kaynak: habr.com

Yorum ekle