Dağıtık izleme nedir?

Dağıtık izleme (distributed tracing), tek bir isteğin dokunduğu her servisteki yolunu ve her adımın süresini kaydeder. Zamanın nereye gittiğini ve hatanın nerede başladığını böyle görürsünüz.

Önce bir trace okuyalım

Tanımlardan önce gerçekte karşınıza çıkacak şeye bakalım. Aşağıda POST /basvuru isteğinin sadeleştirilmiş trace'i var. Her satır bir span, girinti de üst span'i gösteriyor.

trace 4bf92f3577b34da6a3ce929d0e0e4736                       toplam 1.840 ms

api-gateway    POST /basvuru            [==============================] 1840 ms
  basvuru-svc  POST /basvuru            [ =============================] 1815 ms
    basvuru    SELECT musteri           [ =]                               22 ms
    basvuru    SELECT musteri           [  =]                              21 ms
    basvuru    SELECT musteri           [   =]                             23 ms
    skor-svc   POST /skor               [    =======================  ]  1490 ms
      skor     cache GET skor:88213     [    =]                             2 ms
      skor     SELECT kurallar          [     ======================  ]  1460 ms
    basvuru    INSERT basvuru           [                           = ]    41 ms
    basvuru    publish basvuru.alindi   [                            =]     6 ms

Tek resim, hiçbir metriğin doğrudan söyleyemeyeceği şeyleri anlatıyor:

  • Sürenin neredeyse tamamı skor-svc içindeki bir SQL cümlesinde.
  • basvuru-svc, SELECT musteri sorgusunu üst üste üç kez çalıştırıyor. Bugün küçük görünse de büyük dosyalarda büyüyecek bir N+1 kalıbı olabilir.
  • Önbellek sorgusu önce çalışmış ve büyük ihtimalle bulamamış. SQL'in neden çalıştığını bu açıklıyor.
  • Çağrılar birbiri ardına çalışıyor. Ekibin varsaydığı paralellik burada yok.

Temel kavramlar

Trace

Bir isteğin veya işlemin eksiksiz kaydıdır. Tüm parçaları 16 baytlık aynı trace kimliğini paylaşır.

Span

Süresi ölçülmüş tek bir işlemdir: gelen HTTP isteği, giden çağrı, veritabanı sorgusu veya bir iş mantığı parçası. Bir span şunları taşır:

  • POST /basvuru veya SELECT kurallar gibi bir ad
  • başlangıç ve bitiş zamanı
  • kendi kimliği ve üst span'in kimliği
  • bir tür (server, client, internal, producer, consumer)
  • http.response.status_code gibi öznitelikler
  • hatayı işaretleyebilen bir durum
  • yığın izli istisna kaydı gibi olaylar
  • toplu iş ve mesajlaşma senaryolarında diğer trace'lerdeki span'lere bağlantılar

Bağlam taşıma

İzlemeyi dağıtık yapan kısım budur. A servisi B'yi çağırırken trace kimliğini ve geçerli span kimliğini isteğe ekler. B bunları okur ve kendi span'ini A'nınkine alt span yapar. HTTP'de standart traceparent başlığıdır:

traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01

Soldan sağa alanlar sürüm, trace kimliği, üst span kimliği ve bayraklardır. Sondaki 01 bu trace'in örneklendiğini söyler. Kopuk trace'lerin çoğunun sebebi, bu başlığın kaybolduğu bir halkadır.

Client ve server span farkı

İki servis arasındaki tek çağrı iki span üretir: çağıranda client, çağrılanda server. Aradaki fark çok şey anlatır. Client span 900 ms, server span 50 ms ise zaman sunucunun işleyicisinin dışında geçmiştir: ağda, bir vekil sunucuda, bağlantı havuzunda, sunucunun önündeki kuyrukta veya iş parçacığı beklerken. Sık duyulan "bizim panelde API 50 ms, karşı taraf 900 ms diyor" tartışmasında iki taraf da haklıdır.

Şelalede tanınacak kalıplar

Görünüm Olası anlamı Neye bakılır
Tek uzun yaprak span Yavaş sorgu veya dış çağrı Sorgu planı, indeksler, alt servis
Art arda çok sayıda kısa, aynı span N+1 sorgu veya geveze API Toplu çağrı, ORM yükleme ayarları
Üst span başlangıcı ile ilk alt span arasında boşluk Span'lerin kapsamadığı kod ya da bekleme Metot düzeyi veri, iş parçacığı havuzu, GC duraklaması
Client span, server span'den çok uzun Kuyruk veya bağlantı havuzu beklemesi Havuz metrikleri, vekil sunucu, ağ
Aynı hedefe merdiven gibi yeniden denemeler Hatayı saklayan yeniden deneme Yeniden deneme politikası, zaman aşımları
Alt span üst span'den önce başlıyor gibi Sunucular arası saat kayması Düğümlerde NTP eşitlemesi
Trace birden bitiyor, altı yok Kayıp bağlam veya enstrümantasyonsuz servis O halkadaki enstrümantasyon

Span'in içinde açıklanmayan büyük bir boşluk gördüğünüzde span'ler artık yetmez. Kod değiştirmeden metot düzeyi izleme tam bu soruya cevap verir.

Metrik, trace ve log birlikte

Üç sinyal farklı sorulara cevap verir:

  • Metrikler bir şeyin değiştiğini ve ne kadar değiştiğini söyler. Uzun süre saklaması ucuzdur, ama tek tek istekleri açıklamaz.
  • Trace'ler zamanın ve hataların isteğin neresinde olduğunu söyler. Pahalı oldukları için genellikle örneklenir.
  • Loglar bir kod parçasının o anda ne bildirdiğini söyler. Hata mesajı veya iş değeri gibi ayrıntıları taşır.

Asıl güç bağlantıdan gelir. trace_id taşıyan bir log satırı sizi doğrudan trace'e götürür. Trace de sizi yüz pod'da grep yapmak yerine yalnızca o isteğin loglarına götürür.

Örnekleme

Yoğun bir sistem çok büyük hacimde span üretir, her şeyi saklamak nadiren değer. İki ana seçenek vardır.

Head-based sampling (baştan örnekleme) kararı trace'in başında verir. Yüzde 10 oranla trace'lerin yüzde 10'u kaydedilir, karar sampled bayrağıyla aşağı taşınır. Ucuzdur, ama sonucu bilmeden karar verdiği için hataların da yüzde 90'ını atar.

Tail-based sampling (kuyruk tabanlı örnekleme) kararı trace tamamlandıktan sonra verir. Tüm hataları ve yavaş istekleri, geri kalanın ise bir kısmını saklayabilir. Bütün trace'leri tamponlamak gerektiğinden daha çok bellek ve biraz mimari iş ister.

Farkı örnekle görelim: saniyede 2.000 istek ve yüzde 0,1 hata, yani saniyede 2 hata. Yüzde 5 baştan örneklemeyle 2 × 0,05 = saniyede 0,1 hatalı trace, yani 10 saniyede bir trace kalır. 200.000 istekte bir görülen nadir bir hata bu trafikte 100 saniyede bir çıkar. Bunun yüzde 5'ini saklamak 2.000 saniyede bir kayıt demektir, kabaca 33 dakikada bir. "Tüm hataları sakla" kuralı olan kuyruk tabanlı örnekleme hepsini yakalar.

İzlemenin iyi yapamadığı işler

  • Asenkron ve toplu işler. Birçok üreticiden gelen mesajları topluca işleyen bir tüketici tek bir üst-alt ağacına sığmaz. OpenTelemetry bunun için span bağlantılarını kullanır, arka uçlar bunları farklı başarıyla gösterir.
  • Span'in içindeki zaman. Alt span'i olmayan 2 saniyelik bir span yalnızca 2 saniyenin orada geçtiğini söyler.
  • Uzun süren iş akışları. Saatler veya günler süren bir süreç tek trace'e pek sığmaz. Bağlantılı ayrı trace'ler düşünün.
  • Enstrümantasyonsuz bileşenler. Eski sistemler, ana bilgisayarlar ve üçüncü taraf servisler boşluk yaratır. Client span yine de ne kadar beklediğinizi gösterir.
  • Hassas veri. SQL metni ve URL'ler kişisel veri taşıyabilir. T.C. kimlik numarası veya IBAN içeren bir URL trace'e aynen yazılır. Parametreli sorgu kullanın, öznitelikleri SDK veya collector katmanında süzün. Ayrıntı için KVKK ve veri yerelliği yazısına bakın.

Nereden başlamalı?

  1. İş için önemli ve en az üç servisi aşan bir istek yolu seçin.
  2. Önce otomatik enstrümantasyonu kullanın. HTTP, veritabanı ve mesajlaşma span'leri çoğu zaman kod yazmadan gelir. Bkz. OpenTelemetry nedir, nasıl kullanılır.
  3. service.name değerini tutarlı verin. Tek servisin üç adla göründüğü trace bitmeyen kafa karışıklığı yaratır.
  4. Ağ geçitlerinde, mesaj kuyruklarında ve iş parçacığı geçişlerinde kopuk trace arayın. Her şeyden önce bağlam taşımayı düzeltin.
  5. Elle span'i yalnızca "keşke burada olsaydı" dediğiniz yerlere ekleyin.
  6. trace_id değerini loglarınıza yazın.
  7. Örnekleme kararını gerçek hacminizi gördükten sonra verin.

Wrentrix trace'leri nasıl kullanıyor?

Wrentrix, herhangi bir OpenTelemetry SDK'sından HTTP üzerinden OTLP kabul eder; bu veriden canlı servis ve bağımlılık haritası, uç nokta başına p50/p95/p99, hata grupları ve trace'e bağlı loglar üretir. Kuyruk tabanlı örnekleme destekler. "Span içindeki boşluk" sorununa karşı Java ve .NET için kod değiştirmeden, Python ve Node.js için kuralla metot süreleri ekler. Örnek trace'lere canlı demodan tıklayabilirsiniz.

Sık sorulan sorular

Trace ile span arasındaki fark nedir?

Trace, bir isteğin yolculuğunun tamamıdır. Span ise bu yolculuktaki bir HTTP çağrısı veya veritabanı sorgusu gibi süresi ölçülmüş tek bir işlemdir. Span'ler kimlikler üzerinden üst span'lerine bağlanır ve aynı trace kimliğini paylaşan bir ağaç oluşturur.

Dağıtık izleme ile loglama arasındaki fark nedir?

Loglar kodun yazdığı ayrı olaylardır ve servisler arasında kendiliğinden birbirine bağlı değildir. Trace'ler ise süre ve üst-alt ilişkisi içeren, servisleri aşan yapılandırılmış kayıtlardır. Trace kimliğini loglara eklediğinizde aynı isteğin iki görünümünü birden elde edersiniz.

Dağıtık izleme ne kadar ek yük getirir?

Tipik otomatik enstrümantasyonda genellikle azdır, ama span hacmine, öznitelik boyutuna, dile ve dışa aktarım ayarlarına bağlıdır. Sıcak döngülerde span üretmek veya büyük içerikleri yakalamak yükü artırır. Güvenebileceğiniz rakam kendi servisinizdeki yük testinden çıkar.

Dağıtık izleme için uygulama kodunu değiştirmek gerekir mi?

Başlangıçta çoğu zaman gerekmez. Java, .NET, Python ve Node.js için ajanlar ve otomatik enstrümantasyon kütüphaneleri yaygın çatılarda kod değiştirmeden span üretir. İşe özgü span ve öznitelikler kod ister, ekipler bunları zaman içinde ekler.

Trace'lerim neden parçalara bölünüyor?

Neredeyse her zaman bir halka bağlamı kaybettiği için. Sık görülen nedenler başlıkları iletmeyen vekil sunucu veya ağ geçidi, bağlam taşımayan mesaj kuyruğu, geçerli bağlamı kaybeden iş parçacığı geçişi ve uyumsuz taşıma biçimleridir. Kopmadan önceki son span'i bulup giden çağrısının ne taşıdığına bakın.