इस कोडलैब (कोड बनाना सीखने के लिए ट्यूटोरियल) के बारे में जानकारी
1. परिचय
पिछली बार अपडेट किए जाने की तारीख: 15-07-2022
ऐप्लिकेशन को जांचने की क्षमता
देखना और OpenTelemetry
निगरानी करने की क्षमता का इस्तेमाल किसी सिस्टम के एट्रिब्यूट के बारे में बताने के लिए किया जाता है. मॉनिटर करने की क्षमता वाले सिस्टम की मदद से, टीमें अपने सिस्टम को लगातार डीबग कर सकती हैं. इस हिसाब से, निगरानी करने के तीन मुख्य आधार हैं; लॉग, मेट्रिक, और ट्रेस, सिस्टम को मॉनिटर करने की क्षमता पाने के बुनियादी इंस्ट्रुमेंट हैं.
OpenTelemetry, खास निर्देशों, लाइब्रेरी, और एजेंट का एक ऐसा सेट है जो इंस्ट्रुमेंटेशन और टेलीमेट्री डेटा (लॉग, मेट्रिक, और ट्रेस) के एक्सपोर्ट को तेज़ करता है, जिसकी निगरानी करने की ज़रूरत होती है. OpenTelemetry, CNCF के तहत एक ओपन स्टैंडर्ड और कम्यूनिटी की ओर से चलाया जाने वाला प्रोजेक्ट है. प्रोजेक्ट और इसके ईकोसिस्टम से मिली लाइब्रेरी का इस्तेमाल करके, डेवलपर अपने ऐप्लिकेशन को वेंडर न्यूट्रल तरीके से और एक से ज़्यादा आर्किटेक्चर के साथ इस्तेमाल कर सकते हैं.
निगरानी करने के तीन मुख्य पहलुओं के अलावा, लगातार प्रोफ़ाइल बनाना, पता लगाने की एक अहम वजह है. साथ ही, इसकी मदद से इंडस्ट्री में उपयोगकर्ताओं की संख्या बढ़ाई जा सकती है. Cloud Profiler, शुरुआत करने वालों में से एक है. यह ऐप्लिकेशन के कॉल स्टैक में परफ़ॉर्मेंस मेट्रिक को ड्रिल-डाउन करने के लिए, आसान इंटरफ़ेस उपलब्ध कराता है.
यह कोडलैब इस सीरीज़ का पहला हिस्सा है. इसमें OpenTelemetry और Cloud Trace की मदद से, माइक्रोसर्विस में डिस्ट्रिब्यूटेड ट्रेस को शामिल किया गया है. दूसरे भाग में, Cloud Profiler की मदद से लगातार प्रोफ़ाइल बनाने के बारे में बताया जाएगा.
डिस्ट्रिब्यूटेड ट्रेस
लॉग, मेट्रिक, और ट्रेस में से ट्रेस एक टेलीमेट्री है, जो सिस्टम में इस प्रोसेस के किसी खास हिस्से की इंतज़ार के समय के बारे में बताता है. खास तौर पर, माइक्रोसर्विस के दौर में, डिस्ट्रिब्यूटेड ट्रेस की मदद से, डिस्ट्रिब्यूट किए जाने वाले सिस्टम में आने वाली रुकावटों का पता लगाया जा सकता है.
डिस्ट्रिब्यूट किए गए ट्रेस का विश्लेषण करते समय, ट्रेस डेटा विज़ुअलाइज़ेशन एक नज़र में सिस्टम के इंतज़ार के समय को सही तरीके से समझने का मुख्य ज़रिया है. डिस्ट्रिब्यूटेड ट्रेस में, हम सिस्टम के एंट्रीपॉइंट से जुड़े एक अनुरोध को प्रोसेस करने के लिए कॉल का एक सेट मैनेज करते हैं. यह अनुरोध कई स्पैन के रूप में ट्रेस के रूप में होता है.
स्पैन, डिस्ट्रिब्यूटेड सिस्टम में किए गए काम की यूनिट को दिखाता है. इसमें, शुरू और खत्म होने का समय रिकॉर्ड होता है. स्पैन के एक-दूसरे के बीच अक्सर हैरारकी के संबंध होते हैं - नीचे की तस्वीर में, सभी छोटे स्पैन, एक बड़े /मैसेज स्पैन वाले चाइल्ड स्पैन हैं, और इन्हें एक ट्रेस में जोड़ दिया गया है, जो सिस्टम के ज़रिए काम का पाथ दिखाता है.
Google Cloud Trace, डिस्ट्रिब्यूटेड ट्रेस बैकएंड के लिए उपलब्ध विकल्पों में से एक है. साथ ही, यह Google Cloud में मौजूद अन्य प्रॉडक्ट के साथ अच्छी तरह इंटिग्रेट होता है.
आपको क्या बनाना होगा
इस कोडलैब में, "शेक्सपियर ऐप्लिकेशन" नाम की सेवाओं में इंस्ट्रुमेंट ट्रेस की जानकारी देखी जा रही है (जिसे शेक्स ऐप भी कहते हैं). यह Google Kubernetes Engine क्लस्टर पर चलता है. शेक्स ऐप का आर्किटेक्चर नीचे बताया गया है:
- Loadgen, एचटीटीपी में क्लाइंट को क्वेरी स्ट्रिंग भेजता है
- क्लाइंट, gRPC में लोडजेन से सर्वर तक क्वेरी को पास करते हैं
- सर्वर, क्लाइंट की क्वेरी को स्वीकार करता है, Google Cloud Storage से शेक्सपियर के सभी कामों को टेक्स्ट फ़ॉर्मैट में फ़ेच करता है, क्वेरी वाली लाइनों में खोज करता है, और क्लाइंट से मेल खाने वाली लाइन की संख्या दिखाता है
अनुरोध में मौजूद ट्रेस की जानकारी का इस्तेमाल किया जाएगा. इसके बाद, आप सर्वर में प्रोफ़ाइलर एजेंट को एम्बेड करेंगे और बॉटलनेक की जांच करेंगे.
आपको इनके बारे में जानकारी मिलेगी
- Go प्रोजेक्ट में OpenTelemetry Trace लाइब्रेरी के साथ शुरुआत करने का तरीका
- लाइब्रेरी के साथ स्पैन बनाने का तरीका
- ऐप्लिकेशन के कॉम्पोनेंट के बीच वायर पर स्पैन कॉन्टेक्स्ट लागू करने का तरीका
- Cloud Trace को ट्रेस का डेटा कैसे भेजें
- Cloud Trace पर ट्रेस का विश्लेषण कैसे करें
यह कोडलैब आपकी माइक्रोसेवाओं को तैयार करने का तरीका बताता है. इसे आसानी से समझने के लिए, इस उदाहरण में सिर्फ़ तीन कॉम्पोनेंट शामिल किए गए हैं (लोड जनरेटर, क्लाइंट, और सर्वर). हालांकि, इस कोडलैब में बताई गई प्रोसेस को ज़्यादा जटिल और बड़ा सिस्टम भी लागू किया जा सकता है.
आपको इन चीज़ों की ज़रूरत होगी
- Go के बारे में बुनियादी जानकारी
- Kubernetes की बुनियादी जानकारी
2. सेटअप और ज़रूरी शर्तें
अपने हिसाब से एनवायरमेंट सेटअप करना
अगर आपके पास पहले से Google खाता (Gmail या Google Apps) नहीं है, तो एक खाता बनाएं. Google Cloud Platform कंसोल ( 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 आधारित इस वर्चुअल मशीन में ऐसे सभी डेवलपमेंट टूल मौजूद हैं जिनकी आपको ज़रूरत पड़ेगी. यह पांच जीबी की स्थायी होम डायरेक्ट्री उपलब्ध कराता है और 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 क्लस्टर सेट अप करना
इस कोडलैब में, Google Kubernetes Engine (GKE) पर माइक्रोसर्विस का क्लस्टर चलाया जाएगा. इस कोडलैब की प्रोसेस इस तरह है:
- Cloud Shell में बेसलाइन प्रोजेक्ट डाउनलोड करें
- कंटेनर में माइक्रोसर्विस बनाएं
- Google Artifact Registry (GAR) पर कंटेनर अपलोड करना
- GKE (जीकेई) पर कंटेनर डिप्लॉय करना
- ट्रेस इंस्ट्रुमेंटेशन के लिए सेवाओं का सोर्स कोड बदलें
- दूसरे चरण पर जाएं
Kubernetes इंजन चालू करना
सबसे पहले, हम Kubernetes क्लस्टर सेट अप करते हैं. इसमें GKE (जीकेई) पर शेक्स ऐप्लिकेशन चलता है. इसलिए, हमें GKE (जीकेई) चालू करना होगा. "Kubernetes Engine" मेन्यू पर जाएं और 'चालू करें' बटन दबाएं.
अब आप Kubernetes क्लस्टर बनाने के लिए तैयार हैं.
Kubernetes क्लस्टर बनाना
Cloud Shell पर, Kubernetes क्लस्टर बनाने के लिए नीचे दिया गया कमांड चलाएं. कृपया पुष्टि करें कि ज़ोन की वैल्यू उसी क्षेत्र में है जिसे 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 और स्केफ़ोल्ड का सेटअप
अब हमारे पास Kubernetes क्लस्टर है, जो डिप्लॉयमेंट के लिए तैयार है. इसके बाद, हम कंटेनर को पुश और डिप्लॉय करने के लिए, एक कंटेनर रजिस्ट्री की तैयारी करते हैं. इन चरणों के लिए, हमें एक Artifact Registry (GAR) और स्कैफ़ोल्ड सेट अप करना होगा, ताकि वे इसका इस्तेमाल कर सकें.
Artifact Registry का सेटअप करना
"Artifact Registry" के मेन्यू पर जाएं और 'चालू करें' बटन दबाएं.
कुछ देर बाद, आपको GAR का डेटा स्टोर करने की जगह वाला ब्राउज़र दिखेगा. "डेटा स्टोर करने की जगह बनाएं" पर क्लिक करें बटन पर क्लिक करें और रिपॉज़िटरी का नाम डालें.
इस कोडलैब में, मैंने डेटा स्टोर करने की नई जगह को trace-codelab
नाम दिया है. आर्टफ़ैक्ट का फ़ॉर्मैट "डॉकर" है और जगह का टाइप "क्षेत्र" है. Google Compute Engine के डिफ़ॉल्ट ज़ोन के लिए सेट किए गए इलाके के आस-पास का इलाका चुनें. उदाहरण के लिए, इस उदाहरण में "us-central1-f" को चुना गया इसलिए यहां हम "us-central1 (आयोवा)" को चुनते हैं. इसके बाद, "बनाएं" पर क्लिक करें बटन.
अब आपको "ट्रेस-कोडलैब" दिखता है रिपॉज़िटरी ब्राउज़र पर.
हम रजिस्ट्री पाथ की जांच करने के लिए बाद में यहां वापस आएंगे.
Skaffold का सेटअप
Kubernetes पर चलने वाली माइक्रोसर्विस बनाने के लिए, Skaffold एक आसान टूल है. यह कमांड के छोटे सेट का इस्तेमाल करके, ऐप्लिकेशन के कंटेनर बनाने, पुश करने, और डिप्लॉय करने का वर्कफ़्लो मैनेज करता है. Skoffold, डिफ़ॉल्ट रूप से कंटेनर रजिस्ट्री के रूप में Docker Registry का इस्तेमाल करते हैं. इसलिए, आपको कंटेनर को पुश करने पर GAR की पहचान करने के लिए, skaffold को कॉन्फ़िगर करना होगा.
Cloud Shell को फिर से खोलें और पुष्टि करें कि स्कैफ़ोल्ड को इंस्टॉल किया गया है. Cloud Shell पर, डिफ़ॉल्ट रूप से एनवायरमेंट में स्केलोल्ड इंस्टॉल होता है. निम्न कमांड चलाएं और स्केलोल्ड वर्शन देखें.
skaffold version
कमांड आउटपुट
v1.38.0
अब आपके पास स्केलोल्ड के इस्तेमाल के लिए, डिफ़ॉल्ट रिपॉज़िटरी को रजिस्टर करने का विकल्प है. रजिस्ट्री पाथ पाने के लिए, 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 पर होस्ट किया जाता है. इसलिए, यहां दिए गए git कमांड की मदद से, Cloud Shell एनवायरमेंट में उन्हें डाउनलोड करें.
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 मेनिफ़ेस्ट फ़ाइलें
- प्रोटो: क्लाइंट और सर्वर के बीच कम्यूनिकेशन के लिए प्रोटो डेफ़िनिशन
- src: हर सेवा के सोर्स कोड के लिए डायरेक्ट्री
- skaffold.yaml: skaffold के लिए कॉन्फ़िगरेशन फ़ाइल
इस कोडलैब में, step0
फ़ोल्डर में मौजूद सोर्स कोड को अपडेट किया जाएगा. नीचे दिया गया तरीका अपनाकर, जवाबों के लिए step[1-6]
फ़ोल्डर में भी सोर्स कोड देखे जा सकते हैं. (पहले भाग में चरण0 से लेकर चौथे चरण तक के बारे में बताया गया है, जबकि दूसरे भाग में पांचवें और छठे चरण को शामिल किया गया है)
skaffold कमांड चलाएं
आखिरकार, आप अभी बनाए गए Kubernetes क्लस्टर पर बनाने, पुश और लागू करने के लिए तैयार हैं. ऐसा लगता है कि इसमें कई चरण हैं, लेकिन असल में स्कैफ़ोल्ड आपके लिए सब कुछ करता है. इसे नीचे दिए गए निर्देश की मदद से करके देखते हैं:
cd step0 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
खास जानकारी
इस चरण में, आपने अपने एनवायरमेंट में कोडलैब मटीरियल तैयार किया है और उम्मीद के मुताबिक स्कैफ़ोल्ड के चलने की पुष्टि की है.
अगला वीडियो
अगले चरण में, आपको ट्रेस जानकारी को तैयार करने के लिए, लोडजेन सेवा के सोर्स कोड में बदलाव करना होगा.
4. एचटीटीपी के लिए इंस्ट्रुमेंटेशन
ट्रेस इंस्ट्रुमेंटेशन और प्रोपगेशन का सिद्धांत
सोर्स कोड में बदलाव करने से पहले, मुझे एक आसान डायग्राम में यह बताना होगा कि डिस्ट्रिब्यूट किए गए ट्रेस कैसे काम करते हैं.
इस उदाहरण में, हम ट्रेस और स्पैन की जानकारी को Cloud Trace में एक्सपोर्ट करने के लिए कोड का इस्तेमाल करते हैं. साथ ही, लोड जेन सेवा से सर्वर सेवा को किए गए अनुरोध पर, ट्रेस कॉन्टेक्स्ट लागू करते हैं.
ऐप्लिकेशन को ट्रेस आईडी और स्पैन आईडी जैसा ट्रेस मेटाडेटा भेजना होगा, ताकि Cloud Trace को एक ही ट्रेस में रखने वाले सभी स्पैन को इकट्ठा किया जा सके. साथ ही, ऐप्लिकेशन को डाउनस्ट्रीम सेवाओं का अनुरोध करने पर ट्रेस कॉन्टेक्स्ट (पैरंट स्पैन के ट्रेस आईडी और स्पैन आईडी का कॉम्बिनेशन) लागू करने होंगे. इससे उन्हें यह पता चल सकेगा कि वे किस ट्रेस कॉन्टेक्स्ट को हैंडल कर रहे हैं.
OpenTelemetry इन कामों में आपकी मदद करता है:
- यूनीक ट्रेस आईडी और स्पैन आईडी जनरेट करने के लिए
- ट्रेस आईडी और स्पैन आईडी को बैकएंड में एक्सपोर्ट करने के लिए
- ट्रेस कॉन्टेक्स्ट को अन्य सेवाओं पर लागू करने के लिए
- अतिरिक्त मेटाडेटा एम्बेड करने के लिए जो ट्रेस का विश्लेषण करने में मदद करता है
OpenTelemetry Trace के कॉम्पोनेंट
OpenTelemetry की मदद से, इंस्ट्रुमेंट ऐप्लिकेशन ट्रेस करने की प्रक्रिया यहां दी गई है:
- एक्सपोर्टर बनाएं
- एक्सपोर्टर को 1 में बाइंड करने के लिए, TracerProvider बनाएं और उसे ग्लोबल तौर पर सेट करें.
- प्रचार का तरीका सेट करने के लिए, TextMapPropagaror सेट करें
- TracerProvider से ट्रेसर पाएं
- ट्रेसर से स्पैन जनरेट करें
फ़िलहाल, आपको हर कॉम्पोनेंट की प्रॉपर्टी को समझने की ज़रूरत नहीं है, लेकिन याद रखने वाली सबसे ज़रूरी बात ये है:
- इस एक्सपोर्टर को TracerProvider में प्लग किया जा सकता है
- TracerProvider में ट्रेस सैंपलिंग और एक्सपोर्ट से जुड़े सभी कॉन्फ़िगरेशन होते हैं
- सभी ट्रेस, ट्रेसर ऑब्जेक्ट में बंडल किए गए हैं
यह समझने के बाद, आइए कोडिंग के असल काम पर चलते हैं.
इंस्ट्रुमेंट की पहली अवधि
इंस्ट्रुमेंट लोड जनरेटर सेवा
क्लाउड शेल के सबसे ऊपर दाईं ओर मौजूद बटन को दबाकर, क्लाउड शेल एडिटर खोलें. बाएं पैनल में एक्सप्लोरर से
step0/src/loadgen/main.go
खोलें और मुख्य फ़ंक्शन ढूंढें.
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++ } }
मुख्य फ़ंक्शन में, आपको फ़ंक्शन run
को कॉल करने वाला लूप दिखता है. मौजूदा लागू करने के तरीके में, सेक्शन में दो लॉग लाइनें होती हैं, जो फ़ंक्शन कॉल की शुरुआत और आखिर में रिकॉर्ड करती हैं. आइए, अब फ़ंक्शन कॉल की इंतज़ार के समय को ट्रैक करने के लिए इंस्ट्रुमेंट स्पैन की जानकारी का इस्तेमाल करते हैं.
जैसा कि पिछले सेक्शन में बताया गया है, सबसे पहले OpenTelemetry के लिए पूरे कॉन्फ़िगरेशन को सेट अप करते हैं. OpenTelemetry पैकेज को इस तरह जोड़ें:
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 )
आसानी से समझने के लिए, हम initTracer
नाम का एक सेटअप फ़ंक्शन बनाते हैं और उसे main
फ़ंक्शन में कॉल करते हैं.
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 को सेट अप करने की प्रोसेस पिछले सेक्शन में बताई गई हो. इस तरीके को लागू करने में, हम stdout
एक्सपोर्टर का इस्तेमाल करते हैं जो सभी ट्रेस जानकारी को स्ट्रक्चर्ड फ़ॉर्मैट में stdout में एक्सपोर्ट करता है.
इसके बाद, इसे मुख्य फ़ंक्शन से कॉल किया जाता है. initTracer()
पर कॉल करें और पक्का करें कि ऐप्लिकेशन बंद करने पर, TracerProvider.Shutdown()
पर भी कॉल किया जाए.
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) ...
सेट अप पूरा करने के बाद, आपको एक यूनीक ट्रेस आईडी और स्पैन आईडी वाला स्पैन बनाना होगा. OpenTelemetry इसके लिए एक आसान लाइब्रेरी उपलब्ध कराता है. इंस्ट्रुमेंट एचटीटीपी क्लाइंट में और नए पैकेज जोड़ें.
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" )
क्योंकि लोड जनरेटर क्लाइंट सेवा को runQuery
फ़ंक्शन में net/http
के साथ HTTP में कॉल कर रहा है, इसलिए हम net/http
के लिए कॉन्ट्रिब पैकेज का इस्तेमाल करते हैं और httptrace
और otelhttp
पैकेज के एक्सटेंशन के साथ इंस्ट्रुमेंटेशन को चालू करते हैं.
इंस्ट्रुमेंट्ड क्लाइंट के ज़रिए एचटीटीपी अनुरोधों को कॉल करने के लिए, सबसे पहले एक पैकेज ग्लोबल वैरिएबल httpClient.
step0/src/loadgen/main.go
var httpClient = http.Client{ Transport: otelhttp.NewTransport(http.DefaultTransport) }
इसके बाद, OpenTelemetry और कस्टम एचटीटीपी क्लाइंट से अपने-आप जनरेट हुए स्पैन का इस्तेमाल करके, कस्टम स्पैन बनाने के लिए, runQuery
फ़ंक्शन में इंस्ट्रुमेंटेशन जोड़ें. आपको यह करना होगा:
otel.Tracer()
के साथ ग्लोबलTracerProvider
से ट्रेसर पाएंTracer.Start()
तरीके से रूट स्पैन बनाएं- किसी मनचाहे समय में, रूट स्पैन को खत्म करें (इस मामले में,
runQuery
फ़ंक्शन खत्म होने पर)
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) }
अब आपने loadgen (एचटीटीपी क्लाइंट ऐप्लिकेशन) में इंस्ट्रुमेंटेशन का काम पूरा कर लिया है. कृपया अपने go.mod
और go.sum
को go mod
निर्देश से अपडेट करना न भूलें.
go mod tidy
इंस्ट्रुमेंट क्लाइंट सेवा
पिछले सेक्शन में, हमने नीचे दी गई ड्रॉइंग में लाल आयत में बंद हिस्से को इंस्ट्रुमेंट किया. हमने लोड जनरेटर सेवा में अवधि की जानकारी शामिल की है. लोड जनरेट करने वाली सेवा की तरह ही, अब हमें क्लाइंट सेवा को इंस्ट्रुमेंट करना होगा. लोड जनरेटर सेवा से अंतर यह है कि क्लाइंट सेवा को एचटीटीपी हेडर में लोड जनरेटर सेवा से ली गई ट्रेस आईडी जानकारी को एक्सट्रैक्ट करना होता है और स्पैन जनरेट करने के लिए आईडी का इस्तेमाल करना होता है.
क्लाउड शेल एडिटर खोलें और ज़रूरी पैकेज जोड़ें. जैसा कि हमने लोड जनरेटर सेवा के लिए किया था.
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 को सेट अप करना होगा. बस लोड जेन से initTracer
फ़ंक्शन को कॉपी करके चिपकाएं और इसे क्लाइंट सेवा के main
फ़ंक्शन में भी कॉल करें.
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 }
अब समय है इंस्ट्रुमेंट स्पैन की. क्लाइंट सेवा को लोडजेन सेवा से एचटीटीपी अनुरोध स्वीकार करने होते हैं. इसलिए, इसे हैंडलर को इंस्ट्रुमेंट करना पड़ता है. क्लाइंट सेवा में एचटीटीपी सर्वर को net/http के साथ लागू किया जाता है. साथ ही, otelhttp
पैकेज का इस्तेमाल उसी तरह किया जा सकता है जिस तरह हमने loadgen में किया था.
सबसे पहले, हम हैंडलर रजिस्ट्रेशन को otelhttp
हैंडलर से बदल देते हैं. main
फ़ंक्शन में, उन लाइनों को ढूंढें जहां एचटीटीपी हैंडलर को http.HandleFunc()
के साथ रजिस्टर किया गया है.
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)
इसके बाद, हम हैंडलर के अंदर मौजूद असल स्पैन को इंस्ट्रुमेंट करते हैं. Fuc (*clientService) हैंडलर() ढूंढें और trace.SpanFromContext()
के साथ स्पैन इंस्ट्रुमेंटेशन जोड़ें.
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 ...
इस इंस्ट्रुमेंटेशन का इस्तेमाल करने पर, आपको handler
तरीके की शुरुआत से लेकर आखिर तक के स्पैन मिलते हैं. स्पैन का विश्लेषण करना आसान बनाने के लिए, एक और एट्रिब्यूट जोड़ें. यह एट्रिब्यूट, मैच होने वाली संख्या को क्वेरी में सेव करता है. लॉग लाइन से ठीक पहले, यह कोड जोड़ें.
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)) ...
ऊपर दिए गए सभी इंस्ट्रुमेंटेशन का इस्तेमाल करके, आपने लोडजेन और क्लाइंट के बीच ट्रेस इंस्ट्रुमेंटेशन पूरा किया. आइए, देखते हैं कि यह कैसे काम करता है. कोड को फिर से skaffold की मदद से चलाएं.
skaffold dev
GKE (जीकेई) क्लस्टर पर सेवाएं चलाने के कुछ समय बाद, आपको बहुत सारे लॉग मैसेज इस तरह दिखेंगे:
कमांड आउटपुट
[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
एक्सपोर्टर से ये मैसेज मिलते हैं. आपको दिखेगा कि लोडजेन के हिसाब से सभी स्पैन के पैरंट के पास TraceID: 00000000000000000000000000000000
है, क्योंकि यह रूट स्पैन है, यानी कि ट्रेस में पहला स्पैन. साथ ही, आपको यह भी पता चलेगा कि एम्बेड एट्रिब्यूट "query"
में ऐसी क्वेरी स्ट्रिंग है जो क्लाइंट सेवा को भेजी जाती है.
खास जानकारी
इस चरण में, आपने लोड जनरेटर सेवा और क्लाइंट सेवा को एचटीटीपी में कम्यूनिकेट किया है और पुष्टि की है कि आप सभी सेवाओं में ट्रेस कॉन्टेक्स्ट लागू कर सकते हैं और स्पैन की जानकारी को दोनों सेवाओं से एसटीडीआउट में एक्सपोर्ट कर सकते हैं.
अगला वीडियो
अगले चरण में, आपको क्लाइंट सेवा और सर्वर सेवा को इंस्ट्रुमेंट करना होगा, ताकि यह पुष्टि की जा सके कि gRPC के ज़रिए ट्रेस कॉन्टेक्स्ट को कैसे लागू किया जाए.
5. gRPC के लिए इंस्ट्रुमेंटेशन
पिछले चरण में, हमने इस माइक्रोसर्विस में अनुरोध के पहले आधे हिस्से को शामिल किया था. इस चरण में, हम क्लाइंट सेवा और सर्वर सेवा के बीच gRPC कम्यूनिकेशन करने की कोशिश करते हैं. (नीचे दिए गए चित्र में हरा और बैंगनी आयत)
gRPC क्लाइंट के लिए इंस्ट्रुमेंटेशन प्री-बिल्ड करें
OpenTelemetry के नेटवर्क में ऐसी कई लाइब्रेरी हैं जिन्हें आसानी से इस्तेमाल किया जा सकता है, जिनसे डेवलपर को इंस्ट्रुमेंट वाले ऐप्लिकेशन इस्तेमाल करने में मदद मिलती है. पिछले चरण में, हमने net/http
पैकेज के लिए प्री-बिल्ड इंस्ट्रुमेंटेशन का इस्तेमाल किया था. इस चरण में, जब हम gRPC के ज़रिए ट्रेस कॉन्टेक्स्ट को लागू करने की कोशिश कर रहे हैं, तब हम इसके लिए लाइब्रेरी का इस्तेमाल करते हैं.
सबसे पहले, आपको otelgrpc
नाम का पहले से बना gRPC पैकेज इंपोर्ट करना होता है.
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" )
इस बार, क्लाइंट सेवा, सर्वर सेवा के लिए एक gRPC क्लाइंट है, इसलिए आपको gRPC क्लाइंट को इंस्ट्रुमेंट करना होगा. mustConnGRPC
फ़ंक्शन ढूंढें और ऐसे gRPC इंटरसेप्टर जोड़ें जो क्लाइंट के सर्वर से अनुरोध करने पर, हर बार नए स्पैन इंस्टॉल करते हैं.
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 को पहले ही सेट अप कर लिया है, इसलिए आपको ऐसा करने की ज़रूरत नहीं है.
gRPC सर्वर के लिए पहले से बने इंस्ट्रुमेंटेशन
हमने gRPC क्लाइंट के लिए जो किया, उसी तरह हम gRPC सर्वर के लिए पहले से बने इंस्ट्रुमेंटेशन को हम gRPC सर्वर कहते हैं. इंपोर्ट सेक्शन में नया पैकेज जोड़ें, जैसे:
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" )
यह इंस्ट्रुमेंट सर्वर पर पहली बार इस्तेमाल करने की वजह से, आपको सबसे पहले OpenTelemetry को सेट अप करना होगा. ठीक वैसे ही जैसे हमने लोडजेन और क्लाइंट सेवाओं के लिए किया था.
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 ...
इसके बाद, आपको सर्वर इंटरसेप्टर जोड़ने होंगे. main
फ़ंक्शन में, वह जगह ढूंढें जहां grpc.NewServer()
को कॉल किया जाता है और फ़ंक्शन में इंटरसेप्टर जोड़ें.
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) ...
माइक्रोसर्विस चलाएं और ट्रेस की पुष्टि करें
इसके बाद, skaffold कमांड से बदले गए कोड को चलाएं.
skaffold dev
अब आपको stdout पर स्पैन के बारे में कई जानकारी दिखेगी.
कमांड आउटपुट
... [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] } ...
आपको पता चलता है कि आपने trace.Start()
या span.SpanFromContext()
का इस्तेमाल करके, किसी भी स्पैन का नाम एम्बेड नहीं किया है. साथ ही, मैन्युअल तरीके से बनाए गए स्पैन भी नहीं बनाए हैं. अब भी आपको कई स्पैन मिलते हैं, क्योंकि उन्हें gRPC इंटरसेप्टर ने जनरेट किया है.
खास जानकारी
इस चरण में, आपने OpenTelemetry नेटवर्क लाइब्रेरी की मदद से gRPC आधारित कम्यूनिकेशन तैयार किया है.
अगला वीडियो
अगले चरण में, आपको Cloud ट्रेस की मदद से ट्रेस को विज़ुअलाइज़ करना होगा. साथ ही, इकट्ठा किए गए स्पैन का विश्लेषण करने का तरीका बताया जाएगा.
6. Cloud Trace की मदद से ट्रेस को विज़ुअलाइज़ करें
OpenTelemetry की मदद से, आपने पूरे सिस्टम में ट्रेस को इंस्ट्रुमेंट किया है. आपने अब तक एचटीटीपी और gRPC सेवाएं इस्तेमाल करने का तरीका सीख लिया है. भले ही आपने उन्हें इंस्ट्रुमेंट करना सीख लिया है, लेकिन फिर भी आपने उनका विश्लेषण करना नहीं सीखा है. इस सेक्शन में, आपको stdout एक्सपोर्टर को Cloud Trace एक्सपोर्टर से बदलना होगा. साथ ही, आपको अपने ट्रेस का विश्लेषण करने का तरीका पता चलेगा.
क्लाउड ट्रेस एक्सपोर्टर का इस्तेमाल करना
OpenTelemetry की सबसे बड़ी खूबियों में से एक है, डिवाइस को प्लग किए जा सकने वाला टूल. अपने इंस्ट्रुमेंटेशन से इकट्ठा किए गए सभी स्पैन को विज़ुअलाइज़ करने के लिए, आपको stdout एक्सपोर्टर को Cloud Trace एक्सपोर्टर से बदलना होगा.
हर सेवा की main.go
फ़ाइलें खोलें और initTracer()
फ़ंक्शन ढूंढें. stdout एक्सपोर्टर जनरेट करने के लिए, लाइन को मिटाएं और इसके बजाय Cloud Trace एक्सपोर्टर बनाएं.
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 }
आपको इसी फ़ंक्शन को क्लाइंट और सर्वर सेवा में भी बदलाव करना होगा.
माइक्रोसर्विस चलाएं और ट्रेस की पुष्टि करें
बदलाव करने के बाद, क्लस्टर को सामान्य तरीके से skaffold कमांड की मदद से चलाएं.
skaffold dev
इसके बाद, आपको stdout पर स्ट्रक्चर्ड लॉग फ़ॉर्मैट में, स्पैन के बारे में ज़्यादा जानकारी नहीं दिखती, क्योंकि आपने एक्सपोर्टर को Cloud Trace से बदल दिया है.
कमांड आउटपुट
[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 ...
आइए, अब पुष्टि करते हैं कि सभी स्पैन, Cloud Trace पर सही तरीके से भेजे गए हैं या नहीं. Cloud Console को ऐक्सेस करें और "ट्रेस लिस्ट" पर जाएं. इसे खोज बॉक्स से ऐक्सेस करना आसान है. इसके अलावा, बाएं पैनल में मौजूद मेन्यू पर भी क्लिक किया जा सकता है. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
फिर आपको प्रतीक्षा अवधि ग्राफ़ में कई नीले धब्बे दिखाई देंगे. हर एक स्पॉट सिर्फ़ एक ट्रेस को दिखाता है.
इनमें से किसी एक पर क्लिक करें. इससे आपको ट्रेस में जानकारी दिखेगी. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
यहां तक कि इस सरल झटपट दृश्य से भी, आप पहले से ही काफ़ी जानकारी जानते हैं. उदाहरण के लिए, वॉटरफ़ॉल ग्राफ़ से, यह देखा जा सकता है कि इंतज़ार के समय की वजह, ज़्यादातर shakesapp.ShakespeareService/GetMatchCount
नाम वाले स्पैन से है. (ऊपर दी गई इमेज में 1 देखें) इसकी पुष्टि खास जानकारी वाली टेबल से की जा सकती है. (सबसे दायां कॉलम, हर स्पैन की अवधि दिखाता है.) साथ ही, यह ट्रेस "friend" क्वेरी के लिए था. (ऊपर की इमेज में दो विकल्प देखें)
इन छोटे विश्लेषणों को ध्यान में रखते हुए, शायद आपको पता चले कि आपको GetMatchCount
तरीके के बारे में ज़्यादा जानकारी चाहिए. Stdout जानकारी की तुलना में, विज़ुअलाइज़ेशन ज़्यादा कारगर होता है. Cloud Trace की जानकारी के बारे में ज़्यादा जानने के लिए, कृपया हमारे आधिकारिक दस्तावेज़ पर जाएं.
खास जानकारी
इस चरण में, आपने stdout एक्सपोर्टर को Cloud Trace से बदल दिया है और Cloud Trace पर विज़ुअलाइज़ किए गए ट्रेस को देखा है. साथ ही, आपने ट्रेस का विश्लेषण करना भी सीखा.
अगला वीडियो
अगले चरण में, आपको GetMatchCount में सब स्पैन जोड़ने के लिए, सर्वर सेवा के सोर्स कोड में बदलाव करना होगा.
7. बेहतर विश्लेषण के लिए सब स्पैन जोड़ें
पिछले चरण में, आपको loadgen से मिली दोतरफ़ा यात्रा के समय की वजह का पता चला है. यह ज़्यादातर सर्वर सेवा में GetMatchCount तरीके, gRPC हैंडलर के अंदर की प्रोसेस है. हालांकि, हमने हैंडलर के अलावा कोई अन्य जानकारी नहीं डाली है. इसलिए, हमें वॉटरफ़ॉल ग्राफ़ से ज़्यादा अहम जानकारी नहीं मिल सकी. ऐसा अक्सर तब होता है, जब हम माइक्रोसर्विस बनाना शुरू करते हैं.
इस सेक्शन में, हम एक सब-स्पैन दिखाएंगे, जहां सर्वर, Google Cloud Storage को कॉल करता है. ऐसा इसलिए, क्योंकि कुछ बाहरी नेटवर्क I/O इस प्रोसेस में ज़्यादा समय लेते हैं. ऐसे में, यह पता लगाना ज़रूरी है कि कॉल की वजह कॉल है या नहीं.
सर्वर में सब स्पैन का इंस्ट्रुमेंट जोड़ना
main.go
को सर्वर में खोलें और readFiles
फ़ंक्शन ढूंढें. यह फ़ंक्शन, शेक्सपियर के काम की सभी टेक्स्ट फ़ाइलों को फ़ेच करने के लिए, Google Cloud Storage को अनुरोध भेज रहा है. इस फ़ंक्शन में, सब-स्पैन बनाया जा सकता है, जैसे कि क्लाइंट सेवा में एचटीटीपी सर्वर इंस्ट्रुमेंटेशन के लिए आपने क्या किया.
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 ...
नई अवधि जोड़ने के लिए बस इतना ही. आइए देखते हैं कि ऐप्लिकेशन चलाकर यह कितना काम करता है.
माइक्रोसर्विस चलाएं और ट्रेस की पुष्टि करें
बदलाव करने के बाद, क्लस्टर को सामान्य तरीके से skaffold कमांड की मदद से चलाएं.
skaffold dev
साथ ही, ट्रेस सूची में से query.request
नाम का एक ट्रेस चुनें. आपको shakesapp.ShakespeareService/GetMatchCount
में नए स्पैन के अलावा, मिलता-जुलता ट्रेस वॉटरफ़ॉल ग्राफ़ दिखेगा. (नीचे लाल आयत से घिरा स्पैन)
इस ग्राफ़ से यह पता लगाया जा सकता है कि Google Cloud Storage को बाहरी कॉल करने में काफ़ी समय लगता है, लेकिन इंतज़ार का समय ज़्यादातर दूसरी चीज़ों की वजह से हो रहा है.
ट्रेस वॉटरफ़ॉल ग्राफ़ से, सिर्फ़ कुछ लुक के ज़रिए आपको पहले ही काफ़ी अहम जानकारी मिल चुकी है. आपको अपने आवेदन में, परफ़ॉर्मेंस से जुड़ी अन्य जानकारी कैसे मिलती है? अब आपको प्रोफ़ाइलर के बारे में जानकारी मिल जाएगी, लेकिन फ़िलहाल कोडलैब के इस सेशन को खत्म करने का तरीका अपनाकर, प्रोफ़ाइलर के सभी ट्यूटोरियल को पार्ट 2 में भेज दें.
खास जानकारी
इस चरण में, आपने सर्वर सेवा में एक और अवधि का इस्तेमाल किया और सिस्टम के इंतज़ार के समय के बारे में अहम जानकारी हासिल की.
8. बधाई हो
आपने OpenTelemery की मदद से, डिस्ट्रिब्यूटेड ट्रेस बना लिए हैं. साथ ही, आपने Google Cloud Trace की माइक्रोसेवा में, अनुरोध के बाद के समय की पुष्टि कर दी है.
ज़्यादा समय तक कसरत करने के लिए, इन विषयों को खुद आज़माया जा सकता है.
- फ़िलहाल, लागू करने की प्रोसेस के दौरान हेल्थ जांच से जनरेट हुए सभी स्पैन भेजे जाते हैं. (
grpc.health.v1.Health/Check
) Cloud Traces से इन स्पैन को कैसे फ़िल्टर किया जा सकता है? हिंट यहां दिया गया है. - इवेंट लॉग को स्पैन के साथ जोड़ें और देखें कि यह 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 और एडमिन" > "सेटिंग", और फिर "बंद करें" पर क्लिक करें बटन.
इसके बाद, डायलॉग बॉक्स में दिए गए फ़ॉर्म में प्रोजेक्ट का आईडी डालें, न कि प्रोजेक्ट का नाम डालें और बंद करने की पुष्टि करें.