1. परिचय

पिछला अपडेट: 14-07-2022
ऐप्लिकेशन की निगरानी करने की सुविधा
Observability और Continuous Profiler
ऑब्ज़र्वेबिलिटी, किसी सिस्टम की एक विशेषता होती है. ऑब्ज़र्वेबिलिटी की सुविधा वाले सिस्टम की मदद से, टीमें अपने सिस्टम को आसानी से डीबग कर सकती हैं. इस संदर्भ में, सिस्टम के लिए लॉग, मेट्रिक, और ट्रेस, ऑब्ज़र्वेबिलिटी के तीन मुख्य पिलर हैं.
इसके अलावा, ऑब्ज़र्वेबिलिटी के तीन मुख्य सिद्धांतों के साथ-साथ, लगातार प्रोफ़ाइलिंग करना भी ऑब्ज़र्वेबिलिटी का एक और मुख्य कॉम्पोनेंट है. साथ ही, यह इंडस्ट्री में उपयोगकर्ताओं की संख्या बढ़ा रहा है. Cloud Profiler, परफ़ॉर्मेंस मेट्रिक को जनरेट करने वाले टूल में से एक है. यह ऐप्लिकेशन कॉल स्टैक में परफ़ॉर्मेंस मेट्रिक की बारीकी से जांच करने के लिए, आसान इंटरफ़ेस उपलब्ध कराता है.
यह कोडलैब, सीरीज़ का दूसरा हिस्सा है. इसमें लगातार प्रोफ़ाइलिंग करने वाले एजेंट को इंस्ट्रुमेंट करने के बारे में बताया गया है. पहले हिस्से में, OpenTelemetry और Cloud Trace की मदद से डिस्ट्रिब्यूटेड ट्रेसिंग के बारे में बताया गया है. साथ ही, इसमें यह भी बताया गया है कि पहले हिस्से की मदद से, माइक्रोसर्विस की परफ़ॉर्मेंस में आने वाली रुकावटों की पहचान कैसे की जा सकती है.
आपको क्या बनाने को मिलेगा
इस कोडलैब में, आपको Google Kubernetes Engine क्लस्टर पर चलने वाले "Shakespeare application" (इसे Shakesapp भी कहा जाता है) की सर्वर सेवा में, कंटीन्यूअस प्रोफ़ाइलर एजेंट को इंस्ट्रूमेंट करना है. Shakesapp का आर्किटेक्चर इस तरह है:

- Loadgen, क्लाइंट को एचटीटीपी में क्वेरी स्ट्रिंग भेजता है
- क्लाइंट, gRPC में लोडजन से सर्वर तक क्वेरी पास करते हैं
- सर्वर, क्लाइंट से मिली क्वेरी को स्वीकार करता है. इसके बाद, Google Cloud Storage से शेक्सपियर की सभी रचनाओं को टेक्स्ट फ़ॉर्मैट में फ़ेच करता है. इसके बाद, क्वेरी से मिलती-जुलती लाइनों को खोजता है और क्लाइंट को उन लाइनों की संख्या दिखाता है
पहले हिस्से में, आपको पता चला कि सर्वर सेवा में कहीं कोई समस्या है. हालांकि, आपको इसकी सटीक वजह का पता नहीं चल सका.
आपको क्या सीखने को मिलेगा
- प्रोफ़ाइलर एजेंट को एम्बेड करने का तरीका
- Cloud Profiler पर बॉटलनेक की जांच करने का तरीका
इस कोडलैब में, आपके ऐप्लिकेशन में लगातार प्रोफ़ाइलर एजेंट को इंस्ट्रुमेंट करने का तरीका बताया गया है.
आपको इन चीज़ों की ज़रूरत होगी
- Go की बुनियादी जानकारी
- Kubernetes की बुनियादी जानकारी
2. सेटअप और ज़रूरी शर्तें
अपने हिसाब से एनवायरमेंट सेट अप करना
अगर आपके पास पहले से कोई Google खाता (Gmail या Google Apps) नहीं है, तो आपको एक खाता बनाना होगा. Google Cloud Platform Console ( console.cloud.google.com) में साइन इन करें और एक नया प्रोजेक्ट बनाएं.
अगर आपके पास पहले से कोई प्रोजेक्ट है, तो कंसोल में सबसे ऊपर बाईं ओर मौजूद, प्रोजेक्ट चुनने वाले पुल-डाउन मेन्यू पर क्लिक करें:

इसके बाद, नया प्रोजेक्ट बनाने के लिए, डायलॉग बॉक्स में मौजूद ‘नया प्रोजेक्ट' बटन पर क्लिक करें:

अगर आपके पास पहले से कोई प्रोजेक्ट नहीं है, तो आपको अपना पहला प्रोजेक्ट बनाने के लिए इस तरह का डायलॉग दिखेगा:

इसके बाद, प्रोजेक्ट बनाने के डायलॉग बॉक्स में, नए प्रोजेक्ट की जानकारी डाली जा सकती है:

प्रोजेक्ट आईडी याद रखें. यह सभी Google Cloud प्रोजेक्ट के लिए एक यूनीक नाम होता है. ऊपर दिया गया नाम पहले ही इस्तेमाल किया जा चुका है. इसलिए, यह आपके लिए काम नहीं करेगा. माफ़ करें! इसे इस कोडलैब में बाद में PROJECT_ID के तौर पर दिखाया जाएगा.
इसके बाद, अगर आपने अब तक ऐसा नहीं किया है, तो आपको Google Cloud के संसाधनों का इस्तेमाल करने के लिए, Developers Console में बिलिंग चालू करनी होगी. साथ ही, Cloud Trace API चालू करना होगा.

इस कोडलैब को पूरा करने में आपको कुछ डॉलर से ज़्यादा खर्च नहीं करने पड़ेंगे. हालांकि, अगर आपको ज़्यादा संसाधनों का इस्तेमाल करना है या उन्हें चालू रखना है, तो यह खर्च बढ़ सकता है. इस दस्तावेज़ के आखिर में "सफाई" सेक्शन देखें. Google Cloud Trace, Google Kubernetes Engine, और Google Artifact Registry की कीमतों के बारे में आधिकारिक दस्तावेज़ में बताया गया है.
- Google Cloud के कार्रवाइयों वाले सुइट की कीमत | कार्रवाइयों वाला सुइट
- कीमत | Kubernetes Engine के दस्तावेज़
- Artifact Registry की कीमत | Artifact Registry का दस्तावेज़
Google Cloud Platform के नए उपयोगकर्ताओं को, मुफ़्त में आज़माने के लिए 300 डॉलर मिलते हैं. इससे इस कोडलैब का इस्तेमाल बिना किसी शुल्क के किया जा सकता है.
Google Cloud Shell सेटअप करना
Google Cloud और Google Cloud Trace को अपने लैपटॉप से रिमोटली ऐक्सेस किया जा सकता है. हालांकि, इस कोडलैब में हम Google Cloud Shell का इस्तेमाल करेंगे. यह क्लाउड में चलने वाला कमांड लाइन एनवायरमेंट है.
यह Debian पर आधारित वर्चुअल मशीन है. इसमें डेवलपमेंट के लिए ज़रूरी सभी टूल पहले से मौजूद हैं. यह 5 जीबी की होम डायरेक्ट्री उपलब्ध कराता है और Google Cloud में चलता है. इससे नेटवर्क की परफ़ॉर्मेंस और पुष्टि करने की प्रोसेस बेहतर होती है. इसका मतलब है कि इस कोडलैब के लिए, आपको सिर्फ़ एक ब्राउज़र की ज़रूरत होगी. हां, यह Chromebook पर भी काम करता है.
Cloud Console से Cloud Shell को चालू करने के लिए, बस Cloud Shell चालू करें
पर क्लिक करें. इसे चालू होने और एनवायरमेंट से कनेक्ट होने में कुछ ही समय लगता है.


Cloud Shell से कनेक्ट होने के बाद, आपको दिखेगा कि आपकी पुष्टि पहले ही हो चुकी है और प्रोजेक्ट पहले से ही आपके PROJECT_ID पर सेट है.
gcloud auth list
कमांड आउटपुट
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
कमांड आउटपुट
[core] project = <PROJECT_ID>
अगर किसी वजह से प्रोजेक्ट सेट नहीं है, तो यह कमांड दें:
gcloud config set project <PROJECT_ID>
क्या आपको PROJECT_ID की तलाश है? देखें कि आपने सेटअप के दौरान किस आईडी का इस्तेमाल किया था या Cloud Console के डैशबोर्ड में जाकर इसे देखें:

Cloud Shell, कुछ एनवायरमेंट वैरिएबल को डिफ़ॉल्ट रूप से भी सेट करता है. ये वैरिएबल, आने वाले समय में कमांड चलाने के दौरान आपके काम आ सकते हैं.
echo $GOOGLE_CLOUD_PROJECT
कमांड आउटपुट
<PROJECT_ID>
आखिर में, डिफ़ॉल्ट ज़ोन और प्रोजेक्ट कॉन्फ़िगरेशन सेट करें.
gcloud config set compute/zone us-central1-f
आपके पास अलग-अलग ज़ोन चुनने का विकल्प होता है. ज़्यादा जानकारी के लिए, रीजन और ज़ोन देखें.
Go भाषा का सेटअप
इस कोडलैब में, हम सभी सोर्स कोड के लिए Go का इस्तेमाल करते हैं. Cloud Shell पर यहां दिया गया निर्देश चलाएं और पुष्टि करें कि Go का वर्शन 1.17 या इसके बाद का है या नहीं
go version
कमांड आउटपुट
go version go1.18.3 linux/amd64
Google Kubernetes Cluster सेट अप करना
इस कोडलैब में, Google Kubernetes Engine (GKE) पर माइक्रोसेवाओं का क्लस्टर चलाया जाएगा. इस कोडलैब की प्रोसेस इस तरह है:
- बेसलाइन प्रोजेक्ट को Cloud Shell में डाउनलोड करें
- कंटेनर में माइक्रोसेवाएं बनाना
- कंटेनर को Google Artifact Registry (GAR) पर अपलोड करना
- GKE पर कंटेनर डिप्लॉय करना
- ट्रेस इंस्ट्रूमेंटेशन के लिए, सेवाओं के सोर्स कोड में बदलाव करना
- दूसरे चरण पर जाएं
Kubernetes Engine चालू करें
सबसे पहले, हम एक Kubernetes क्लस्टर सेट अप करते हैं. इसमें Shakesapp, GKE पर चलता है. इसलिए, हमें GKE को चालू करना होगा. "Kubernetes Engine" मेन्यू पर जाएं और ENABLE बटन दबाएं.

अब आपके पास Kubernetes क्लस्टर बनाने का विकल्प है.
Kubernetes क्लस्टर बनाना
Kubernetes क्लस्टर बनाने के लिए, Cloud Shell पर यह कमांड चलाएं. कृपया पुष्टि करें कि ज़ोन की वैल्यू उस क्षेत्र के हिसाब से है जिसका इस्तेमाल Artifact Registry रिपॉज़िटरी बनाने के लिए किया जाएगा. अगर आपकी रिपॉज़िटरी का क्षेत्र, ज़ोन में शामिल नहीं है, तो ज़ोन की वैल्यू us-central1-f बदलें.
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
कमांड आउटपुट
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 और skaffold सेटअप करना
अब हमारे पास डिप्लॉयमेंट के लिए तैयार Kubernetes क्लस्टर है. इसके बाद, हम कंटेनर को पुश और डिप्लॉय करने के लिए, कंटेनर रजिस्ट्री तैयार करते हैं. इन चरणों के लिए, हमें Artifact Registry (GAR) सेट अप करना होगा. साथ ही, इसका इस्तेमाल करने के लिए skaffold सेट अप करना होगा.
Artifact Registry का सेटअप
"Artifact Registry" के मेन्यू पर जाएं और 'चालू करें' बटन दबाएं.

कुछ समय बाद, आपको GAR का रिपॉज़िटरी ब्राउज़र दिखेगा. "CREATE REPOSITORY" बटन पर क्लिक करें और रिपॉज़िटरी का नाम डालें.

इस कोडलैब में, मैंने नई रिपॉज़िटरी का नाम trace-codelab रखा है. आर्टफ़ैक्ट का फ़ॉर्मैट "Docker" है और लोकेशन का टाइप "Region" है. Google Compute Engine के डिफ़ॉल्ट ज़ोन के लिए सेट किए गए क्षेत्र के आस-पास का क्षेत्र चुनें. उदाहरण के लिए, ऊपर दिए गए उदाहरण में "us-central1-f" चुना गया है. इसलिए, यहां हम "us-central1 (Iowa)" चुनते हैं. इसके बाद, "बनाएं" बटन पर क्लिक करें.

अब आपको रिपॉज़िटरी ब्राउज़र पर "trace-codelab" दिखेगा.

हम रजिस्ट्री पाथ की जांच करने के लिए, बाद में इस पेज पर वापस आएंगे.
Skaffold सेट अप करना
Skaffold एक ऐसा टूल है जो Kubernetes पर चलने वाली माइक्रोसर्विस बनाने में आपकी मदद करता है. यह ऐप्लिकेशन के कंटेनर बनाने, उन्हें पुश करने, और डिप्लॉय करने के वर्कफ़्लो को मैनेज करता है. इसके लिए, कुछ ही कमांड का इस्तेमाल किया जाता है. Skaffold डिफ़ॉल्ट रूप से, Docker Registry को कंटेनर रजिस्ट्री के तौर पर इस्तेमाल करता है. इसलिए, आपको Skaffold को कॉन्फ़िगर करना होगा, ताकि वह कंटेनर को GAR पर पुश कर सके.
Cloud Shell को फिर से खोलें और पुष्टि करें कि Skaffold इंस्टॉल है या नहीं. (Cloud Shell, डिफ़ॉल्ट रूप से एनवायरमेंट में skaffold इंस्टॉल करता है.) यहां दिया गया कमांड चलाएं और Skaffold का वर्शन देखें.
skaffold version
कमांड आउटपुट
v1.38.0
अब, skaffold के इस्तेमाल के लिए डिफ़ॉल्ट रिपॉज़िटरी रजिस्टर की जा सकती है. रजिस्ट्री पाथ पाने के लिए, Artifact Registry के डैशबोर्ड पर जाएं. इसके बाद, उस रिपॉज़िटरी के नाम पर क्लिक करें जिसे आपने पिछले चरण में सेट अप किया था.

इसके बाद, आपको पेज के सबसे ऊपर ब्रेडक्रंब ट्रेल दिखेगी. क्लिपबोर्ड पर रजिस्ट्री पाथ कॉपी करने के लिए,
आइकॉन पर क्लिक करें.

'कॉपी करें' बटन पर क्लिक करने पर, आपको ब्राउज़र में सबसे नीचे यह डायलॉग दिखेगा:
"us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab" को कॉपी किया गया
क्लाउड शेल पर वापस जाएं. डैशबोर्ड से अभी कॉपी किए गए मान के साथ skaffold config set default-repo कमांड चलाएं.
skaffold config set default-repo us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab
कमांड आउटपुट
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
इसके अलावा, आपको रजिस्ट्री को Docker कॉन्फ़िगरेशन के लिए कॉन्फ़िगर करना होगा. यह कमांड चलाएं:
gcloud auth configure-docker us-central1-docker.pkg.dev --quiet
कमांड आउटपुट
{
"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
अब GKE पर Kubernetes कंटेनर सेट अप करने के लिए, अगले चरण पर जाएं.
खास जानकारी
इस चरण में, आपको कोडलैब एनवायरमेंट सेट अप करना होगा:
- Cloud Shell सेट अप करना
- कंटेनर रजिस्ट्री के लिए, Artifact Registry रिपॉज़िटरी बनाई गई
- कंटेनर रजिस्ट्री का इस्तेमाल करने के लिए, skaffold सेट अप करना
- Kubernetes क्लस्टर बनाया गया है, जहां कोडलैब की माइक्रोसेवाएं चलती हैं
आगे बढ़ें
अगले चरण में, आपको सर्वर सेवा में कंटीन्यूअस प्रोफ़ाइलर एजेंट को इंस्ट्रूमेंट करना होगा.
3. माइक्रोसर्विसेज़ को बनाएं, पुश करें, और डिप्लॉय करें
कोडलैब का मटीरियल डाउनलोड करना
पिछले चरण में, हमने इस कोडलैब के लिए सभी ज़रूरी शर्तें सेट अप की हैं. अब इन पर पूरी माइक्रोसेवाएँ चलाई जा सकती हैं. कोड लैब का मटीरियल GitHub पर होस्ट किया गया है. इसलिए, इसे Cloud Shell एनवायरमेंट में डाउनलोड करने के लिए, यहां दिया गया git कमांड इस्तेमाल करें.
cd ~ git clone https://github.com/ymotongpoo/opentelemetry-trace-codelab-go.git cd opentelemetry-trace-codelab-go
प्रोजेक्ट का डायरेक्ट्री स्ट्रक्चर इस तरह है:
.
├── 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
- मेनिफ़ेस्ट: Kubernetes मेनिफ़ेस्ट फ़ाइलें
- proto: क्लाइंट और सर्वर के बीच कम्यूनिकेशन के लिए प्रोटो परिभाषा
- src: हर सेवा के सोर्स कोड के लिए डायरेक्ट्री
- skaffold.yaml: skaffold के लिए कॉन्फ़िगरेशन फ़ाइल
इस कोडलैब में, आपको step4 फ़ोल्डर में मौजूद सोर्स कोड को अपडेट करना होगा. शुरुआत से ही बदलावों के बारे में जानने के लिए, step[1-6] फ़ोल्डर में मौजूद सोर्स कोड भी देखा जा सकता है. (पहले हिस्से में चरण 0 से चरण 4 तक की जानकारी दी गई है. वहीं, दूसरे हिस्से में चरण 5 और 6 के बारे में बताया गया है)
skaffold कमांड चलाना
आखिर में, आपके पास अभी बनाए गए Kubernetes क्लस्टर पर पूरा कॉन्टेंट बनाने, पुश करने, और डिप्लॉय करने का विकल्प होता है. ऐसा लगता है कि इसमें कई चरण शामिल हैं, लेकिन असल में Skaffold आपके लिए सब कुछ करता है. आइए, इस कमांड का इस्तेमाल करके देखते हैं:
cd step4 skaffold dev
कमांड चलाने के तुरंत बाद, आपको docker build का लॉग आउटपुट दिखता है. इससे पुष्टि की जा सकती है कि उन्हें रजिस्ट्री में पुश कर दिया गया है.
कमांड आउटपुट
... ---> 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
सभी सेवा कंटेनर पुश करने के बाद, Kubernetes डिप्लॉयमेंट अपने-आप शुरू हो जाते हैं.
कमांड आउटपुट
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
डप्लॉयमेंट के बाद, आपको हर कंटेनर में stdout पर भेजे गए ऐप्लिकेशन के असली लॉग इस तरह दिखेंगे:
कमांड आउटपुट
[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
ध्यान दें कि इस समय, आपको सर्वर से मिले सभी मैसेज देखने हैं. ठीक है, अब आप सेवाओं की डिस्ट्रिब्यूटेड ट्रेसिंग के लिए, OpenTelemetry की मदद से अपने ऐप्लिकेशन को इंस्ट्रुमेंट करने के लिए तैयार हैं.
सेवा को इंस्ट्रुमेंट करना शुरू करने से पहले, कृपया Ctrl-C दबाकर अपने क्लस्टर को बंद करें.
कमांड आउटपुट
...
[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
खास जानकारी
इस चरण में, आपने अपने एनवायरमेंट में कोडलैब का मटीरियल तैयार कर लिया है. साथ ही, आपने पुष्टि कर ली है कि Skaffold उम्मीद के मुताबिक काम कर रहा है.
आगे बढ़ें
अगले चरण में, ट्रेस की जानकारी को इंस्ट्रुमेंट करने के लिए, लोडजन सेवा के सोर्स कोड में बदलाव करें.
4. Cloud Profiler एजेंट का इंस्ट्रूमेंटेशन
लगातार प्रोफ़ाइलिंग का कॉन्सेप्ट
लगातार प्रोफ़ाइलिंग के कॉन्सेप्ट को समझने से पहले, हमें प्रोफ़ाइलिंग के कॉन्सेप्ट को समझना होगा. प्रोफ़ाइलिंग, ऐप्लिकेशन का डाइनैमिक तरीके से विश्लेषण करने का एक तरीका है. इसे डाइनैमिक प्रोग्राम विश्लेषण भी कहा जाता है. आम तौर पर, इसे ऐप्लिकेशन डेवलपमेंट के दौरान लोड टेस्टिंग वगैरह की प्रोसेस में किया जाता है. यह एक बार की जाने वाली गतिविधि है. इससे किसी खास अवधि के दौरान, सीपीयू और मेमोरी के इस्तेमाल जैसी सिस्टम मेट्रिक को मेज़र किया जाता है. प्रोफ़ाइल का डेटा इकट्ठा करने के बाद, डेवलपर कोड के बाहर उनका विश्लेषण करते हैं.
लगातार प्रोफ़ाइलिंग, सामान्य प्रोफ़ाइलिंग का ही एक बेहतर तरीका है: यह लंबे समय तक चलने वाले ऐप्लिकेशन के लिए, समय-समय पर छोटी विंडो प्रोफ़ाइल चलाता है और प्रोफ़ाइल का डेटा इकट्ठा करता है. इसके बाद, यह ऐप्लिकेशन की किसी एट्रिब्यूट के आधार पर, आंकड़ों का विश्लेषण अपने-आप जनरेट करता है. जैसे, वर्शन नंबर, डिप्लॉयमेंट ज़ोन, मेज़रमेंट का समय वगैरह. आपको इस कॉन्सेप्ट के बारे में ज़्यादा जानकारी हमारे दस्तावेज़ में मिलेगी.
टारगेट एक चालू ऐप्लिकेशन है. इसलिए, प्रोफ़ाइल डेटा को समय-समय पर इकट्ठा किया जा सकता है. साथ ही, इसे ऐसे बैकएंड पर भेजा जा सकता है जो आंकड़ों वाले डेटा को प्रोसेस करता है. यह Cloud Profiler एजेंट है और आपको इसे जल्द ही सर्वर सेवा में एम्बेड करना होगा.
Cloud Profiler एजेंट को एम्बेड करना
Cloud Shell के सबसे ऊपर दाईं ओर मौजूद,
बटन दबाकर Cloud Shell Editor खोलें. बाएं पैनल में मौजूद एक्सप्लोरर से step4/src/server/main.go खोलें और मुख्य फ़ंक्शन ढूंढें.
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 फ़ंक्शन में, आपको OpenTelemetry और gRPC के लिए कुछ सेटअप कोड दिखता है. यह कोड, कोडलैब के पहले हिस्से में सेट अप किया गया है. अब आपको यहां Cloud Profiler एजेंट के लिए इंस्ट्रुमेंटेशन जोड़ना होगा. हमने initTracer() के लिए जो किया है उसी तरह, आसानी से पढ़ने के लिए initProfiler() नाम का फ़ंक्शन लिखा जा सकता है.
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{} ऑब्जेक्ट में दिए गए विकल्पों के बारे में ज़्यादा जानें.
- सेवा: सेवा का वह नाम जिसे चुना जा सकता है और जिसे प्रोफ़ाइलर डैशबोर्ड पर चालू किया जा सकता है
- ServiceVersion: सेवा के वर्शन का नाम. इस वैल्यू के आधार पर, प्रोफ़ाइल के डेटा सेट की तुलना की जा सकती है.
- NoHeapProfiling: मेमोरी के इस्तेमाल की प्रोफ़ाइल बनाने की सुविधा बंद करें
- NoAllocProfiling: मेमोरी के बंटवारे की प्रोफ़ाइल बनाने की सुविधा बंद करें
- NoGoroutineProfiling: goroutine की प्रोफ़ाइल बनाने की सुविधा बंद करें
- NoCPUProfiling: सीपीयू प्रोफ़ाइलिंग बंद करें
इस कोडलैब में, हम सिर्फ़ सीपीयू प्रोफ़ाइलिंग की सुविधा चालू करते हैं.
अब आपको इस फ़ंक्शन को main फ़ंक्शन में कॉल करना होगा. पक्का करें कि आपने इंपोर्ट ब्लॉक में Cloud Profiler पैकेज इंपोर्ट किया हो.
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
...
}
ध्यान दें कि go कीवर्ड के साथ initProfiler() फ़ंक्शन को कॉल किया जा रहा है. क्योंकि profiler.Start() ब्लॉक करता है. इसलिए, आपको इसे किसी दूसरी goroutine में चलाना होगा. अब इसे बनाया जा सकता है. पक्का करें कि आपने डिप्लॉयमेंट से पहले go mod tidy को चला लिया हो.
go mod tidy
अब अपनी नई सर्वर सेवा के साथ क्लस्टर को डिप्लॉय करें.
skaffold dev
Cloud Profiler पर फ़्लेम ग्राफ़ दिखने में आम तौर पर कुछ मिनट लगते हैं. सबसे ऊपर मौजूद खोज बॉक्स में "प्रोफ़ाइलर" टाइप करें. इसके बाद, प्रोफ़ाइलर के आइकॉन पर क्लिक करें.

इसके बाद, आपको यह फ़्लेम ग्राफ़ दिखेगा.

खास जानकारी
इस चरण में, आपने सर्वर सेवा में Cloud Profiler एजेंट को एम्बेड किया और पुष्टि की कि यह फ़्लेम ग्राफ़ जनरेट करता है.
आगे बढ़ें
अगले चरण में, फ़्लेम ग्राफ़ की मदद से ऐप्लिकेशन में परफ़ॉर्मेंस से जुड़ी समस्या की वजह का पता लगाया जाएगा.
5. Cloud Profiler के फ़्लेम ग्राफ़ का विश्लेषण करना
फ़्लेम ग्राफ़ क्या है?
फ़्लेम ग्राफ़, प्रोफ़ाइल डेटा को विज़ुअलाइज़ करने के तरीकों में से एक है. ज़्यादा जानकारी के लिए, कृपया हमारा दस्तावेज़ देखें. हालांकि, यहां इसकी खास जानकारी दी गई है:
- हर बार, ऐप्लिकेशन में मेथड/फ़ंक्शन कॉल को दिखाता है
- वर्टिकल दिशा में कॉल स्टैक होता है. कॉल स्टैक, ऊपर से नीचे की ओर बढ़ता है
- हॉरिज़ॉन्टल दिशा में संसाधन के इस्तेमाल को दिखाया गया है. यह जितना ज़्यादा होगा, परफ़ॉर्मेंस उतनी ही खराब होगी.
इसलिए, आइए अब हम फ़्लेम ग्राफ़ को देखते हैं.

फ़्लेम ग्राफ़ का विश्लेषण करना
पिछले सेक्शन में, आपने सीखा कि फ़्लेम ग्राफ़ में मौजूद हर बार, फ़ंक्शन/तरीके के कॉल को दिखाता है. साथ ही, इसकी लंबाई का मतलब है कि फ़ंक्शन/तरीके में संसाधन का इस्तेमाल किया गया है. Cloud Profiler का फ़्लेम ग्राफ़, बार को घटते क्रम में या लंबाई के हिसाब से बाएं से दाएं क्रम में लगाता है. इसलिए, ग्राफ़ के सबसे ऊपर बाईं ओर से देखना शुरू करें.

हमारे मामले में, यह साफ़ तौर पर पता चलता है कि grpc.(*Server).serveStreams.func1.2 सबसे ज़्यादा सीपीयू समय ले रहा है. साथ ही, कॉल स्टैक को ऊपर से नीचे तक देखने पर पता चलता है कि ज़्यादातर समय grpc.(*Server).serveStreams.func1.2 में खर्च होता है. यह सर्वर सेवा में gRPC सर्वर हैंडलर है.main.(*serverService).GetMatchCount
GetMatchCount में, आपको regexp फ़ंक्शन की एक सीरीज़ दिखती है: regexp.MatchString और regexp.Compile. ये स्टैंडर्ड पैकेज से हैं. इसका मतलब है कि इनकी परफ़ॉर्मेंस के साथ-साथ, कई अन्य पहलुओं से भी अच्छी तरह जांच की जानी चाहिए. हालांकि, यहां दिए गए नतीजे से पता चलता है कि regexp.MatchString और regexp.Compile में सीपीयू टाइम रिसॉर्स का इस्तेमाल ज़्यादा हुआ है. इन तथ्यों के आधार पर, यह माना जा सकता है कि regexp.MatchString का इस्तेमाल करने से परफ़ॉर्मेंस से जुड़ी समस्याएं हो रही हैं. इसलिए, आइए उस सोर्स कोड को पढ़ते हैं जहां फ़ंक्शन का इस्तेमाल किया गया है.
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 को कॉल किया जाता है. सोर्स कोड को पढ़ने पर, आपको पता चल सकता है कि फ़ंक्शन को नेस्ट किए गए for-लूप के अंदर कॉल किया गया है. इसलिए, हो सकता है कि इस फ़ंक्शन का इस्तेमाल सही तरीके से न किया गया हो. आइए, regexp का GoDoc देखें.

दस्तावेज़ के मुताबिक, regexp.MatchString हर कॉल में रेगुलर एक्सप्रेशन पैटर्न को कंपाइल करता है. इसलिए, संसाधनों की ज़्यादा खपत की वजह यह है.
खास जानकारी
इस चरण में, आपने फ़्लेम ग्राफ़ का विश्लेषण करके, संसाधन इस्तेमाल होने की वजह का अनुमान लगाया.
आगे बढ़ें
अगले चरण में, सर्वर सेवा के सोर्स कोड को अपडेट करें और वर्शन 1.0.0 से हुए बदलाव की पुष्टि करें.
6. सोर्स कोड अपडेट करना और फ़्लेम ग्राफ़ की तुलना करना
सोर्स कोड अपडेट करना
पिछले चरण में, आपने यह मान लिया था कि regexp.MatchString के इस्तेमाल का मतलब है कि ज़्यादा संसाधनों का इस्तेमाल किया जा रहा है. इसलिए, आइए इस समस्या को हल करें. कोड खोलें और उस हिस्से में थोड़ा बदलाव करें.
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
}
जैसा कि आप देख सकते हैं, अब regexp पैटर्न कंपाइल करने की प्रोसेस को regexp.MatchString से अलग कर दिया गया है. साथ ही, इसे नेस्ट किए गए for लूप से बाहर ले जाया गया है.
इस कोड को डिप्लॉय करने से पहले, initProfiler() फ़ंक्शन में वर्शन स्ट्रिंग को अपडेट करना न भूलें.
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)
}
}
अब देखते हैं कि यह सुविधा कैसे काम करती है. skaffold कमांड का इस्तेमाल करके क्लस्टर डिप्लॉय करें.
skaffold dev
कुछ समय बाद, Cloud Profiler डैशबोर्ड को फिर से लोड करें और देखें कि यह कैसा दिखता है.

वर्शन को "1.1.0" पर सेट करना न भूलें, ताकि आपको सिर्फ़ वर्शन 1.1.0 की प्रोफ़ाइलें दिखें. जैसा कि आपको दिख रहा है, GetMatchCount के बार की लंबाई कम हो गई है.साथ ही, सीपीयू के इस्तेमाल का अनुपात भी कम हो गया है. इसका मतलब है कि बार छोटा हो गया है.

सिर्फ़ एक वर्शन के फ़्लेम ग्राफ़ को देखकर ही नहीं, बल्कि दो वर्शन के बीच के अंतर की तुलना करके भी परफ़ॉर्मेंस का पता लगाया जा सकता है.

"तुलना करें" ड्रॉप-डाउन सूची की वैल्यू को "वर्शन" में बदलें. इसके बाद, "तुलना किया गया वर्शन" की वैल्यू को "1.0.0" में बदलें. यह ओरिजनल वर्शन है.

आपको इस तरह का फ़्लेम ग्राफ़ दिखेगा. ग्राफ़ का आकार, 1.1.0 जैसा ही है, लेकिन रंग अलग है. तुलना मोड में, रंग का मतलब यह है:
- नीला: वैल्यू (संसाधन की खपत) कम हुई
- नारंगी: हासिल की गई वैल्यू (रिसोर्स का इस्तेमाल)
- ग्रे: न तो संतुष्ट और न ही असंतुष्ट
लेगेंड को देखते हुए, आइए फ़ंक्शन पर एक नज़र डालें. जिस बार को ज़ूम इन करना है उस पर क्लिक करके, स्टैक में मौजूद ज़्यादा जानकारी देखी जा सकती है. कृपया main.(*serverService).GetMatchCount बार पर क्लिक करें. बार पर कर्सर घुमाकर भी, तुलना की जानकारी देखी जा सकती है.

इसमें बताया गया है कि सीपीयू के इस्तेमाल का कुल समय 5.26 सेकंड से घटकर 2.88 सेकंड हो गया है. कुल समय 10 सेकंड है, जो सैंपलिंग विंडो है. यह एक बहुत बड़ा सुधार है!
अब प्रोफ़ाइल डेटा का विश्लेषण करके, ऐप्लिकेशन की परफ़ॉर्मेंस को बेहतर बनाया जा सकता है.
खास जानकारी
इस चरण में, आपने सर्वर सेवा में बदलाव किया और Cloud Profiler के तुलना मोड में सुधार की पुष्टि की.
आगे बढ़ें
अगले चरण में, सर्वर सेवा के सोर्स कोड को अपडेट करें और वर्शन 1.0.0 से हुए बदलाव की पुष्टि करें.
7. अतिरिक्त चरण: ट्रेस वॉटरफ़ॉल में सुधार की पुष्टि करना
डिस्ट्रिब्यूटेड ट्रेस और कंटीन्यूअस प्रोफ़ाइलिंग के बीच अंतर
कोड लैब के पहले हिस्से में, आपने पुष्टि की थी कि आपको अनुरोध के पाथ के लिए, माइक्रोसेवाओं में बॉटलनेक सेवा का पता चल सकता है. साथ ही, आपको उस सेवा में बॉटलनेक की सटीक वजह का पता नहीं चल सका. इस दूसरे पार्ट के कोडलैब में, आपने सीखा कि लगातार प्रोफ़ाइलिंग करने से, कॉल स्टैक से किसी एक सेवा में आने वाली रुकावट का पता लगाया जा सकता है.
इस चरण में, आइए डिस्ट्रिब्यूटेड ट्रेस (Cloud Trace) से वॉटरफ़ॉल ग्राफ़ की समीक्षा करें और देखें कि यह कंटीन्यूअस प्रोफ़ाइलिंग से कितना अलग है.
यह वॉटरफ़ॉल ग्राफ़, "love" क्वेरी वाले ट्रेस में से एक है. इसमें कुल 6.7 सेकंड (6700 मि॰से॰) लग रहे हैं.

यह संख्या, एक ही क्वेरी के लिए समय के साथ बदल सकती है. आपने बताया कि अब कुल लेटेन्सी 1.5 सेकंड (1500 मि॰से॰) है. यह पिछली लेटेन्सी से काफ़ी कम है.

यहां यह जानना ज़रूरी है कि डिस्ट्रिब्यूटेड ट्रेस वॉटरफ़ॉल चार्ट में, कॉल स्टैक की जानकारी तब तक उपलब्ध नहीं होती, जब तक कि हर जगह स्पैन को इंस्ट्रूमेंट न किया जाए. साथ ही, डिस्ट्रिब्यूटेड ट्रेसिंग सिर्फ़ सेवाओं के बीच होने वाली देरी पर फ़ोकस करती है, जबकि कंटीन्यूअस प्रोफ़ाइलिंग, किसी एक सेवा के कंप्यूटर संसाधनों (सीपीयू, मेमोरी, ओएस थ्रेड) पर फ़ोकस करती है.
दूसरे पहलू में, डिस्ट्रिब्यूटेड ट्रेस, इवेंट पर आधारित होता है. वहीं, कंटीन्यूअस प्रोफ़ाइलिंग, आंकड़ों पर आधारित होती है. हर ट्रेस के लिए, इंतज़ार के समय का ग्राफ़ अलग होता है. साथ ही, इंतज़ार के समय में होने वाले बदलावों के रुझान को पाने के लिए, आपको वितरण जैसे किसी दूसरे फ़ॉर्मैट की ज़रूरत होती है.
खास जानकारी
इस चरण में, आपने डिस्ट्रिब्यूटेड ट्रेस और कंटीन्यूअस प्रोफ़ाइलिंग के बीच के अंतर की जांच की.
8. बधाई हो
आपने OpenTelemetry की मदद से डिस्ट्रिब्यूटेड ट्रेस बना लिए हैं. साथ ही, Google Cloud Trace पर माइक्रोसेवा के लिए अनुरोधों की लेटेन्सी की पुष्टि कर ली है.
ज़्यादा अभ्यास के लिए, इन विषयों को खुद आज़माएं.
- मौजूदा तरीके से, हेल्थ चेक से जनरेट किए गए सभी स्पैन भेजे जाते हैं. (
grpc.health.v1.Health/Check) Cloud Trace से उन स्पैन को कैसे फ़िल्टर किया जाता है? हिंट यहां है. - इवेंट लॉग को स्पैन से जोड़ें और देखें कि यह Google Cloud Trace और Google Cloud Logging पर कैसे काम करता है. हिंट यहां है.
- किसी सेवा को दूसरी भाषा में उपलब्ध सेवा से बदलें. इसके बाद, उस भाषा के लिए OpenTelemetry का इस्तेमाल करके उसे इंस्ट्रूमेंट करें.
इसके अलावा, अगर आपको इसके बाद प्रोफ़ाइलर के बारे में जानना है, तो कृपया दूसरे हिस्से पर जाएं. ऐसे में, नीचे दिए गए 'साफ़ करें' सेक्शन को छोड़ दें.
खाली करने के लिए जगह
इस कोडलैब के बाद, कृपया Kubernetes क्लस्टर को बंद करें और प्रोजेक्ट को मिटाना न भूलें. ऐसा करने से, आपको Google Kubernetes Engine, Google Cloud Trace, और Google Artifact Registry पर अनचाहे शुल्क नहीं लगेंगे.
सबसे पहले, क्लस्टर मिटाएं. अगर क्लस्टर को skaffold dev के साथ चलाया जा रहा है, तो आपको सिर्फ़ Ctrl-C दबाना होगा. अगर क्लस्टर को skaffold run के साथ चलाया जा रहा है, तो यह कमांड चलाएं:
skaffold delete
कमांड आउटपुट
Cleaning up... - deployment.apps "clientservice" deleted - service "clientservice" deleted - deployment.apps "loadgen" deleted - deployment.apps "serverservice" deleted - service "serverservice" deleted
क्लस्टर मिटाने के बाद, मेन्यू पैन में जाकर "IAM और एडमिन" > "सेटिंग" चुनें. इसके बाद, "बंद करें" बटन पर क्लिक करें.

इसके बाद, डायलॉग बॉक्स में मौजूद फ़ॉर्म में प्रोजेक्ट आईडी (प्रोजेक्ट का नाम नहीं) डालें और बंद करने की पुष्टि करें.