Mikroservislerde dağıtık izlemeyi (OpenTelemetry) nasıl kurarım?
Soru
Bir istek API Gateway → Auth → Sipariş → Stok sırasıyla geziyor. Aradaki bir serviste 800ms gecikmenin kaynağını bulmakta zorlanıyoruz. OpenTelemetry ile tüm servisler (Laravel ve Go) arasında `trace_id` taşıyıp merkezi APM'de (Jaeger/Grafana Tempo) görselleştirmeyi planlıyoruz. HTTP header'ları ve kuyruk mesajları üzerinden context propagation'ı nasıl tasarlarım?
Cevap
Kısa cevap: Custom bir şema icat etmeyin; W3C Trace Context (traceparent/tracestate) üzerinde standartlaşın ki PHP ve Go birbirini sorunsuz anlasın.
Kısa cevap
Sizin asıl derdiniz “800ms nerede” — ve bunu görebilmek için trace’in servisler ve kuyruklar arasında kopmadan taşınması gerekiyor. Go tarafındaki HTTP mekaniğini, yani context’in istekle birlikte nasıl taşındığını Go’da HTTP servisi yazmak yazısında anlatmıştım.
Neden
-
Standart başlık, iki dilin ortak paydasıdır. W3C Trace Context standart olduğu için Laravel ve Go aynı
traceparent’ı ortak okur. Kenditrace_idbaşlığınızı uydurursanız her yeni servis için bir çeviri katmanı borçlanırsınız. -
Zincir en çok kuyruk hop’unda kopar. Takımların unuttuğu parça budur: HTTP tarafını doğru kurup mesaj yayınlarken context’i taşımazsanız asenkron sıçramalar APM’de orphan trace olarak görünür. Aynı kuyruğun kendi dayanıklılık tarafını log hattına buffer koyma sorusunda ayrıca tartışmıştım.
-
Head-only sampling tam da aradığınız trace’i atar. 800ms’lik outlier’ı görmek istiyorsanız kararı isteğin başında vermek yanlış yerdir.
Ne yapmalı
-
W3C Trace Context’i standart yapın. Gateway’de kök span’i başlatın; her servis gelen HTTP header’ından context’i extract etsin, giden çağrılara inject etsin.
-
Kuyruklarda aynı
traceparent’ı mesajla taşıyın. Mesajı publish ederkentraceparent’ı bir mesaj header’ı/attribute olarak ekleyin, worker’da yeniden extract edin. -
Her servise OTel SDK koyun, OTLP ile gönderin. Servis → OTLP → bir Collector → Jaeger/Tempo. Collector’ı araya almak, export’u uygulamadan ayırır ve backend değiştirmeyi kolaylaştırır.
-
Sampling’i akıllı seçin.
parent-basedile bir trace’in tüm span’leri aynı kaderi paylaşsın; üstüne tail sampling ekleyin ki yavaş trace’ler kesin tutulsun. -
trace_id’yi elle örmeyin. Kendi elinizle header okuma/yazma kodu yazmayın; SDK’nın context propagation’ı bunu zaten taşır. Elle yapınca bir yerde unutursunuz ve trace o noktada kopar.
Sonuç: Ben olsam W3C Trace Context + OTel SDK + Collector + Tempo/Jaeger kurar, propagation’ı SDK’ya bırakır, kuyruk hop’unda traceparent’ı mesaj header’ına koymayı asla atlamazdım. Mimari muhakemeyi neden böyle kurduğunuzu sade.dev’de anlatıyorum. 800ms’i ancak kopmamış bir trace gösterir.
İlgili Yazılar
Yorumlar
Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.