Span ile çözüm arasındaki boşluk
OpenTelemetry otomatik enstrümantasyonu sınırları yakalamakta iyidir: gelen HTTP istekleri, giden çağrılar, veritabanı cümleleri, mesajlaşma. Bu çok şeyi kapsar, ama tanıdık bir delik bırakır: 1,8 saniye süren bir server span, 40 ms'lik bir veritabanı alt span'i, 60 ms'lik bir HTTP alt span'i ve 1,7 saniyelik boşluk.
Kayıp süre sizin kodunuzda ya da kimsenin enstrümante etmediği bir kütüphanededir. Büyük bir nesne üzerinde çalışan bir serileştirici, bir kilit, kötü geri izleyen bir düzenli ifade, binlerce küçük ayırma yapan bir eşleyici ya da kimsenin yavaş saymadığı bir önbellek ıskası yolu olabilir. Bunu yalnızca span'lerle bulmak için birinin yeri tahmin etmesi, elle span eklemesi, sürüm çıkması, sorunun tekrarlanmasını beklemesi ve yeniden tahmin etmesi gerekir. Sürümün değişiklik penceresine bağlı olduğu denetimli ortamlarda bu döngü haftalar alabilir.
Diğer klasik cevap profil araçlarıdır. Derinlik için mükemmeldirler, ama profili genellikle siz karar verdiğinizde, seçtiğiniz bir örnekte alırsınız. Üstelik bir metodun geçen salı 14.05'te normal bir salıya göre nasıl davrandığı hakkında pek bir şey söylemez. Metot düzeyi izleme ikisinin arasında durur: üretim trafiğinde sürekli, metot başına süre ölçümü, baktığınız trace ve uç nokta verisiyle bağlantılı.
Türkiye'de birçok kurumda kodu güvenle değiştirebilecek kişinin artık kurumda olmadığı eski Java ve .NET uygulamaları çalışıyor. Bu uygulamalar için "önce koda şunu ekleyin" önerisi pratikte karşılık bulmaz. Kod değiştirmeden izleme bu yüzden burada ayrı bir önem taşır.
Çalışma zamanına göre destek
| Çalışma zamanı | Metot verisi nasıl üretilir | Kod değişikliği |
|---|---|---|
| Java | Sıfır kod, admission webhook kancalarıyla | Yok |
| .NET | Sıfır kod, admission webhook kancalarıyla | Yok |
| Python | Kural tabanlı | Kurallar, uygulama düzenlemesi değil |
| Node.js | Kural tabanlı | Kurallar, uygulama düzenlemesi değil |
Satırlar arasındaki fark gerçektir ve planlamayı etkiler. Java ve .NET'te bir sonraki yeniden başlatmadan itibaren, neyi izleyeceğinizi seçmeden metot görünürlüğü alırsınız. Python ve Node.js'te kapsamı kurallar belirler, birinin uygulamanın hangi bölümlerinin önemli olduğuna karar vermesi gerekir. Kural kurulumunu kendi kod tabanınız için birlikte inceleyebiliriz, bize sorun. Örnek veriyi canlı demoda görebilirsiniz.
Süreç içine nasıl ulaşıyor?
Bunun için kimse Dockerfile veya dağıtım manifestosu düzenlemez. Mekanizma standart bir Kubernetes genişleme noktasına dayanır.
Bir pod oluşturulurken API sunucusu bir mutating admission webhook çağırabilir, webhook da
pod tanımını saklanmadan önce değiştirebilir. İki büyük yönetilen çalışma zamanının açılışta
ek kod yüklemenin desteklenen bir yolu vardır. JVM'de Java agent mekanizması bulunur ve
JAVA_TOOL_OPTIONS ortam değişkenini okur. .NET çalışma zamanı, ortam
değişkenleriyle denetlenen başlangıç kancaları ve bir profil API'si sunar. Admission
webhook, imajı değiştirmeden bunu pod için ayarlayabilecek konumdadır.
Bundan operatörlerin ilk sorduğu üç sonuç çıkar.
Bir sonraki yeniden başlatmada devreye girer, o yeniden başlatmayı Wrentrix yapmaz. Webhook pod'ları yalnızca oluşturulurken görür. Çalışan bir pod sonraki dağıtım, düğüm boşaltma veya planlı rollout'a kadar dokunulmadan kalır. Wrentrix iş yüklerini hiçbir zaman yeniden başlatmaz. Ajanı gündüz kurup enstrümantasyonun normal sürüm döngünüzle gelmesini bekleyebilirsiniz.
Fail-open çalışır. Webhook, ajan erişilemezse pod'ların enstrümantasyonsuz
başlayacağı şekilde ayarlıdır. Kubernetes dilinde bunu failurePolicy: Ignore
ifade eder. Dağıtımınız izlemenin sağlığına bağlı olmaz, doğru öncelik de budur. Bedeli
şudur: ajan kesintisinde metot verisi olmayan pod'lar oluşabilir ve bakmazsanız fark
etmezsiniz. Ajan bakımından sonra enstrümante edilmiş pod sayısını kontrol edin.
Pod başlangıcına küçük bir maliyet ekler. Admission webhook ek yükü pod başlangıcı başına p95 değerinde 25 ms'nin altındadır. Bu yalnızca admission adımı içindir, süreç içi maliyet hakkında bir şey söylemez. O maliyet uygulamanızın çağrı kalıplarına bağlıdır. Temsili bir iş yükünde önce ve sonra ölçün. Bizden gelen dahil tek bir ek yük rakamı, sizin kodunuzdan çıkmadıkça pek anlam taşımaz.
Bir pod'un değiştirildiğini standart araçlarla görmek için canlı tanımdaki ortam değişkenlerini ve birimleri manifestonuzla karşılaştırın:
oc get pod odeme-7c9f5d7b6-x2k4q -n prod -o jsonpath='{.spec.containers[0].env}'
oc get pod odeme-7c9f5d7b6-x2k4q -n prod -o jsonpath='{.spec.volumes}'
Git'teki manifestonuz değişmez, dolayısıyla GitOps denetleyicileri normalde Deployment üzerinde sapma bildirmez. Değişiklik pod'un üzerindedir. Webhook ayarlarını nasıl inceleyeceğinizi Kubernetes ve pod izleme sayfasında anlattık.
Neden 17 kovalı histogram?
Her metodun her çağrısını kaydetmek çok fazla veri demektir ve çoğu hiç okunmaz. Wrentrix metot taban çizgilerini 17 kovalı histogramlardan üretir. Her metodun süreleri 17 zaman aralığına sayılır, tek tek çağrılar değil, dağılım saklanır ve karşılaştırılır.
Hesap tasarımı açıklıyor. Örnek olarak dakikada 6.000 kez çağrılan bir metodu alın. Ham kayıt yalnızca bu metot için dakikada 6.000 değer demektir. Histogram ise metot ne kadar yoğun olursa olsun 17 sayaçtır. Dakikada 60 milyon kez çağrılan metot da aynı 17 sayaca mal olur. Metot düzeyi geçmişi, yalnızca önceden seçilmiş birkaç span için değil, bütün uygulama için karşılanabilir kılan budur.
Dağılım, ortalamanın yakalayamadığı şeyleri de yakalar. Bir metodun iki dönemdeki sürelerini sadeleştirilmiş bir örnekle görelim:
| Süre aralığı | Normal saat | Kötü saat |
|---|---|---|
| 10 ms altı | 8.800 | 8.760 |
| 10-100 ms | 1.170 | 1.090 |
| 100 ms - 1 sn | 30 | 30 |
| 1 sn üstü | 0 | 120 |
İki sütunda da toplam 10.000 çağrı var. Çağrıların yalnızca yüzde 1,2'si yer değiştirmiş, medyan hiç değişmemiş, ama bir saniyenin üstünde yepyeni bir grup belirmiş. Bu bir ortalama olsaydı hafif gürültü gibi görünen bir miktar yükselirdi. Şekil olarak ise "çağrıların yüzde 1,2'si artık yavaş bir şeye takılıyor" der: kilit, zaman aşımı ve yeniden deneme, bağlantı beklemesi. Çift tepeli bir kayma, CPU baskısı veya GC yüzünden her şeyin bir kova yukarı çıktığı düzgün bir yavaşlamadan farklı bir nedene işaret eder.
Dürüst bir sınır da var. Histogramdan tahmin edilen yüzdelik, kova sınırlarından daha hassas olamaz, tek kova içindeki kayma görünmez. Metot histogramları davranışın değiştiğini ve nerede değiştiğini bulmak içindir. Tek bir kod yolunda mikrosaniye hassasiyeti için profil aracı kullanmaya devam edin.
Bir incelemede nasıl kullanılır?
Kurgu bir olayla tipik akış:
-
POST /basvuruuç noktasında SLO alarmı çalışıyor. p99 tırmanmış, p50 değişmemiş. - Yavaş bir trace açıyorsunuz. Server span içinde açıklanamayan büyük bir süre var, hiçbir alt çağrı bunu karşılamıyor.
-
Uç noktanın metot verisi
BelgeOlusturucu.Rendermetodunu haftanın bu saati için taban çizgisinin dışında gösteriyor, çağrı ağacının geri kalanı olağan. - Değişiklik korelasyonu, kaymadan birkaç dakika önce yeni bir şablonu açan bir ConfigMap güncellemesi gösteriyor.
- Ayarı geri alıp metodun taban çizgisine dönmesini izliyorsunuz.
Önemli adım üçüncüsüdür. "Bu saat için olağandan yavaş" ifadesi, zaten hep yavaş olan metotları eler. Her uygulamada rapor üreticileri veya toplu iş işleyicileri gibi meşru olarak bir saniye süren metotlar vardır, mutlak süreye göre sıralama onları her seferinde yeniden listeler. Metot başına taban çizgisi çıktıyı kısa bir şüpheli listesine indirir.
Şüpheliyi bulduktan sonra dile özgü iş yine yapılmalıdır. JVM'de GC logları, iş parçacığı dökümleri ve bağlantı havuzlarına bakılır. .NET'te olağan şüpheliler iş parçacığı havuzu tükenmesi, asenkron üzerinde senkron bekleme ve ayırma baskısıdır. Metot iş yapmıyor da bağlantı bekliyorsa havuz boyutu ve sızıntılara bakın.
Pek yardımcı olmayacağı durumlar
- Yerel kod ve çekirdek süresi. Yerel kütüphanelerdeki beklemeler, sistem çağrıları ve I/O, çağıran metotta süre olarak görünür. Nereden çağrıldığını öğrenirsiniz, altında ne olduğunu değil. Linux sunucu metrikleri bunun bir kısmını tamamlar.
- Hiç yeniden başlamayan iş yükleri. Normal rollout döngünüzün dışında kalan uzun ömürlü bir pod yeniden başlayana kadar enstrümante edilmez. Bunlar için kendiniz plan yapın, Wrentrix zorlamaz.
- Diğer diller. Tarif edilen destek Java, .NET, Python ve Node.js içindir. Başka çalışma zamanları herhangi bir OpenTelemetry SDK'sıyla span gönderebilir, ama metot düzeyi veri için bize sorun.
- Kubernetes dışındaki Java ve .NET. Burada anlatılan sıfır kod yolu Kubernetes ve OpenShift'e ait olan admission webhook'tur. JVM'leriniz doğrudan Linux sunucularda çalışıyorsa aynı kapsamayı varsaymadan önce kurulumunuzu bize sorun: demo talebi.
Sık sorulan sorular
Metot düzeyi veri için uygulama kodunu değiştirmem gerekir mi?
Java ve .NET için gerekmez. Enstrümantasyon pod başlarken admission webhook ile uygulanır, imaj ve kaynak kod değişmez. Python ve Node.js kural tabanlıdır, birinin neyin izleneceğini kurallarla tanımlaması gerekir ama uygulama düzenlenmez.
Ajan kurulumu pod'larımı yeniden başlatır mı?
Hayır. Wrentrix iş yüklerini hiçbir zaman yeniden başlatmaz. Çalışan pod olduğu gibi kalır ve dağıtım veya düğüm boşaltma gibi kendi nedeniyle yeniden başladığında metot düzeyi izlemeye geçer.
Pod başlarken Wrentrix ajanı düşükse ne olur?
Admission webhook fail-open çalışır. Pod enstrümantasyonsuz normal başlar, ajan kesintisi dağıtımları engellemez. O pod, ajan erişilebilir durumdayken yeniden başlayana kadar metot verisi taşımaz.
Metot düzeyi izlemenin performans ek yükü nedir?
Verebildiğimiz ölçülmüş rakam, pod başlangıcı başına 25 ms'nin altındaki p95 admission webhook ek yüküdür. Çalışma anındaki ek yük uygulamanızın davranışına çok bağlıdır, yaygınlaştırmadan önce temsili bir iş yükünde karşılaştırma yapın. Testi tasarlamak için yardım isterseniz bize sorun.
Metot düzeyi izleme profil aracının yerini alır mı?
Hayır. Metot sürelerini histogramlara ölçer, öğrenilen taban çizgisiyle karşılaştırır ve uç noktalara bağlar, yani hangi metodun ne zaman değiştiğini söyler. Metodun CPU ile ne yaptığı gibi daha derin sorular için çalışma zamanınızın kendi profil araçlarını kullanmak gerekir.