1. Giriş
Son Güncelleme: 14.07.2022
Uygulamanın gözlemlenebilirliği
Gözlemlenebilirlik ve Sürekli Profil Aracı
Gözlemlenebilirlik, bir sistemin özelliklerini tanımlamak için kullanılan terimdir. Gözlemlenebilirliğe sahip bir sistem, ekiplerin sistemlerinde etkin bir şekilde hata ayıklamasına olanak tanır. Bu bağlamda, gözlemlenebilirliğin üç ayağı; günlükler, metrikler ve izler, sistemin gözlemlenebilirlik elde etmesi için temel araçlardır.
Gözlemlenebilirliğin üç temel dayanağına ek olarak, sürekli profil çıkarma gözlemlenebilirlik açısından başka bir temel bileşendir ve sektördeki kullanıcı tabanını genişletmektedir. Kaynaklardan biri olan Cloud Profiler, uygulama çağrı yığınlarındaki performans metriklerini ayrıntılı olarak incelemek için kolay bir arayüz sunar.
Bu codelab, serinin 2. bölümüdür ve sürekli profil aracı aracı için enstrümantasyon yöntemini kapsar. 1. bölümde OpenTelemetry ve Cloud Trace ile dağıtılmış izlemeyi ele alacağız. 1. bölümde ise mikro hizmetlerin performans sorunlarını daha iyi tespit etme hakkında daha fazla bilgi edineceksiniz.
Oluşturacaklarınız
Bu codelab'de, "Shakespeare uygulamasının" sunucu hizmetindeki araç sürekli profil aracı aracısını kullanacaksınız. (diğer adıyla Shakesapp) olan bir uygulamadır. Shakesapp'in mimarisi aşağıda açıklandığı gibidir:
- Loadgen, HTTP'de istemciye bir sorgu dizesi gönderir
- İstemciler sorguyu gRPC'deki yük kaynağından sunucuya iletir
- Sunucu; istemciden gelen sorguyu kabul eder, tüm Shakespare 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.
1. bölümde, performans sorununun sunucu hizmetinin bir yerinde olduğunu tespit ettiniz, ancak nedenini tam olarak belirleyemediniz.
Neler öğreneceksiniz?
- Profil oluşturucu aracısı yerleştirme
- Cloud Profiler'da performans sorunlarını inceleme
Bu codelab'de, uygulamanızda sürekli profil aracı aracının nasıl kullanılacağı açıklanmaktadır.
Gerekenler
- Go hakkında temel düzeyde bilgi
- Kubernetes hakkında temel bilgiler
2. Kurulum ve Gereksinimler
Kendi hızınızda ortam kurulumu
Google Hesabınız (Gmail veya Google Apps) yoksa bir hesap oluşturmanız gerekir. Google Cloud Platform konsolunda ( console.cloud.google.com) oturum açın ve yeni bir proje oluşturun.
Zaten bir projeniz varsa konsolun sol üst köşesindeki proje seçimi açılan menüsünü tıklayın:
Sonra ‘YENİ PROJE’yi tıklayın. düğmesini tıklayın:
Henüz projeniz yoksa ilk projenizi oluşturmak için şuna benzer bir iletişim kutusu görmeniz gerekir:
Sonraki proje oluşturma iletişim kutusu yeni projenizin ayrıntılarını girmenize olanak tanır:
Tüm Google Cloud projeleri için benzersiz bir ad olan proje kimliğini unutmayın (yukarıdaki ad daha önce alınmış ve size uygun olmayacaktır!). Bu kod, bu codelab'in ilerleyen bölümlerinde PROJECT_ID olarak adlandırılacaktır.
Sonraki adımda, henüz yapmadıysanız Developers Console'da faturalandırmayı etkinleştirmeniz ve Google Cloud kaynaklarını kullanmak ve Cloud Trace API'yi etkinleştirmek için yapmanız gerekir.
Bu codelab'i çalıştırmanın maliyeti birkaç dolardan fazla değildir. Ancak daha fazla kaynak kullanmaya karar verirseniz veya bu kaynakları çalışır durumda bırakırsanız daha yüksek ücret ödemeniz gerekebilir (bu belgenin sonundaki "temizlik" bölümüne bakın). Google Cloud Trace, Google Kubernetes Engine ve Google Artifact Registry'nin fiyatları resmi belgelerde belirtilmiştir.
- Google Cloud işlem paketi için fiyatlandırma | İşlem Paketi
- Fiyatlandırma | Kubernetes Engine Belgeleri
- Artifact Registry Fiyatlandırması | Artifact Registry belgeleri
Yeni Google Cloud Platform kullanıcıları, bu codelab'i tamamen ücretsiz hale getirecek 300 ABD doları değerindeki ücretsiz denemeden yararlanabilir.
Google Cloud Shell Kurulumu
Google Cloud ve Google Cloud Trace, dizüstü bilgisayarınızdan uzaktan çalıştırılabilse de bu codelab'de Cloud'da çalışan bir komut satırı ortamı olan Google Cloud Shell'i kullanacağız.
Bu Debian tabanlı sanal makine, ihtiyacınız olan tüm geliştirme araçlarıyla yüklüdür. 5 GB boyutunda kalıcı bir ana dizin sunar ve Google Cloud'da çalışarak ağ performansını ve kimlik doğrulamasını büyük ölçüde iyileştirir. Yani bu codelab'de ihtiyacınız olan tek şey bir tarayıcıdır (Evet, Chromebook'ta çalışır).
Cloud Console'dan Cloud Shell'i etkinleştirmek için Cloud Shell'i Etkinleştir'i tıklamanız yeterlidir (sağlanması ve ortama bağlanması birkaç dakika sürer).
Cloud Shell'e bağlandıktan sonra kimliğinizin doğrulandığını ve projenin PROJECT_ID
olarak ayarlanmış olduğunu göreceksiniz.
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 şu komutu vermeniz yeterlidir:
gcloud config set project <PROJECT_ID>
PROJECT_ID
cihazınızı mı arıyorsunuz? Kurulum adımlarında kullandığınız kimliği kontrol edin veya Cloud Console kontrol panelinden arayın:
Cloud Shell bazı ortam değişkenlerini de varsayılan olarak ayarlar. Bu değişkenler, gelecekte komut çalıştırdığınızda işinize yarayabilir.
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ı alt bölgeler seçebilirsiniz. Daha fazla bilgi için Bölgeler ve Bölgeler.
Go dil kurulumu
Bu codelab'de tüm kaynak kodları için Go'yu kullanacağız. Cloud Shell'de aşağıdaki komutu çalıştırın ve Go sürümünün 1.17 veya üzeri 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 codelab'de, Google Kubernetes Engine'de (GKE) bir mikro hizmet kümesi çalıştıracaksınız. Bu codelab'de süreç aşağıdaki gibidir:
- Temel projeyi Cloud Shell'e indirme
- Container'larda mikro hizmetler derleme
- Kapsayıcıları Google Artifact Registry'ye (GAR) yükleme
- Container'ları GKE'ye dağıtma
- İzleme araçları için hizmetlerin kaynak kodunu değiştirin
- 2. adıma git
Kubernetes Engine'i etkinleştirme
İlk olarak Shakesapp'in GKE'de çalıştığı bir Kubernetes kümesi oluşturmak için GKE'yi etkinleştirmemiz gerekiyor. "Kubernetes Engine" menüsüne gidin 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 altında olduğunu onaylayın. Depo bölgeniz, alt bölgeyi kapsamıyorsa us-central1-f
alt bölge değerini 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. Şimdi, container'ları push ve dağıtma işlemleri için container kaydı için hazırlayacağız. Bu adımlar için bir Artifact Registry (GAR) oluşturmamız ve bunu kullanmak için kaykay yapmamız gerekir.
Artifact Registry kurulumu
"Artifact Registry" menüsüne gidin ETKİNLEŞTİR düğmesine basın.
Bir süre sonra GAR'nin depo tarayıcısını göreceksiniz. "REPOSITORY OLUŞTUR"u tıklayın. düğmesini tıklayın ve deponun adını girin.
Bu codelab'de yeni depoyu trace-codelab
olarak adlandırıyorum. Yapının biçimi "Docker"dır ve konum türü "Bölge" ise. Google Compute Engine varsayılan alt bölgesi için belirlediğinize yakın bölgeyi seçin. Örneğin, bu örnek "us-central1-f"yi seçti Burada "us-central1 (Iowa)"yı seçiyoruz. Ardından "OLUŞTUR"u tıklayın. düğmesini tıklayın.
Artık "trace-codelab"i görüyorsunuz. kod deposunda toplanır.
Kayıt defteri yolunu kontrol etmek için daha sonra buraya geri döneceğiz.
Skaffold kurulumu
Skaffold, Kubernetes üzerinde çalışan mikro hizmetler oluştururken kullanabileceğiniz pratik bir araçtır. Uygulama container'larını oluşturma, aktarma ve dağıtma iş akışını küçük bir komut grubuyla yönetir. Skaffold, container kayıt defteri olarak varsayılan olarak Docker Registry'yi kullanır. Bu nedenle, container'lara aktarılırken GAR'yi tanımak için skaffold'u yapılandırmanız gerekir.
Cloud Shell'i tekrar açın ve skaffold yüklü olup olmadığını onaylayın. (Cloud Shell'i varsayılan olarak ortama yükler.) Aşağıdaki komutu çalıştırarak skaffold sürümünü görebilirsiniz.
skaffold version
Komut çıkışı
v1.38.0
Şimdi, varsayılan depoyu skaf Fold'un kullanması için 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 en altında aşağıdakine benzer bir mesaj içeren bir iletişim kutusu görürsünüz:
"us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab" kopyalandı
Cloud Shell'e geri dönün. Kontrol panelinden kopyaladığınız değerle skaffold config set default-repo
komutunu ç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 yapılandırmanı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 container'ı oluşturma adımına geçebilirsiniz.
Özet
Bu adımda codelab ortamınızı kuracaksınız:
- Cloud Shell'i kurma
- Container kayıt defteri için Artifact Registry deposu oluşturuldu
- Container kayıt defterini kullanmak için skaffold'u ayarlama
- codelab mikro hizmetlerinin çalıştırıldığı bir Kubernetes kümesi oluşturuldu
Sonraki bölüm
Bir sonraki adımda sunucu hizmetinde sürekli profil aracı aracısını kuracaksınız.
3. Mikro hizmetleri derleme, aktarma ve dağıtma
Codelab materyalini indirin
Önceki adımda bu codelab için tüm ön koşulları ayarladık. Artık tüm mikro hizmetleri bunların üzerinde çalıştırmaya hazırsınız. Codelab materyali GitHub'da barındırıldığından aşağıdaki git komutuyla verileri 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
- manifest'ler: Kubernetes manifest dosyaları
- proto: istemci ve sunucu arasındaki iletişimin proto tanımı
- src: her hizmetin kaynak kodu için dizinler
- skaffold.yaml: Skaffold için yapılandırma dosyası
Bu codelab'de, step4
klasörünün altında bulunan kaynak kodunu güncelleyeceksiniz. Baştaki değişiklikler için step[1-6]
klasöründeki kaynak koduna da bakabilirsiniz. (1. Bölüm 0. adımdan 4. adıma, 2. Bölüm 5. ve 6. adımları kapsar)
skaffold komutunu çalıştırma
Artık tüm içeriği derlemeye, aktarmaya ve az önce oluşturduğunuz Kubernetes kümesine dağıtmaya hazırsınız. Bu araç birden fazla adım içeriyormuş gibi görünüyor, ancak gerçek kaykay, her şeyi sizin için yapıyor. Bunu aşağıdaki komutla deneyelim:
cd step4 skaffold dev
Komutu çalıştırır çalıştırmaz docker build
günlük çıkışını görürsünüz ve bunların kayıt defterine başarıyla aktarıldığını 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 container'ları aktarıldı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 container'da stdout'a yayınlanan 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 aşamada, sunucudan gelen tüm iletileri görmek istediğinizi unutmayın. Tamam, nihayet hizmetlerin dağıtılmış izlemesi için OpenTelemetry ile uygulamanıza enstrümantasyon yapmaya hazırsınız.
Hizmetin enstrümantasyonuna başlamadan önce lütfen Ctrl-C tuşlarına basarak 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 patenin beklendiği gibi çalıştığını onayladınız.
Sonraki bölüm
Sonraki adımda iz bilgilerini kullanmak için loadgen hizmetinin kaynak kodunu değiştireceksiniz.
4. Cloud Profiler aracısının kullanımı
Sürekli profil çıkarma kavramı
Sürekli profil çıkarma kavramını açıklamadan önce, öncelikle profil çıkarma kavramını anlamamız gerekir. Profil oluşturma, uygulamayı dinamik olarak analiz etmenin yollarından biridir (dinamik program analizi) ve genellikle yük testi gibi uygulama geliştirme süreçlerinde gerçekleştirilir. Bu, belirli bir dönemdeki CPU ve bellek kullanımları gibi sistem metriklerini ölçmeye yönelik tek bir çekim etkinliğidir. Geliştiriciler, profil verilerini topladıktan sonra bu verileri kod dışında analiz eder.
Sürekli profil oluşturma, normal profil çıkarma için kullanılan genişletilmiş bir yaklaşımdır: Uzun süredir çalışan uygulamada düzenli olarak kısa pencere profilleri çalıştırır ve bir dizi profil verisi toplar. Ardından, uygulamanın belirli bir özelliğine (ör. sürüm numarası, dağıtım bölgesi, ölçüm zamanı) göre istatistiksel analiz otomatik olarak oluşturulur. Bu kavram hakkında ayrıntılı bilgiyi belgelerimizde bulabilirsiniz.
Hedef çalışan bir uygulama olduğundan, profil verilerini düzenli olarak toplamanın ve istatistiksel verileri sonradan işleyen bir arka uca göndermenin bir yolu vardır. Bu, Cloud Profiler aracısıdır. Bu aracı yakında sunucu hizmetine yerleştireceksiniz.
Cloud Profiler aracısı yerleştirme
Cloud Shell'in sağ üst tarafında bulunan düğmeye basarak Cloud Shell Düzenleyici'yi açın. Sol bölmedeki gezginden
step4/src/server/main.go
uygulamasını açın ve ana işlevi bulun.
step4/src/server/main.go
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 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) healthpb.RegisterHealthServer(srv, svc) if err := srv.Serve(lis); err != nil { log.Fatalf("error serving server: %v", err) } }
main
işlevinde, codelab'in 1. bölümünde yapılan OpenTelemetry ve gRPC için bazı kurulum kodları görürsünüz. Şimdi, buraya Cloud Profiler aracısı için araçlar ekleyeceksiniz. Tıpkı initTracer()
için yaptığımız gibi, okunabilirlik için initProfiler()
adlı bir işlev yazabilirsiniz.
step4/src/server/main.go
import ( ... "cloud.google.com/go/profiler" // step5. add profiler package "cloud.google.com/go/storage" ... ) // step5: add Profiler initializer func initProfiler() { cfg := profiler.Config{ Service: "server", ServiceVersion: "1.0.0", NoHeapProfiling: true, NoAllocProfiling: true, NoGoroutineProfiling: true, NoCPUProfiling: false, } if err := profiler.Start(cfg); err != nil { log.Fatalf("failed to launch profiler agent: %v", err) } }
profiler.Config{}
nesnesinde belirtilen seçeneklere yakından bakalım.
- Hizmet: Seçip profil aracı kontrol panelini etkinleştirebileceğiniz hizmet adı
- ServiceVersion: Hizmet sürümünün adı. Profil veri kümelerini bu değere göre karşılaştırabilirsiniz.
- NoHeapProfiling: Bellek tüketimi profili oluşturmayı devre dışı bırakın
- NoAllocProfiling: Bellek ayırma profili oluşturmayı devre dışı bırak
- NoGoroutineProfiling: Gorutin profili oluşturmayı devre dışı bırakın
- NoCPUProfiling: CPU profili oluşturmayı devre dışı bırakın
Bu codelab'de yalnızca CPU profili oluşturmayı etkinleştireceğiz.
Şimdi yapmanız gereken, bu işlevi main
işlevinde çağırmaktır. Cloud Profiler paketini içe aktarma bloğundaki içe aktardığınızdan emin olun.
step4/src/server/main.go
func main() { ... defer func() { if err := tp.Shutdown(context.Background()); err != nil { log.Fatalf("error shutting down TracerProvider: %v", err) } }() // step2. end setup // step5. start profiler go initProfiler() // step5. end svc := NewServerService() // step2: add interceptor ... }
initProfiler()
işlevini go
anahtar kelimesiyle çağırdığınızı unutmayın. Çünkü profiler.Start()
blokları nedeniyle başka bir gorutte çalıştırmanız gerekiyor. Artık yapı oluşturmaya hazır. go mod tidy
uygulamasını dağıtımdan önce çalıştırdığınızdan emin olun.
go mod tidy
Şimdi kümenizi yeni sunucu hizmetinizle dağıtın.
skaffold dev
Cloud Profiler'da flame grafiğini görmek genellikle birkaç dakika sürer. "Profil oluşturucu" yazın yazıp Profil Aracı simgesini tıklayın.
Aşağıdaki flame grafiğini görürsünüz.
Özet
Bu adımda, sunucu hizmetine Cloud Profiler aracısını yerleştirdiniz ve bu aracın flame grafiği oluşturduğunu onayladınız.
Sonraki bölüm
Bir sonraki adımda, alev grafiğiyle uygulamadaki performans sorununun nedenini araştıracaksınız.
5. Cloud Profiler flame grafiğini analiz etme
Flame Graph nedir?
Flame Graph, profil verilerini görselleştirmenin yollarından biridir. Ayrıntılı açıklama için lütfen dokümanımıza göz atın. Ancak kısa özet:
- Her çubuk, uygulamadaki yöntemi/işlev çağrısını ifade eder
- Dikey yön, çağrı yığınıdır. çağrı yığını yukarıdan aşağıya doğru büyür
- Yatay yön, kaynak kullanımını gösterir. ne kadar uzun olursa o kadar kötü olur.
Bunu göz önünde bulundurarak, elde edilen flame grafiğine bakalım.
Alev Grafiği Analizi
Önceki bölümde, flame grafiğindeki her çubuğun işlev/yöntem çağrısını ifade ettiğini ve bu çağrının uzunluğunun işlev/yöntemdeki kaynak kullanımını ifade ettiğini öğrendiniz. Cloud Profiler'ın flame grafiği, çubuğu azalan düzende veya uzunluğu soldan sağa doğru sıralar. Önce grafiğin sol üst kısmına bakmaya başlayabilirsiniz.
Örneğimizde, en çok CPU zamanının grpc.(*Server).serveStreams.func1.2
olduğu ve çağrı yığınına yukarıdan aşağıya doğru bakıldığında, çoğu zaman sunucu hizmetindeki gRPC sunucu işleyici olan main.(*serverService).GetMatchCount
ürününde geçirildiği açıkça görülmektedir.
GetMatchCount altında bir dizi regexp işlevi görürsünüz: regexp.MatchString
ve regexp.Compile
. Bu ürünler standart paket kapsamındadır. Yani, performans dahil olmak üzere birçok açıdan iyi test edilmelidir. Ancak buradaki sonuç regexp.MatchString
ve regexp.Compile
için CPU zaman kaynağı kullanımının yüksek olduğunu gösterir. Bu gerçekler ışığında, regexp.MatchString
kullanımının performans sorunlarıyla ilgili olduğu varsayılmıştır. Şimdi işlevin kullanıldığı kaynak kodunu okuyalım.
step4/src/server/main.go
func (s *serverService) GetMatchCount(ctx context.Context, req *shakesapp.ShakespeareRequest) (*shakesapp.ShakespeareResponse, error) { resp := &shakesapp.ShakespeareResponse{} texts, err := readFiles(ctx, bucketName, bucketPrefix) if err != nil { return resp, fmt.Errorf("fails to read files: %s", err) } for _, text := range texts { for _, line := range strings.Split(text, "\n") { line, query := strings.ToLower(line), strings.ToLower(req.Query) isMatch, err := regexp.MatchString(query, line) if err != nil { return resp, err } if isMatch { resp.MatchCount++ } } } return resp, nil }
regexp.MatchString
bu yere çağrılıyor. Kaynak kodunu okuduğunuzda işlevin iç içe yerleştirilmiş "for-loop"un içinde çağrıldığını görebilirsiniz. Bu nedenle bu işlevin kullanımı yanlış olabilir. regexp'in GoDoc bölümünü arayalım.
Belgeye göre regexp.MatchString
, her çağrıda normal ifade kalıbını derler. Yani yüksek kaynak tüketiminin nedeni bu şekildedir.
Özet
Bu adımda flame grafiğini analiz ederek kaynak tüketiminin nedeninin varsayımını yaptınız.
Sonraki bölüm
Sonraki adımda sunucu hizmetinin kaynak kodunu güncelleyecek ve 1.0.0 sürümündeki değişikliği onaylayacaksınız.
6. Kaynak kodu güncelleme ve flame grafiklerini karşılaştırma
Kaynak kodu güncelleme
Önceki adımda, regexp.MatchString
kullanımının büyük miktarda kaynak tüketimiyle ilişkili olduğunu varsaydınız. Bu sorunu çözelim. Kodu açın ve o kısmı biraz değiştirin.
step4/src/server/main.go
func (s *serverService) GetMatchCount(ctx context.Context, req *shakesapp.ShakespeareRequest) (*shakesapp.ShakespeareResponse, error) { resp := &shakesapp.ShakespeareResponse{} texts, err := readFiles(ctx, bucketName, bucketPrefix) if err != nil { return resp, fmt.Errorf("fails to read files: %s", err) } // step6. considered the process carefully and naively tuned up by extracting // regexp pattern compile process out of for loop. query := strings.ToLower(req.Query) re := regexp.MustCompile(query) for _, text := range texts { for _, line := range strings.Split(text, "\n") { line = strings.ToLower(line) isMatch := re.MatchString(line) // step6. done replacing regexp with strings if isMatch { resp.MatchCount++ } } } return resp, nil }
Gördüğünüz gibi, regexp kalıbı derleme işlemi regexp.MatchString
öğesinden alınıp iç içe yerleştirilmiş "for" döngüsünden çıkarılır.
Bu kodu dağıtmadan önce initProfiler()
işlevindeki sürüm dizesini güncellediğinizden emin olun.
step4/src/server/main.go
func initProfiler() { cfg := profiler.Config{ Service: "server", ServiceVersion: "1.1.0", // step6. update version NoHeapProfiling: true, NoAllocProfiling: true, NoGoroutineProfiling: true, NoCPUProfiling: false, } if err := profiler.Start(cfg); err != nil { log.Fatalf("failed to launch profiler agent: %v", err) } }
Şimdi, bunun nasıl çalıştığına bakalım. Kümeyi skaffold komutuyla dağıtın.
skaffold dev
Bir süre sonra Cloud Profiler kontrol panelini yeniden yükleyerek durumu inceleyin.
Yalnızca 1.1.0 sürümündeki profilleri görmek için sürümü "1.1.0"
olarak değiştirdiğinizden emin olun. Sizin de bildiğiniz gibi, GetMatchCount çubuğunun uzunluğu ve CPU süresinin kullanım oranı azaldı (yani, çubuk kısaldı).
Sadece tek bir sürümün flame grafiğine bakarak değil, iki sürüm arasındaki farkları da karşılaştırabilirsiniz.
"Şununla karşılaştır" değerini değiştirme açılır listeden "Sürüm"e ve "Karşılaştırılan sürüm" değerini değiştirebilirsiniz. "1.0.0" olan yeni bir sürüme güncelleyin.
Bu tür bir flame grafiği görürsünüz. Grafiğin şekli 1.1.0 ile aynıdır ancak renklendirme farklıdır. Karşılaştırma modunda renk şu anlama gelir:
- Mavi: Azalan değer (kaynak tüketimi)
- Turuncu: Kazanılan değer (kaynak tüketimi)
- Gri: nötr
Açıklamaları göz önünde bulundurarak, işleve daha yakından bakalım. Yakınlaştırmak istediğiniz çubuğu tıklayarak grubun içindeki daha fazla ayrıntıyı görebilirsiniz. Lütfen main.(*serverService).GetMatchCount
çubuğu tıklayın. Ayrıca, fareyle çubuğun üzerine geldiğinizde karşılaştırmanın ayrıntılarını görürsünüz.
Burada toplam CPU süresinin 5,26 saniyeden 2,88 saniyeye düşürüldüğü yazıyor (toplam 10 sn = örnekleme aralığı). Bu muazzam bir gelişme.
Artık profil verilerinin analizinden uygulamanızın performansını artırabilirsiniz.
Özet
Bu adımda, sunucu hizmetinde bir düzenleme yaptınız ve Cloud Profiler'ın karşılaştırma modundaki iyileştirmeyi onayladınız.
Sonraki bölüm
Sonraki adımda sunucu hizmetinin kaynak kodunu güncelleyecek ve 1.0.0 sürümündeki değişikliği onaylayacaksınız.
7. Ek adım: Trace şelalesinde iyileştirmeyi onaylayın
Dağıtılmış izleme ve sürekli profil oluşturma arasındaki fark
Codelab'in 1. bölümünde, bir istek yolu için mikro hizmetler genelinde performans sorunu hizmetini çözebileceğinizi ve ilgili hizmetteki performans sorununun tam nedenini çözemediğinizi onayladınız. Bu 2. bölümde codelab'de, sürekli profil çıkarmanın tek bir hizmetteki sorunu çağrı yığınlarından tespit etmenize olanak tanıdığını öğrendiniz.
Bu adımda, dağıtılmış izdeki (Cloud Trace) şelale grafiğini inceleyip sürekli profil çıkarma ile arasındaki farkı inceleyelim.
Bu şelale grafiği, "aşk" sorgusunu içeren izlerden biridir. Toplamda yaklaşık 6,7 sn (6.700 ms) sürüyor.
Bu adım, aynı sorgu için yapılan iyileştirme sonrasında gelir. Sizin de bildiğiniz gibi toplam gecikme 1, 5 sn (1500 ms) oldu.Bu değer, önceki uygulamaya kıyasla büyük bir iyileşmedir.
Buradaki önemli nokta, araç dünyanın her yerine yayıldığı sürece dağıtılmış iz şelale grafiğinde çağrı yığını bilgilerinin kullanılamamasıdır. Ayrıca, dağıtılmış izler yalnızca hizmetlerdeki gecikmeye odaklanırken, sürekli profil çıkarma işlemi tek bir hizmetin bilgisayar kaynaklarına (CPU, bellek, işletim sistemi iş parçacıkları) odaklanır.
Bir başka açıdan bakıldığında, dağıtılmış iz etkinlik temelidir, sürekli profil ise istatistikseldir. Her iz farklı bir gecikme grafiğine sahiptir ve gecikme değişikliklerinin trendini öğrenmek için dağıtım gibi farklı bir biçime ihtiyacınız vardır.
Özet
Bu adımda, dağıtılmış izleme ve sürekli profil oluşturma arasındaki farkı kontrol ettiniz.
8. Tebrikler
OpenTelemery ile dağıtılmış izleri başarıyla oluşturdunuz ve Google Cloud Trace'te mikro hizmetteki istek gecikmelerini onayladınız.
Genişletilmiş egzersizler 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 Traces'te nasıl filtrelersiniz? İpucuna buradan ulaşabilirsiniz. - Olay günlüklerini aralıklarla ilişkilendirin ve Google Cloud Trace ve Google Cloud Logging'de nasıl çalıştığını öğrenin. İpucuna buradan ulaşabilirsiniz.
- Bazı hizmetleri başka bir dildeki bir hizmetle değiştirin ve söz konusu dil için OpenTelemetry ile enstrümantasyon yöntemini kullanmayı deneyin.
Ayrıca, bundan sonra profil oluşturucu hakkında daha fazla bilgi edinmek isterseniz lütfen 2. bölüme geçin. Bu durumda, aşağıdaki temizleme bölümünü atlayabilirsiniz.
Temizleme
Bu codelab'den sonra Google Kubernetes Engine, Google Cloud Trace ve Google Artifact Registry'de beklenmedik ücretlerle karşılaşmamak için lütfen Kubernetes kümesini durdurun ve projeyi sildiğinizden emin olun.
İlk olarak 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ölmesinden "IAM ve Yönetici" > "Ayarlar"ı, ardından "KAPALI"yı tıklayın. düğmesini tıklayın.
Ardından iletişim kutusundaki forma Proje Kimliği'ni (Proje Adı'nı değil) girin ve kapatmayı onaylayın.