1. Giriş
Son Güncelleme: 15.07.2022
Uygulamanın gözlemlenebilirliği
Gözlemlenebilirlik ve OpenTelemetry
Gözlemlenebilirlik, bir sistemin özelliğini tanımlamak için kullanılan terimdir. Gözlemlenebilirliğe sahip bir sistem, ekiplerin sistemlerinde aktif olarak hata ayıklamalarına olanak tanır. Bu bağlamda, gözlemlenebilirliğin üç dayanağı olan günlükler, metrikler ve izler, sistemin gözlemlenebilirlik elde etmesi için temel araçlardır.
OpenTelemetry, gözlemlenebilirliğin gerektirdiği telemetri verilerinin (günlükler, metrikler ve izlemeler) enstrümantasyonunu ve dışa aktarımını hızlandıran bir dizi spesifikasyon, kitaplık ve aracıdır. OpenTelemetry, CNCF bünyesindeki açık standart ve topluluk odaklı bir projedir. Geliştiriciler, projenin ve ekosisteminin sağladığı kitaplıkları kullanarak uygulamalarını tedarikçi firmaya bağlı olmayan bir şekilde ve birden fazla mimariye göre enstrümante edebilir.
Ayrıca gözlemlenebilirliğin üç sütununa ek olarak sürekli profil oluşturma, gözlemlenebilirliğin başka bir önemli bileşenidir ve sektördeki kullanıcı tabanını genişletir. Cloud Profiler, bu tür araçların öncülerinden biridir ve uygulama çağrı yığınlarındaki performans metriklerini ayrıntılı olarak incelemek için kolay bir arayüz sağlar.
Bu codelab, serinin 1. bölümünü oluşturur ve mikro hizmetlerde OpenTelemetry ve Cloud Trace ile dağıtılmış izlemeleri enstrümante etmeyi kapsar. 2. bölümde, Cloud Profiler ile sürekli profil oluşturma ele alınacaktır.
Dağıtılmış İz
Günlük, metrik ve iz arasında iz, sistemdeki sürecin belirli bir bölümünün gecikmesini belirten telemetridir. Özellikle mikro hizmetler çağında, dağıtılmış izleme, genel dağıtılmış sistemdeki gecikme darboğazlarını bulmak için güçlü bir itici güçtür.
Dağıtılmış izlekleri analiz ederken, genel sistem gecikmelerini bir bakışta anlamak için iz veri görselleştirmesi önemlidir. Dağıtılmış izlemede, sistem giriş noktasına yapılan tek bir isteği birden fazla Span içeren bir izleme biçiminde işlemek için bir dizi çağrıyı ele alırız.
Aralık, dağıtılmış bir sistemde yapılan tek bir çalışma birimini temsil eder ve başlangıç ile bitiş zamanlarını kaydeder. Aralıklar genellikle aralarında hiyerarşik ilişkilere sahiptir. Aşağıdaki resimde, tüm küçük aralıklar büyük bir /messages aralığının alt aralıklarıdır ve bir sistemdeki çalışmanın yolunu gösteren tek bir izlemeye birleştirilmiştir.
Google Cloud Trace, dağıtılmış izleme arka ucu seçeneklerinden biridir ve Google Cloud'daki diğer ürünlerle iyi entegre edilmiştir.
Oluşturacağınız uygulama
Bu codelab'de, bir Google Kubernetes Engine kümesinde çalışan "Shakespeare uygulaması" (diğer adıyla Shakesapp) adlı hizmetlerde bilgi izlemeyi kullanacaksınız. Shakesapp'in mimarisi aşağıda açıklandığı gibidir:
- Loadgen, istemciye HTTP'de bir sorgu dizesi gönderir
- İstemciler, gRPC'de sorguyu yük oluşturma aracından sunucuya iletir.
- Sunucu, istemciden gelen sorguyu kabul eder, tüm Shakespeare eserlerini Google Cloud Storage'dan metin biçiminde getirir, sorguyu içeren satırları arar ve istemciyle eşleşen satırın numarasını döndürür
İstekte izleme bilgilerini donanıma eklersiniz. Ardından, sunucuya bir profilleyici aracı yerleştirir ve darboğazları araştırırsınız.
Neler öğreneceksiniz?
- Go projesinde OpenTelemetry Trace kitaplıklarını kullanmaya başlama
- Kitaplıkla span oluşturma
- Aralık bağlamlarının uygulama bileşenleri arasında kablo üzerinden nasıl yayılması
- İz verilerini Cloud Trace'e gönderme
- Cloud Trace'te izlemeyi analiz etme
Bu codelab'de, mikro hizmetlerinizi nasıl enstrümante edeceğiniz açıklanmaktadır. Anlaşılmasını kolaylaştırmak için bu örnekte yalnızca 3 bileşen (yük oluşturucu, istemci ve sunucu) bulunmaktadır ancak bu kod laboratuvarındaki süreci daha karmaşık ve büyük sistemlere de uygulayabilirsiniz.
Gerekenler
- Go hakkında temel düzeyde bilgi
- Kubernetes hakkında temel düzeyde bilgi
2. Kurulum ve Gereksinimler
Kendine ait tempoda ortam kurulumu
Google Hesabınız (Gmail veya Google Apps) yoksa hesap oluşturmanız gerekir. Google Cloud Platform Console'da ( console.cloud.google.com) oturum açın ve yeni bir proje oluşturun.
Önceden oluşturduğunuz bir projeniz varsa konsolun sol üst kısmındaki proje seçim açılır menüsünü tıklayın:
ve yeni bir proje oluşturmak için açılan iletişim kutusundaki "YENİ PROJE" düğmesini tıklayın:
Henüz projeniz yoksa ilk projenizi oluşturmak için aşağıdaki gibi bir iletişim kutusu görürsünüz:
Ardından açılan proje oluşturma iletişim kutusunda yeni projenizin ayrıntılarını girebilirsiniz:
Tüm Google Cloud projeleri genelinde benzersiz bir ad olan proje kimliğini unutmayın (yukarıdaki ad zaten alınmış ve kullanılamıyor, özür dileriz). Bu codelab'de daha sonra PROJECT_ID olarak anılacaktır.
Ardından, Google Cloud kaynaklarını kullanmak ve Cloud Trace API'yi etkinleştirmek için Developers Console'da faturalandırmayı etkinleştirmeniz gerekir.
Bu kod laboratuvarını çalıştırmak birkaç dolardan fazlaya mal olmaz ancak daha fazla kaynak kullanmaya karar verirseniz veya kaynakları çalışır durumda bırakırsanız maliyet daha yüksek olabilir (bu dokümanın sonundaki "temizlik" bölümüne bakın). Google Cloud Trace, Google Kubernetes Engine ve Google Artifact Registry'nin fiyatları resmi dokümanda belirtilmiştir.
- Google Cloud'un işlem paketi fiyatlandırması | Operations Suite
- Fiyatlandırma | Kubernetes Engine Dokümanları
- Artifact Registry Fiyatlandırması | Artifact Registry belgeleri
Google Cloud Platform'un yeni kullanıcıları 300 ABD doları değerinde ücretsiz deneme sürümü için uygundur. Bu sayede bu kod laboratuvarını tamamen ücretsiz kullanabilirsiniz.
Google Cloud Shell Kurulumu
Google Cloud ve Google Cloud Trace, dizüstü bilgisayarınızdan uzaktan çalıştırılabilir olsa da bu kod laboratuvarında bulutta çalışan bir komut satırı ortamı olan Google Cloud Shell'i kullanacağız.
Debian tabanlı bu sanal makinede ihtiyaç duyacağınız tüm geliştirme araçları yüklüdür. 5 GB boyutunda kalıcı bir ana dizin sunar ve Google Cloud'da çalışır. Bu sayede ağ performansını ve kimlik doğrulamayı büyük ölçüde iyileştirir. Bu, bu codelab için tek ihtiyacınız olan şeyin bir tarayıcı olduğu anlamına gelir (evet, Chromebook'ta çalışır).
Cloud Shell'i Cloud Console'dan etkinleştirmek için Cloud Shell'i etkinleştir'i tıklamanız yeterlidir (ortam sağlanıp bağlantı kurulabilmesi için birkaç dakika beklemeniz gerekir).
Cloud Shell'e bağlandıktan sonra kimliğinizin doğrulandığını ve projenin PROJECT_ID
olarak ayarlandığını görürsünüz.
gcloud auth list
Komut çıkışı
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
Komut çıkışı
[core] project = <PROJECT_ID>
Herhangi bir nedenle proje ayarlanmamışsa aşağıdaki komutu vermeniz yeterlidir:
gcloud config set project <PROJECT_ID>
PROJECT_ID
cihazınızı mı arıyorsunuz? Kurulum adımlarında hangi kimliği kullandığınızı kontrol edin veya Cloud Console kontrol panelinde arayın:
Cloud Shell, bazı ortam değişkenlerini varsayılan olarak da ayarlar. Bu değişkenler, gelecekte komut çalıştırırken faydalı olabilir.
echo $GOOGLE_CLOUD_PROJECT
Komut çıkışı
<PROJECT_ID>
Son olarak, varsayılan alt bölgeyi ve proje yapılandırmasını ayarlayın.
gcloud config set compute/zone us-central1-f
Çeşitli farklı bölgeler seçebilirsiniz. Daha fazla bilgi için Bölgeler ve Alt Bölgeler başlıklı makaleyi inceleyin.
Dil ayarlarına gitme
Bu kod laboratuvarındaki tüm kaynak kodlarda Go kullanılır. Cloud Shell'de aşağıdaki komutu çalıştırın ve Go sürümünün 1.17 veya sonraki bir sürüm olup olmadığını onaylayın.
go version
Komut çıkışı
go version go1.18.3 linux/amd64
Google Kubernetes kümesi oluşturma
Bu kod laboratuvarında, Google Kubernetes Engine'de (GKE) bir mikro hizmet kümesi çalıştıracaksınız. Bu kod laboratuvarının süreci aşağıdaki gibidir:
- Referans projesini Cloud Shell'e indirme
- Mikro hizmetleri kapsayıcılara derleme
- Container'ları Google Artifact Registry'ye (GAR) yükleme
- Container'ları GKE'ye dağıtma
- İzleme enstrümasyonu için hizmetlerin kaynak kodunu değiştirme
- 2. adıma geçin
Kubernetes Engine'i etkinleştirme
Öncelikle, Shakesapp'in GKE'de çalışacağı bir Kubernetes kümesi oluşturduk. Bu nedenle GKE'yi etkinleştirmemiz gerekiyor. "Kubernetes Engine" menüsüne gidin ve ETKİNLEŞTİR düğmesine basın.
Artık Kubernetes kümesi oluşturmaya hazırsınız.
Kubernetes kümesi oluşturma
Cloud Shell'de, Kubernetes kümesi oluşturmak için aşağıdaki komutu çalıştırın. Lütfen Artifact Registry deposu oluşturmak için kullanacağınız bölge değerinin bölgenin altında olduğunu onaylayın. Depo bölgeniz bölgeyi kapsamıyorsa bölge değerini us-central1-f
değiştirin.
gcloud container clusters create otel-trace-codelab2 \ --zone us-central1-f \ --release-channel rapid \ --preemptible \ --enable-autoscaling \ --max-nodes 8 \ --no-enable-ip-alias \ --scopes cloud-platform
Komut çıkışı
Note: Your Pod address range (`--cluster-ipv4-cidr`) can accommodate at most 1008 node(s). Creating cluster otel-trace-codelab2 in us-central1-f... Cluster is being health-checked (master is healthy)...done. Created [https://container.googleapis.com/v1/projects/development-215403/zones/us-central1-f/clusters/otel-trace-codelab2]. To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1-f/otel-trace-codelab2?project=development-215403 kubeconfig entry generated for otel-trace-codelab2. NAME: otel-trace-codelab2 LOCATION: us-central1-f MASTER_VERSION: 1.23.6-gke.1501 MASTER_IP: 104.154.76.89 MACHINE_TYPE: e2-medium NODE_VERSION: 1.23.6-gke.1501 NUM_NODES: 3 STATUS: RUNNING
Artifact Registry ve skaffold kurulumu
Artık dağıtıma hazır bir Kubernetes kümemiz var. Ardından, kapsayıcıları yüklemek ve dağıtmak için bir kapsayıcı kayıt otoritesi oluşturmaya hazırlanırız. Bu adımlar için bir Artifact Registry (GAR) oluşturmamız ve bunu kullanmak için skaffold'u kurmamız gerekir.
Artifact Registry kurulumu
"Artifact Registry" (Öğe Kaydı) menüsüne gidin ve ETKİNLEŞTİR düğmesine basın.
Birkaç dakika sonra GAR'ın depo tarayıcısını görürsünüz. "DEPOLAMA ALANI OLUŞTUR" düğmesini tıklayın ve depolama alanının adını girin.
Bu kod laboratuvarındaki yeni depoya trace-codelab
adını veriyorum. Yapının biçimi "Docker", konum türü ise "Bölge"dir. Google Compute Engine varsayılan bölgesi için ayarladığınız bölgeye yakın bir bölge seçin. Örneğin, bu örnekte yukarıda "us-central1-f" seçilmiştir. Bu nedenle burada "us-central1 (Iowa)"yı seçiyoruz. Ardından "OLUŞTUR" düğmesini tıklayın.
Artık depo tarayıcısında "trace-codelab" ifadesini görürsünüz.
Kayıt defteri yolunu kontrol etmek için daha sonra buraya geri döneceğiz.
Skaffold kurulumu
Skaffold, Kubernetes'te çalışan mikro hizmetler oluşturmaya çalışırken kullanabileceğiniz kullanışlı bir araçtır. Küçük bir komut grubuyla uygulama kapsayıcıları oluşturma, yayınlama ve dağıtma iş akışını yönetir. Skaffold varsayılan olarak container kayıt defteri olarak Docker Registry'yi kullanır. Bu nedenle, skaffold'u, container'ları gönderirken GAR'ı tanıyacak şekilde yapılandırmanız gerekir.
Cloud Shell'i tekrar açın ve skaffold'un yüklü olup olmadığını kontrol edin. (Cloud Shell, skaffold'u varsayılan olarak ortama yükler.) Aşağıdaki komutu çalıştırarak skaffold sürümünü görün.
skaffold version
Komut çıkışı
v1.38.0
Artık skaffold'un kullanacağı varsayılan depoyu kaydedebilirsiniz. Kayıt defteri yolunu almak için Artifact Registry kontrol paneline gidin ve önceki adımda ayarladığınız deponun adını tıklayın.
Ardından, sayfanın üst kısmında içerik haritası yollarını görürsünüz. Kayıt defteri yolunu panoya kopyalamak için simgesini tıklayın.
Kopyala düğmesini tıkladığınızda, tarayıcının alt kısmında aşağıdaki gibi bir mesaj içeren iletişim kutusunu görürsünüz:
"us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab" kopyalandı
Cloud Shell'e geri dönün. skaffold config set default-repo
komutunu, kontrol panelinden kopyaladığınız değerle çalıştırın.
skaffold config set default-repo us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab
Komut çıkışı
set value default-repo to us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab for context gke_stackdriver-sandbox-3438851889_us-central1-b_stackdriver-sandbox
Ayrıca, kayıt defterini Docker yapılandırmasına göre ayarlamanız gerekir. Aşağıdaki komutu çalıştırın:
gcloud auth configure-docker us-central1-docker.pkg.dev --quiet
Komut çıkışı
{ "credHelpers": { "gcr.io": "gcloud", "us.gcr.io": "gcloud", "eu.gcr.io": "gcloud", "asia.gcr.io": "gcloud", "staging-k8s.gcr.io": "gcloud", "marketplace.gcr.io": "gcloud", "us-central1-docker.pkg.dev": "gcloud" } } Adding credentials for: us-central1-docker.pkg.dev
Artık GKE'de Kubernetes kapsayıcısı oluşturma işleminin bir sonraki adımına geçebilirsiniz.
Özet
Bu adımda codelab ortamınızı ayarlarsınız:
- Cloud Shell'i ayarlama
- Kapsayıcı kayıt defteri için bir Artifact Registry deposu oluşturuldu
- skaffold'u, Container Registry'yi kullanacak şekilde ayarlama
- Codelab mikro hizmetlerinin çalıştığı bir Kubernetes kümesi oluşturma
Sonraki bölüm
Sonraki adımda, mikro hizmetlerinizi derleyip kümeye gönderecek ve dağıtacaksınız.
3. Mikro hizmetleri derleme, yayınlama ve dağıtma
Codelab materyalini indirin
Önceki adımda, bu kod laboratuvarının tüm ön koşullarını ayarladık. Artık bunların üzerinde tüm mikro hizmetleri çalıştırmaya hazırsınız. Codelab materyali GitHub'da barındırılır. Bu nedenle, aşağıdaki git komutunu kullanarak materyali Cloud Shell ortamına indirin.
cd ~ git clone https://github.com/ymotongpoo/opentelemetry-trace-codelab-go.git cd opentelemetry-trace-codelab-go
Projenin dizin yapısı aşağıdaki gibidir:
. ├── README.md ├── step0 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step1 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step2 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step3 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step4 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step5 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src └── step6 ├── manifests ├── proto ├── skaffold.yaml └── src
- manifests: Kubernetes manifest dosyaları
- proto: istemci ile sunucu arasındaki iletişim için proto tanımı
- src: Her hizmetin kaynak kodunun bulunduğu dizinler
- skaffold.yaml: Skaffold için yapılandırma dosyası
Bu codelab'de, step0
klasöründe bulunan kaynak kodu güncelleyeceksiniz. Aşağıdaki adımlardaki yanıtlar için step[1-6]
klasörlerindeki kaynak koda da bakabilirsiniz. (1. Bölüm 0 ile 4 arasındaki adımları, 2. Bölüm ise 5 ve 6. adımları kapsar)
Skaffold komutunu çalıştırma
Artık içeriğin tamamını derleyip yeni oluşturduğunuz Kubernetes kümesine aktarmaya ve dağıtmaya hazırsınız. Bu işlem birden fazla adımdan oluşsa da skaffold her şeyi sizin için yapar. Bunu aşağıdaki komutla deneyelim:
cd step0 skaffold dev
Komutu çalıştırır çalıştırmaz docker build
dosyasının günlük çıkışını görürsünüz ve dosyaların kayıt defterine başarıyla gönderildiğini onaylayabilirsiniz.
Komut çıkışı
... ---> Running in c39b3ea8692b ---> 90932a583ab6 Successfully built 90932a583ab6 Successfully tagged us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/serverservice:step1 The push refers to repository [us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/serverservice] cc8f5a05df4a: Preparing 5bf719419ee2: Preparing 2901929ad341: Preparing 88d9943798ba: Preparing b0fdf826a39a: Preparing 3c9c1e0b1647: Preparing f3427ce9393d: Preparing 14a1ca976738: Preparing f3427ce9393d: Waiting 14a1ca976738: Waiting 3c9c1e0b1647: Waiting b0fdf826a39a: Layer already exists 88d9943798ba: Layer already exists f3427ce9393d: Layer already exists 3c9c1e0b1647: Layer already exists 14a1ca976738: Layer already exists 2901929ad341: Pushed 5bf719419ee2: Pushed cc8f5a05df4a: Pushed step1: digest: sha256:8acdbe3a453001f120fb22c11c4f6d64c2451347732f4f271d746c2e4d193bbe size: 2001
Tüm hizmet kapsayıcıları yayınlandıktan sonra Kubernetes dağıtımları otomatik olarak başlar.
Komut çıkışı
sha256:b71fce0a96cea08075dc20758ae561cf78c83ff656b04d211ffa00cedb77edf8 size: 1997 Tags used in deployment: - serverservice -> us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/serverservice:step4@sha256:8acdbe3a453001f120fb22c11c4f6d64c2451347732f4f271d746c2e4d193bbe - clientservice -> us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/clientservice:step4@sha256:b71fce0a96cea08075dc20758ae561cf78c83ff656b04d211ffa00cedb77edf8 - loadgen -> us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/loadgen:step4@sha256:eea2e5bc8463ecf886f958a86906cab896e9e2e380a0eb143deaeaca40f7888a Starting deploy... - deployment.apps/clientservice created - service/clientservice created - deployment.apps/loadgen created - deployment.apps/serverservice created - service/serverservice created
Dağıtımdan sonra, her kapsayıcıda stdout'a gönderilen gerçek uygulama günlüklerini aşağıdaki gibi görürsünüz:
Komut çıkışı
[client] 2022/07/14 06:33:15 {"match_count":3040} [loadgen] 2022/07/14 06:33:15 query 'love': matched 3040 [client] 2022/07/14 06:33:15 {"match_count":3040} [loadgen] 2022/07/14 06:33:15 query 'love': matched 3040 [client] 2022/07/14 06:33:16 {"match_count":3040} [loadgen] 2022/07/14 06:33:16 query 'love': matched 3040 [client] 2022/07/14 06:33:19 {"match_count":463} [loadgen] 2022/07/14 06:33:19 query 'tear': matched 463 [loadgen] 2022/07/14 06:33:20 query 'world': matched 728 [client] 2022/07/14 06:33:20 {"match_count":728} [client] 2022/07/14 06:33:22 {"match_count":463} [loadgen] 2022/07/14 06:33:22 query 'tear': matched 463
Bu noktada, sunucudan gelen tüm mesajları görmek istediğinizi unutmayın. Tamam, artık hizmetlerin dağıtık izlemesi için uygulamanızı OpenTelemetry ile enstrümante etmeye hazırsınız.
Hizmeti enstrümante etmeye başlamadan önce lütfen Ctrl-C ile kümenizi kapatın.
Komut çıkışı
... [client] 2022/07/14 06:34:57 {"match_count":1} [loadgen] 2022/07/14 06:34:57 query 'what's past is prologue': matched 1 ^CCleaning up... - W0714 06:34:58.464305 28078 gcp.go:120] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.25+; use gcloud instead. - To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke - deployment.apps "clientservice" deleted - service "clientservice" deleted - deployment.apps "loadgen" deleted - deployment.apps "serverservice" deleted - service "serverservice" deleted
Özet
Bu adımda, codelab materyalini ortamınızda hazırladınız ve skaffold'un beklendiği gibi çalıştığını doğruladınız.
Sonraki bölüm
Bir sonraki adımda, izleme bilgilerini gösterecek şekilde loadgen hizmetinin kaynak kodunu değiştireceksiniz.
4. HTTP için araçlar
İzleme aracı ve yayma kavramı
Kaynak kodunu düzenlemeden önce, dağıtılmış izlemelerin işleyiş şeklini basit bir şema üzerinden kısaca açıklayayım.
Bu örnekte, kodu, Trace ve Span bilgilerini Cloud Trace'e aktaracak ve iz bağlamını loadgen hizmetinden sunucu hizmetine istek boyunca dağıtacak şekilde donatıyoruz.
Cloud Trace'in aynı Trace kimliğine sahip tüm aralıklarını tek bir izde toplayabilmesi için uygulamaların Trace kimliği ve Aralık kimliği gibi Trace meta verilerini göndermesi gerekir. Ayrıca, uygulamanın hangi izleme bağlamını işlediğini bilebilmek için istek gönderen alt hizmetlere izleme bağlamlarını (üst aralığın izleme kimliği ve aralığı kimliğinin birleşimi) yayması gerekir.
OpenTelemetry şunları yapmanıza yardımcı olur:
- benzersiz Trace-ID ve Span-ID oluşturmak için
- Trace-ID ve Span-ID'yi arka uca aktarmak için
- izleme bağlamlarını diğer hizmetlere yaymak için
- İzleri analiz etmeye yardımcı olacak ek meta veriler eklemek için
OpenTelemetry İzinde Bileşenler
Uygulama izlemeyi OpenTelemetry ile enstrümante etme işlemi aşağıdaki gibidir:
- İhracat eden oluşturma
- İhracatçıyı 1'de bağlayan bir TracerProvider oluşturun ve bunu genel olarak ayarlayın.
- Yayma yöntemini ayarlamak için TextMapPropagaror'ı ayarlayın
- TracerProvider'dan Tracer'ı alma
- İzleyiciden Span oluşturma
Şu anda her bileşendeki ayrıntılı özellikleri anlamanız gerekmiyor ancak şu noktaları hatırlamanız önemlidir:
- Buradaki dışa aktarıcı, TracerProvider'a takılabilir.
- TracerProvider, izleme örnekleme ve dışa aktarma ile ilgili tüm yapılandırmaları barındırır.
- Tüm izler Tracer nesnesinde gruplandırılır
Bu bilgiler ışığında, asıl kodlama işlemine geçelim.
Enstrüman ilk aralığı
Araç yük oluşturucu hizmeti
Cloud Shell'in sağ üst kısmındaki düğmesine basarak Cloud Shell Düzenleyici'yi açın. Sol bölmede bulunan gezginden step0/src/loadgen/main.go
'ü açın ve ana işlevi bulun.
step0/src/loadgen/main.go
func main() { ... for range t.C { log.Printf("simulating client requests, round %d", i) if err := run(numWorkers, numConcurrency); err != nil { log.Printf("aborted round with error: %v", err) } log.Printf("simulated %d requests", numWorkers) if numRounds != 0 && i > numRounds { break } i++ } }
Ana işlevde, run
işlevini çağıran döngüyü görürsünüz. Mevcut uygulamada, bölümde işlev çağrısının başlangıcını ve sonunu kaydeden 2 günlük satırı vardır. Şimdi, işlev çağrısının gecikmesini izlemek için Span bilgilerini kaydedelim.
Öncelikle, önceki bölümde belirtildiği gibi OpenTelemetry için tüm yapılandırmaları ayarlayalım. OpenTelemetry paketlerini aşağıdaki gibi ekleyin:
step0/src/loadgen/main.go
import ( "context" // step1. add packages "encoding/json" "fmt" "io" "log" "math/rand" "net/http" "net/url" "time" // step1. add packages "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.10.0" "go.opentelemetry.io/otel/trace" // step1. end add packages )
Okunabilirlik için initTracer
adlı bir kurulum işlevi oluşturup main
işlevinde çağırıyoruz.
step0/src/loadgen/main.go
// step1. add OpenTelemetry initialization function func initTracer() (*sdktrace.TracerProvider, error) { // create a stdout exporter to show collected spans out to stdout. exporter, err := stdout.New(stdout.WithPrettyPrint()) if err != nil { return nil, err } // for the demonstration, we use AlwaysSmaple sampler to take all spans. // do not use this option in production. tp := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithBatcher(exporter), ) otel.SetTracerProvider(tp) otel.SetTextMapPropagator(propagation.TraceContext{}) return tp, nil }
OpenTelemetry'yi ayarlama prosedürünün önceki bölümde açıklandığı gibi olduğunu fark edebilirsiniz. Bu uygulamada, tüm izleme bilgilerini yapılandırılmış biçimde stdout'a aktaran bir stdout
dışa aktarıcı kullanıyoruz.
Ardından, ana işlevden çağırırsınız. initTracer()
numaralı telefonu arayın ve uygulamayı kapatırken TracerProvider.Shutdown()
numaralı telefonu arayın.
step0/src/loadgen/main.go
func main() { // step1. setup OpenTelemetry tp, err := initTracer() if err != nil { log.Fatalf("failed to initialize TracerProvider: %v", err) } defer func() { if err := tp.Shutdown(context.Background()); err != nil { log.Fatalf("error shutting down TracerProvider: %v", err) } }() // step1. end setup log.Printf("starting worder with %d workers in %d concurrency", numWorkers, numConcurrency) log.Printf("number of rounds: %d (0 is inifinite)", numRounds) ...
Kurulumu tamamladıktan sonra benzersiz bir izleme kimliği ve Span kimliği içeren bir Span oluşturmanız gerekir. OpenTelemetry bunun için kullanışlı bir kitaplık sağlar. Araç HTTP istemcisine yeni paketler ekleyin.
step0/src/loadgen/main.go
import ( "context" "encoding/json" "fmt" "io" "log" "math/rand" "net/http" "net/http/httptrace" // step1. add packages "net/url" "time" // step1. add packages "go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" // step1. end add packages "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.10.0" "go.opentelemetry.io/otel/trace" )
Yük oluşturucu, runQuery
işlevinde net/http
ile HTTP'de istemci hizmetini çağırdığından net/http
için contrib paketini kullanırız ve httptrace
ve otelhttp
paketinin uzantısını kullanarak enstrümantasyonu etkinleştiririz.
Öncelikle, HTTP isteklerini enstrümante edilmiş istemci aracılığıyla çağırmak için httpClient adlı bir paket genel değişkeni ekleyin.
step0/src/loadgen/main.go
var httpClient = http.Client{ Transport: otelhttp.NewTransport(http.DefaultTransport) }
Ardından, OpenTelemetry'yi ve özel HTTP istemcisinin otomatik olarak oluşturulan aralığını kullanarak özel aralığı oluşturmak için runQuery
işlevine enstrümantasyon ekleyin. Yapmanız gerekenler:
otel.Tracer()
ile globalTracerProvider
'den izleyici almaTracer.Start()
yöntemiyle kök aralığı oluşturma- Kök aralığı isteğe bağlı bir zamanlamada sonlandırın (bu durumda,
runQuery
işlevinin sonu).
step0/src/loadgen/main.go
reqURL.RawQuery = v.Encode() // step1. replace http.Get() with custom client call // resp, err := http.Get(reqURL.String()) // step1. instrument trace ctx := context.Background() tr := otel.Tracer("loadgen") ctx, span := tr.Start(ctx, "query.request", trace.WithAttributes( semconv.TelemetrySDKLanguageGo, semconv.ServiceNameKey.String("loadgen.runQuery"), attribute.Key("query").String(s), )) defer span.End() ctx = httptrace.WithClientTrace(ctx, otelhttptrace.NewClientTrace(ctx)) req, err := http.NewRequestWithContext(ctx, "GET", reqURL.String(), nil) if err != nil { return -1, fmt.Errorf("error creating HTTP request object: %v", err) } resp, err := httpClient.Do(req) // step1. end instrumentation if err != nil { return -1, fmt.Errorf("error sending request to %v: %v", reqURL.String(), err) }
Artık loadgen'deki (HTTP istemci uygulaması) enstrümantasyon işlemini tamamladınız. Lütfen go.mod
ve go.sum
alanlarınızı go mod
komutuyla güncellediğinizden emin olun.
go mod tidy
Araç müşteri hizmetleri
Önceki bölümde, aşağıdaki çizimde kırmızı dikdörtgenle çevrili olan kısmı enstrümante ettik. Yük oluşturucu hizmetinde span bilgilerini enstrümante ettik. Yük oluşturucu hizmete benzer şekilde, istemci hizmetini de enstrümante etmemiz gerekir. Yük oluşturucu hizmetinden farkı, istemci hizmetinin HTTP üstbilgisinde yük oluşturucu hizmetinden yayılan Trace-ID bilgilerini çıkarması ve Span oluşturmak için bu kimliği kullanması gerektiğidir.
Cloud Shell Düzenleyici'yi açın ve yük oluşturucu hizmeti için yaptığımız gibi gerekli paketleri ekleyin.
step0/src/client/main.go
import ( "context" "encoding/json" "fmt" "io" "log" "net/http" "net/url" "os" "time" "opentelemetry-trace-codelab-go/client/shakesapp" // step1. add new import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/trace" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" // step1. end new import )
OpenTelemtry'yi tekrar kurmamız gerekiyor. loadgen'deki initTracer
işlevini kopyalayıp yapıştırmanız ve istemci hizmetinin main
işlevinde de çağırmanız yeterlidir.
step0/src/client/main.go
// step1. add OpenTelemetry initialization function func initTracer() (*sdktrace.TracerProvider, error) { // create a stdout exporter to show collected spans out to stdout. exporter, err := stdout.New(stdout.WithPrettyPrint()) if err != nil { return nil, err } // for the demonstration, we use AlwaysSmaple sampler to take all spans. // do not use this option in production. tp := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithBatcher(exporter), ) otel.SetTracerProvider(tp) otel.SetTextMapPropagator(propagation.TraceContext{}) return tp, nil }
Şimdi aralıklara alet ekleme zamanı. Müşteri hizmetinin, loadgen hizmetinden gelen HTTP isteklerini kabul etmesi gerektiğinden işleyiciyi donatması gerekir. İstemci hizmetindeki HTTP sunucusu net/http ile uygulanır ve loadgen'de yaptığımız gibi otelhttp
paketini kullanabilirsiniz.
İlk olarak, işleyici kaydını otelhttp
İşleyici ile değiştiririz. main
işlevinde, HTTP işleyicinin http.HandleFunc()
ile kaydedildiği satırları bulun.
step0/src/client/main.go
// step1. change handler to intercept OpenTelemetry related headers // http.HandleFunc("/", svc.handler) otelHandler := otelhttp.NewHandler(http.HandlerFunc(svc.handler), "client.handler") http.Handle("/", otelHandler) // step1. end intercepter setting http.HandleFunc("/_genki", svc.health)
Ardından, işleyicinin içindeki gerçek aralığı enstrümante ederiz. func (*clientService) handler() işlevini bulun ve trace.SpanFromContext()
ile span enstrümantasyonu ekleyin.
step0/src/client/main.go
func (cs *clientService) handler(w http.ResponseWriter, r *http.Request) { ... ctx := r.Context() ctx, cancel := context.WithCancel(ctx) defer cancel() // step1. instrument trace span := trace.SpanFromContext(ctx) defer span.End() // step1. end instrument ...
Bu enstrümantasyonla, handler
yönteminin başından sonuna kadar olan aralıkları alırsınız. Aralıkların analiz edilmesini kolaylaştırmak için eşleşen sayıyı depolayan ek bir özellik ekleyin. Günlük satırının hemen önüne aşağıdaki kodu ekleyin.
func (cs *clientService) handler(w http.ResponseWriter, r *http.Request) { ... // step1. add span specific attribute span.SetAttributes(attribute.Key("matched").Int64(resp.MatchCount)) // step1. end adding attribute log.Println(string(ret)) ...
Yukarıdaki tüm enstrümantasyonlarla, loadgen ile istemci arasındaki izleme enstrümantasyonunu tamamladınız. Bunun nasıl çalıştığına bakalım. Kodu skaffold ile tekrar çalıştırın.
skaffold dev
Hizmetler GKE kümesinde çalıştırıldıktan bir süre sonra aşağıdaki gibi çok sayıda günlük mesajı görürsünüz:
Komut çıkışı
[loadgen] { [loadgen] "Name": "query.request", [loadgen] "SpanContext": { [loadgen] "TraceID": "cfa22247a542beeb55a3434392d46b89", [loadgen] "SpanID": "18b06404b10c418b", [loadgen] "TraceFlags": "01", [loadgen] "TraceState": "", [loadgen] "Remote": false [loadgen] }, [loadgen] "Parent": { [loadgen] "TraceID": "00000000000000000000000000000000", [loadgen] "SpanID": "0000000000000000", [loadgen] "TraceFlags": "00", [loadgen] "TraceState": "", [loadgen] "Remote": false [loadgen] }, [loadgen] "SpanKind": 1, [loadgen] "StartTime": "2022-07-14T13:13:36.686751087Z", [loadgen] "EndTime": "2022-07-14T13:14:31.849601964Z", [loadgen] "Attributes": [ [loadgen] { [loadgen] "Key": "telemetry.sdk.language", [loadgen] "Value": { [loadgen] "Type": "STRING", [loadgen] "Value": "go" [loadgen] } [loadgen] }, [loadgen] { [loadgen] "Key": "service.name", [loadgen] "Value": { [loadgen] "Type": "STRING", [loadgen] "Value": "loadgen.runQuery" [loadgen] } [loadgen] }, [loadgen] { [loadgen] "Key": "query", [loadgen] "Value": { [loadgen] "Type": "STRING", [loadgen] "Value": "faith" [loadgen] } [loadgen] } [loadgen] ], [loadgen] "Events": null, [loadgen] "Links": null, [loadgen] "Status": { [loadgen] "Code": "Unset", [loadgen] "Description": "" [loadgen] }, [loadgen] "DroppedAttributes": 0, [loadgen] "DroppedEvents": 0, [loadgen] "DroppedLinks": 0, [loadgen] "ChildSpanCount": 5, [loadgen] "Resource": [ [loadgen] { [loadgen] "Key": "service.name", [loadgen] "Value": { [loadgen] "Type": "STRING", [loadgen] "Value": "unknown_service:loadgen" ...
stdout
dışa aktarıcısı bu iletileri yayınlar. loadgen tarafından oluşturulan tüm aralıkların üst öğelerinin TraceID: 00000000000000000000000000000000
değerine sahip olduğunu göreceksiniz. Bunun nedeni, kök aralığın (yani izlemedeki ilk aralığın) bu olmasıdır. Ayrıca, "query"
yerleştirme özelliğinin müşteri hizmetine iletilen sorgu dizesini içerdiğini görürsünüz.
Özet
Bu adımda, HTTP üzerinden iletişim kuran yük oluşturucu hizmetini ve istemci hizmetini enstrümante ettiniz ve izleme bağlamını hizmetler arasında başarılı bir şekilde dağıtabileceğinizi ve her iki hizmetten de Span bilgilerini stdout'a aktarabileceğinizi doğruladınız.
Sonraki bölüm
Sonraki adımda, gRPC üzerinden izleme bağlamının nasıl dağıtılacağını doğrulamak için istemci hizmetini ve sunucu hizmetini donatacaksınız.
5. gRPC için araçlar
Önceki adımda, isteğin ilk yarısını bu mikro hizmetlerde donattık. Bu adımda, istemci hizmeti ile sunucu hizmeti arasındaki gRPC iletişimini ayarlamaya çalışırız. (Aşağıdaki resimde yeşil ve mor dikdörtgen)
gRPC istemcisi için ön derleme enstrümantasyonu
OpenTelemetry'nin ekosistemi, geliştiricilerin uygulamaları enstrümante etmesine yardımcı olacak birçok kullanışlı kitaplık sunar. Önceki adımda, net/http
paketi için derleme öncesi enstrümantasyon kullandık. Bu adımda, Trace Context'i gRPC üzerinden yaymaya çalıştığımız için kitaplığı kullanırız.
Öncelikle, otelgrpc
adlı önceden oluşturulmuş gRPC paketini içe aktarın.
step0/src/client/main.go
import ( "context" "encoding/json" "fmt" "io" "log" "net/http" "net/url" "os" "time" "opentelemetry-trace-codelab-go/client/shakesapp" // step2. add prebuilt gRPC package (otelgrpc) "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/trace" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" )
Bu sefer istemci hizmeti, sunucu hizmetine karşı bir gRPC istemcisidir. Bu nedenle, gRPC istemcisini donatmanız gerekir. mustConnGRPC
işlevini bulun ve istemci sunucuya her istek gönderdiğinde yeni kapsamlar oluşturan gRPC müdahalecileri ekleyin.
step0/src/client/main.go
// Helper function for gRPC connections: Dial and create client once, reuse. func mustConnGRPC(ctx context.Context, conn **grpc.ClientConn, addr string) { var err error // step2. add gRPC interceptor interceptorOpt := otelgrpc.WithTracerProvider(otel.GetTracerProvider()) *conn, err = grpc.DialContext(ctx, addr, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor(interceptorOpt)), grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor(interceptorOpt)), grpc.WithTimeout(time.Second*3), ) // step2: end adding interceptor if err != nil { panic(fmt.Sprintf("Error %s grpc: failed to connect %s", err, addr)) } }
OpenTelemetry'yi önceki bölümde zaten ayarladığınız için bunu yapmanız gerekmez.
gRPC sunucusu için önceden oluşturulmuş enstrümantasyon
gRPC istemcisi için yaptığımız gibi, gRPC sunucusu için önceden oluşturulmuş enstrümantasyonu çağırıyoruz. İçe aktarma bölümüne aşağıdaki gibi yeni bir paket ekleyin:
step0/src/server/main.go
import ( "context" "fmt" "io/ioutil" "log" "net" "os" "regexp" "strings" "opentelemetry-trace-codelab-go/server/shakesapp" "cloud.google.com/go/storage" // step2. add OpenTelemetry packages including otelgrpc "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "go.opentelemetry.io/otel" stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/grpc" healthpb "google.golang.org/grpc/health/grpc_health_v1" )
Sunucu ilk kez araçlandırıldığı için loadgen ve istemci hizmetleri için yaptığımıza benzer şekilde önce OpenTelemetry'yi ayarlamanız gerekir.
step0/src/server/main.go
// step2. add OpenTelemetry initialization function func initTracer() (*sdktrace.TracerProvider, error) { // create a stdout exporter to show collected spans out to stdout. exporter, err := stdout.New(stdout.WithPrettyPrint()) if err != nil { return nil, err } // for the demonstration, we use AlwaysSmaple sampler to take all spans. // do not use this option in production. tp := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithBatcher(exporter), ) otel.SetTracerProvider(tp) otel.SetTextMapPropagator(propagation.TraceContext{}) return tp, nil } func main() { ... // step2. setup OpenTelemetry tp, err := initTracer() if err != nil { log.Fatalf("failed to initialize TracerProvider: %v", err) } defer func() { if err := tp.Shutdown(context.Background()); err != nil { log.Fatalf("error shutting down TracerProvider: %v", err) } }() // step2. end setup ...
Ardından, sunucu müdahalecileri eklemeniz gerekir. main
işlevinde, grpc.NewServer()
işlevinin çağrıldığı yeri bulun ve işleve müdahaleciler ekleyin.
step0/src/server/main.go
func main() { ... svc := NewServerService() // step2: add interceptor interceptorOpt := otelgrpc.WithTracerProvider(otel.GetTracerProvider()) srv := grpc.NewServer( grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor(interceptorOpt)), grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor(interceptorOpt)), ) // step2: end adding interceptor shakesapp.RegisterShakespeareServiceServer(srv, svc) ...
Mikro hizmeti çalıştırın ve izlemeyi onaylayın
Ardından, değiştirilmiş kodunuzu skaffold komutuyla çalıştırın.
skaffold dev
Şimdi yine stdout'da bir sürü span bilgisi görüyorsunuz.
Komut çıkışı
... [server] { [server] "Name": "shakesapp.ShakespeareService/GetMatchCount", [server] "SpanContext": { [server] "TraceID": "89b472f213a400cf975e0a0041649667", [server] "SpanID": "96030dbad0061b3f", [server] "TraceFlags": "01", [server] "TraceState": "", [server] "Remote": false [server] }, [server] "Parent": { [server] "TraceID": "89b472f213a400cf975e0a0041649667", [server] "SpanID": "cd90cc3859b73890", [server] "TraceFlags": "01", [server] "TraceState": "", [server] "Remote": true [server] }, [server] "SpanKind": 2, [server] "StartTime": "2022-07-14T14:05:55.74822525Z", [server] "EndTime": "2022-07-14T14:06:03.449258891Z", [server] "Attributes": [ ... [server] ], [server] "Events": [ [server] { [server] "Name": "message", [server] "Attributes": [ ... [server] ], [server] "DroppedAttributeCount": 0, [server] "Time": "2022-07-14T14:05:55.748235489Z" [server] }, [server] { [server] "Name": "message", [server] "Attributes": [ ... [server] ], [server] "DroppedAttributeCount": 0, [server] "Time": "2022-07-14T14:06:03.449255889Z" [server] } [server] ], [server] "Links": null, [server] "Status": { [server] "Code": "Unset", [server] "Description": "" [server] }, [server] "DroppedAttributes": 0, [server] "DroppedEvents": 0, [server] "DroppedLinks": 0, [server] "ChildSpanCount": 0, [server] "Resource": [ [server] { ... [server] ], [server] "InstrumentationLibrary": { [server] "Name": "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc", [server] "Version": "semver:0.33.0", [server] "SchemaURL": "" [server] } [server] } ...
Herhangi bir span adı yerleştirmediğinizi ve trace.Start()
veya span.SpanFromContext()
ile manuel olarak span oluşturduğunuzu fark edersiniz. gRPC müdahalecileri tarafından oluşturuldukları için yine çok sayıda span alırsınız.
Özet
Bu adımda, OpenTelemetry ekosistem kitaplıklarının desteğiyle gRPC tabanlı iletişimi araçlandırdınız.
Sonraki bölüm
Sonraki adımda, Cloud Trace ile izinizi görselleştirecek ve toplanan aralıkları nasıl analiz edeceğinizi öğreneceksiniz.
6. Cloud Trace ile izlemeyi görselleştirme
OpenTelemetry ile sistemin tamamında iz eklediniz. Şu ana kadar HTTP ve gRPC hizmetlerini nasıl enstrümante edeceğinizi öğrendiniz. Bu metrikleri nasıl ölçeceğinizi öğrendiniz ancak nasıl analiz edeceğinizi henüz öğrenmediniz. Bu bölümde, stdout dışa aktarıcılarını Cloud Trace dışa aktarıcılarıyla değiştirecek ve izlerinizi nasıl analiz edeceğinizi öğreneceksiniz.
Cloud Trace dışa aktarıcısını kullanma
OpenTelemetry'nin güçlü özelliklerinden biri takılabilir olmasıdır. Enstrümantasyonunuz tarafından toplanan tüm aralıkları görselleştirmek için stdout dışa aktarıcısını Cloud Trace dışa aktarıcısıyla değiştirmeniz yeterlidir.
Her hizmetin main.go
dosyalarını açın ve initTracer()
işlevini bulun. stdout dışa aktarıcısı oluşturmak için satırı silin ve bunun yerine Cloud Trace dışa aktarıcısı oluşturun.
step0/src/loadgen/main.go
import ( ... // step3. add OpenTelemetry for Cloud Trace package cloudtrace "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace" ) // step1. add OpenTelemetry initialization function func initTracer() (*sdktrace.TracerProvider, error) { // step3. replace stdout exporter with Cloud Trace exporter // cloudtrace.New() finds the credentials to Cloud Trace automatically following the // rules defined by golang.org/x/oauth2/google.findDefaultCredentailsWithParams. // https://pkg.go.dev/golang.org/x/oauth2/google#FindDefaultCredentialsWithParams exporter, err := cloudtrace.New() // step3. end replacing exporter if err != nil { return nil, err } // for the demonstration, we use AlwaysSmaple sampler to take all spans. // do not use this option in production. tp := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithBatcher(exporter), ) otel.SetTracerProvider(tp) otel.SetTextMapPropagator(propagation.TraceContext{}) return tp, nil }
Aynı işlevi istemci ve sunucu hizmetinde de düzenlemeniz gerekir.
Mikro hizmeti çalıştırın ve izlemeyi onaylayın
Düzenlemeden sonra, kümeyi skaffold komutuyla normal şekilde çalıştırmanız yeterlidir.
skaffold dev
Ardından, dışa aktarıcıyı Cloud Trace ile değiştirdiğiniz için stdout'da yapılandırılmış günlükler biçiminde çok fazla ara bilgi görmüyorsunuz.
Komut çıkışı
[loadgen] 2022/07/14 15:01:07 simulated 20 requests [loadgen] 2022/07/14 15:01:07 simulating client requests, round 37 [loadgen] 2022/07/14 15:01:14 query 'sweet': matched 958 [client] 2022/07/14 15:01:14 {"match_count":958} [client] 2022/07/14 15:01:14 {"match_count":3040} [loadgen] 2022/07/14 15:01:14 query 'love': matched 3040 [client] 2022/07/14 15:01:15 {"match_count":349} [loadgen] 2022/07/14 15:01:15 query 'hello': matched 349 [client] 2022/07/14 15:01:15 {"match_count":484} [loadgen] 2022/07/14 15:01:15 query 'faith': matched 484 [loadgen] 2022/07/14 15:01:15 query 'insolence': matched 14 [client] 2022/07/14 15:01:15 {"match_count":14} [client] 2022/07/14 15:01:21 {"match_count":484} [loadgen] 2022/07/14 15:01:21 query 'faith': matched 484 [client] 2022/07/14 15:01:21 {"match_count":728} [loadgen] 2022/07/14 15:01:21 query 'world': matched 728 [client] 2022/07/14 15:01:22 {"match_count":484} [loadgen] 2022/07/14 15:01:22 query 'faith': matched 484 [loadgen] 2022/07/14 15:01:22 query 'hello': matched 349 [client] 2022/07/14 15:01:22 {"match_count":349} [client] 2022/07/14 15:01:23 {"match_count":1036} [loadgen] 2022/07/14 15:01:23 query 'friend': matched 1036 [loadgen] 2022/07/14 15:01:28 query 'tear': matched 463 ...
Şimdi tüm aralıkların Cloud Trace'e doğru şekilde gönderilip gönderilmediğini doğrulayalım. Cloud Console'a erişin ve "İzleme listesi"ne gidin. Arama kutusundan kolayca erişebilirsiniz. Aksi takdirde, sol bölmede menüyü tıklayabilirsiniz.
Ardından, gecikme grafiğinde çok sayıda mavi noktanın dağıldığını görürsünüz. Her nokta tek bir izleyiciyi temsil eder.
Bunlardan birini tıkladığınızda izlemenin ayrıntılarını görebilirsiniz.
Bu basit ve hızlı bir bakışta bile birçok analiz hakkında bilgi sahibi olabilirsiniz. Örneğin, şelale grafiğinde gecikmenin çoğunlukla shakesapp.ShakespeareService/GetMatchCount
adlı aralığa bağlı olduğunu görebilirsiniz. (Yukarıdaki resimde 1 numaralı yere bakın.) Bunu özet tablosundan onaylayabilirsiniz. (En sağdaki sütunda her aralığın süresi gösterilir.) Ayrıca bu izleme, "arkadaş" sorgusu içindi. (Yukarıdaki resimde 2'ye bakın)
Bu kısa analizler göz önüne alındığında, GetMatchCount
yönteminde daha ayrıntılı aralıklar hakkında bilgi sahibi olmanız gerektiğini fark edebilirsiniz. Görselleştirme, stdout bilgilerine kıyasla güçlüdür. Cloud Trace ayrıntıları hakkında daha fazla bilgi edinmek için lütfen resmi dokümanlarımızı inceleyin.
Özet
Bu adımda, stdout dışa aktarıcısını Cloud Trace ile değiştirdiniz ve Cloud Trace'te izleri görselleştirdiniz. Ayrıca, izlerini nasıl analiz edeceğinizi de öğrendiniz.
Sonraki bölüm
Sonraki adımda, GetMatchCount işlevine bir alt span eklemek için sunucu hizmetinin kaynak kodunu değiştireceksiniz.
7. Daha iyi analiz için alt aralığı ekleme
Önceki adımda, loadgen'den gözlemlenen gidiş dönüş süresinin nedeninin çoğunlukla sunucu hizmetindeki GetMatchCount yöntemi içindeki işlem (gRPC işleyicisi) olduğunu tespit etmiştiniz. Ancak işleyici dışında bir şeye enstrüman eklemediğimiz için şelale grafiğinden başka analizler elde edemiyoruz. Bu durum, mikro hizmetlere ölçüm eklemeye başladığımızda sık karşılaşılan bir durumdur.
Bu bölümde, sunucunun Google Cloud Storage'ı çağırdığı bir alt aralığı göstereceğiz. Bunun nedeni, bazı harici ağ I/O'larının işlemde uzun zaman almasının yaygın olması ve bunun nedeninin çağrı olup olmadığını belirlemenin önemli olmasıdır.
Sunucuda alt aralığı ayarlama
Sunucuda main.go
dosyasını açın ve readFiles
işlevini bulun. Bu işlev, Shakespeare eserlerinin tüm metin dosyalarını almak için Google Cloud Storage'a bir istek gönderir. Bu işlevde, istemci hizmetinde HTTP sunucusu enstrümantasyonu için yaptığınız gibi bir alt span oluşturabilirsiniz.
step0/src/server/main.go
func readFiles(ctx context.Context, bucketName, prefix string) ([]string, error) { type resp struct { s string err error } // step4: add an extra span span := trace.SpanFromContext(ctx) span.SetName("server.readFiles") span.SetAttributes(attribute.Key("bucketname").String(bucketName)) defer span.End() // step4: end add span ...
Yeni bir span eklemeyle ilgili tüm bilgiler bu kadar. Uygulamayı çalıştırarak nasıl sonuç alacağınıza bakalım.
Mikro hizmeti çalıştırın ve izlemeyi onaylayın
Düzenlemeden sonra kümeyi skaffold komutuyla normal şekilde çalıştırmanız yeterlidir.
skaffold dev
İzleme listesinden query.request
adlı bir izleme seçin. shakesapp.ShakespeareService/GetMatchCount
altında yeni bir aralığın bulunması dışında benzer bir izleme şelalesi grafiği görürsünüz. (Aşağıdaki kırmızı dikdörtgenle çevrili aralık)
Bu grafikten, Google Cloud Storage'a yapılan harici çağrının büyük miktarda gecikmeye neden olduğu ancak gecikmenin büyük bir kısmının başka kaynaklardan kaynaklandığı sonucunu çıkarabilirsiniz.
Henüz yalnızca birkaç kez izleyici akış şelalesi grafiğini inceleyerek çok sayıda analiz elde ettiniz. Uygulamanızdaki diğer performans ayrıntılarını nasıl elde edersiniz? Bu noktada profilleyici devreye girer. Ancak şimdilik bu codelab'in sonuna gelelim ve tüm profilleyici eğitimlerini 2. bölüme bırakalım.
Özet
Bu adımda, sunucu hizmetinde başka bir span eklediniz ve sistem gecikmesi hakkında daha fazla analiz elde ettiniz.
8. Tebrikler
OpenTelemery ile dağıtılmış izlemeler oluşturdunuz ve Google Cloud Trace'te mikro hizmet genelinde istek gecikmeleri olduğunu doğruladınız.
Daha uzun alıştırmalar için aşağıdaki konuları kendiniz deneyebilirsiniz.
- Mevcut uygulama, durum denetimi tarafından oluşturulan tüm aralıkları gönderir. (
grpc.health.v1.Health/Check
) Bu aralıkları Cloud Trace'lerden nasıl filtrelersiniz? İpucu burada. - Etkinlik günlüklerini kapsamlarla ilişkilendirin ve Google Cloud Trace ile Google Cloud Logging'da nasıl çalıştığını öğrenin. İpucu burada.
- Bazı hizmetleri başka bir dilde olan hizmetlerle değiştirin ve bu dil için OpenTelemetry ile enstrümante etmeye çalışın.
Ayrıca, bu bölümden sonra profilleyici hakkında bilgi edinmek isterseniz lütfen 2. bölüme geçin. Bu durumda aşağıdaki temizleme bölümünü atlayabilirsiniz.
Temizleme
Bu kod laboratuvarından sonra, Google Kubernetes Engine, Google Cloud Trace ve Google Artifact Registry'de beklenmedik ücretler ödememek için lütfen Kubernetes kümesini durdurun ve projeyi sildiğinizden emin olun.
Öncelikle kümeyi silin. Kümeyi skaffold dev
ile çalıştırıyorsanız Ctrl-C tuşlarına basmanız yeterlidir. Kümeyi skaffold run
ile çalıştırıyorsanız aşağıdaki komutu çalıştırın:
skaffold delete
Komut çıkışı
Cleaning up... - deployment.apps "clientservice" deleted - service "clientservice" deleted - deployment.apps "loadgen" deleted - deployment.apps "serverservice" deleted - service "serverservice" deleted
Kümeyi sildikten sonra menü bölmesinde "IAM ve Yönetici" > "Ayarlar"ı seçin ve ardından "KAPATIN" düğmesini tıklayın.
Ardından, iletişim kutusundaki forma proje kimliğini (proje adını değil) girin ve kapatma işlemini onaylayın.