1. مقدمه
آخرین به روز رسانی: 2022-07-15
قابلیت مشاهده برنامه
مشاهده پذیری و OpenTelemetry
مشاهده پذیری اصطلاحی است که برای توصیف یک ویژگی از یک سیستم استفاده می شود. یک سیستم با قابلیت مشاهده به تیم ها اجازه می دهد تا به طور فعال سیستم خود را اشکال زدایی کنند. در آن زمینه، سه رکن مشاهده پذیری; گزارشها، متریکها و ردیابیها ابزار اساسی سیستم برای به دست آوردن قابلیت مشاهده هستند.
OpenTelemetry مجموعهای از مشخصات، کتابخانهها و عواملی است که ابزار دقیق و صادرات دادههای تلهمتری (لاگها، متریکها و ردیابیها) را تسریع میبخشد. OpenTelemetry یک پروژه استاندارد باز و جامعه محور تحت CNCF است. با استفاده از کتابخانههایی که پروژه و اکوسیستم آن ارائه میکند، توسعهدهندگان میتوانند برنامههای کاربردی خود را به روش خنثی فروشنده و در برابر معماریهای چندگانه ابزار کنند.
همچنین علاوه بر سه رکن مشاهدهپذیری، نمایهسازی پیوسته یکی دیگر از مؤلفههای کلیدی برای مشاهدهپذیری است و پایگاه کاربران را در صنعت گسترش میدهد . Cloud Profiler یکی از مبتکران است و یک رابط کاربری آسان برای بررسی معیارهای عملکرد در پشته های تماس برنامه ارائه می دهد.
این آزمایشگاه کد قسمت 1 از مجموعه است و ردیابی های توزیع شده ابزار دقیق در میکروسرویس ها با OpenTelemetry و Cloud Trace را پوشش می دهد. قسمت 2 نمایه سازی مداوم با Cloud Profiler را پوشش می دهد.
ردیابی توزیع شده
در میان گزارشها، متریکها و ردیابیها، ردیابی تلهمتری است که تأخیر بخش خاصی از فرآیند را در سیستم نشان میدهد. بهویژه در عصر میکروسرویسها، ردیابی توزیعشده محرک قوی برای کشف تنگناهای تأخیر در سیستم توزیع کلی است.
هنگام تجزیه و تحلیل ردیابی های توزیع شده، تجسم داده های ردیابی کلید درک تأخیرهای کلی سیستم در یک نگاه است. در ردیابی توزیعشده، ما مجموعهای از تماسها را برای پردازش یک درخواست واحد به نقطه ورودی سیستم به شکلی از Trace که حاوی چند دهانه است، مدیریت میکنیم.
Span واحدی از کار انجام شده در یک سیستم توزیع شده را نشان می دهد که زمان شروع و توقف را ثبت می کند. دهانه ها اغلب روابط سلسله مراتبی بین یکدیگر دارند - در تصویر زیر، تمام دهانه های کوچکتر، گستره های فرزند از یک گستره پیام / بزرگ هستند، و در یک Trace جمع شده اند که مسیر کار را از طریق یک سیستم نشان می دهد.
Google Cloud Trace یکی از گزینههای بکاند ردیابی توزیعشده است و به خوبی با سایر محصولات موجود در Google Cloud ادغام شده است.
چیزی که خواهی ساخت
در این نرمافزار، شما میخواهید اطلاعات ردیابی را در سرویسهایی به نام «برنامه Shakespeare» (معروف به Shakesapp) که روی خوشه Google Kubernetes Engine اجرا میشود، ابزار کنید. معماری Shakesapp به شرح زیر است:
- Loadgen یک رشته پرس و جو را در HTTP برای مشتری ارسال می کند
- کلاینت ها از طریق پرس و جو از بارگذار به سرور در gRPC عبور می کنند
- سرور درخواست مشتری را میپذیرد، همه آثار Shakespare را در قالب متن از Google Cloud Storage واکشی میکند، خطوطی را که حاوی پرس و جو هستند جستجو میکند و شماره خطی را که مطابقت دارد به مشتری برمیگرداند.
شما اطلاعات ردیابی را در سراسر درخواست تنظیم خواهید کرد. پس از آن، یک عامل پروفایلر را در سرور تعبیه کرده و گلوگاه را بررسی خواهید کرد.
چیزی که یاد خواهید گرفت
- چگونه با پروژه OpenTelemetry Trace در Go شروع کنیم
- نحوه ایجاد یک span با کتابخانه
- نحوه انتشار زمینه های دهانه در سراسر سیم بین اجزای برنامه
- نحوه ارسال داده های ردیابی به Cloud Trace
- نحوه تجزیه و تحلیل ردیابی در Cloud Trace
این کد لبه توضیح می دهد که چگونه میکروسرویس های خود را ابزار دقیق کنید. برای سهولت درک، این مثال فقط شامل 3 مؤلفه (مولد بار، مشتری و سرور) است، اما میتوانید همان فرآیند توضیح داده شده در این کد لبه را برای سیستمهای پیچیدهتر و بزرگتر اعمال کنید.
آنچه شما نیاز دارید
- دانش اولیه Go
- دانش اولیه Kubernetes
2. راه اندازی و الزامات
تنظیم محیط خود به خود
اگر قبلاً یک حساب Google (Gmail یا Google Apps) ندارید، باید یک حساب ایجاد کنید . به کنسول Google Cloud Platform ( consol.cloud.google.com ) وارد شوید و یک پروژه جدید ایجاد کنید.
اگر قبلاً پروژه ای دارید، روی منوی کشویی انتخاب پروژه در سمت چپ بالای کنسول کلیک کنید:
و روی دکمه "پروژه جدید" در گفتگوی حاصل کلیک کنید تا یک پروژه جدید ایجاد کنید:
اگر قبلاً پروژه ای ندارید، باید یک دیالوگ مانند این را ببینید تا اولین پروژه خود را ایجاد کنید:
گفتگوی بعدی ایجاد پروژه به شما امکان می دهد جزئیات پروژه جدید خود را وارد کنید:
شناسه پروژه را به خاطر بسپارید، که یک نام منحصر به فرد در تمام پروژه های Google Cloud است (نام بالا قبلاً گرفته شده است و برای شما کار نخواهد کرد، متأسفیم!). بعداً در این آزمایشگاه کد به عنوان PROJECT_ID نامیده خواهد شد.
در مرحله بعد، اگر قبلاً این کار را انجام نداده اید، برای استفاده از منابع Google Cloud و فعال کردن Cloud Trace API، باید صورتحساب را در Developers Console فعال کنید .
گذراندن این کد نباید بیش از چند دلار هزینه داشته باشد، اما اگر تصمیم به استفاده از منابع بیشتری داشته باشید یا آنها را در حال اجرا رها کنید، ممکن است بیشتر باشد (به بخش "پاکسازی" در انتهای این سند مراجعه کنید). قیمتهای Google Cloud Trace، Google Kubernetes Engine و Google Artifact Registry در اسناد رسمی ذکر شده است.
- قیمت گذاری مجموعه عملیات Google Cloud | مجموعه عملیات
- قیمت گذاری | مستندات موتور Kubernetes
- قیمت گذاری رجیستری مصنوعات | اسناد ثبت مصنوعات
کاربران جدید Google Cloud Platform واجد شرایط استفاده آزمایشی رایگان 300 دلاری هستند که باید این نرم افزار کد را کاملاً رایگان کند.
Google Cloud Shell Setup
در حالی که Google Cloud و Google Cloud Trace میتوانند از راه دور از لپتاپ شما کار کنند، در این نرمافزار از Google Cloud Shell استفاده میکنیم، یک محیط خط فرمان که در Cloud اجرا میشود.
این ماشین مجازی مبتنی بر دبیان با تمام ابزارهای توسعه که شما نیاز دارید بارگذاری شده است. این دایرکتوری اصلی 5 گیگابایتی دائمی را ارائه می دهد و در Google Cloud اجرا می شود و عملکرد شبکه و احراز هویت را بسیار افزایش می دهد. این بدان معنی است که تمام چیزی که برای این کد لبه نیاز دارید یک مرورگر است (بله، روی کروم بوک کار می کند).
برای فعال کردن Cloud Shell از Cloud Console، کافی است روی Activate 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 برای همه کدهای منبع استفاده می کنیم. دستور زیر را در Cloud Shell اجرا کنید و تأیید کنید که نسخه Go 1.17+ است یا خیر
go version
خروجی فرمان
go version go1.18.3 linux/amd64
یک خوشه Google Kubernetes راه اندازی کنید
در این کد لبه، شما مجموعهای از ریزسرویسها را در موتور Google Kubernetes (GKE) اجرا خواهید کرد. فرآیند این کد لبه به شرح زیر است:
- پروژه پایه را در Cloud Shell دانلود کنید
- میکروسرویس ها را در ظروف بسازید
- بارگذاری کانتینرها در Google Artifact Registry (GAR)
- کانتینرها را روی GKE مستقر کنید
- کد منبع خدمات را برای ابزار دقیق ردیابی تغییر دهید
- به مرحله 2 بروید
موتور Kubernetes را فعال کنید
ابتدا، ما یک خوشه Kubernetes را راه اندازی می کنیم که در آن Shakesapp روی GKE اجرا می شود، بنابراین باید GKE را فعال کنیم. به منوی "Kubernetes Engine" بروید و دکمه ENABLE را فشار دهید.
اکنون شما آماده ایجاد یک خوشه Kubernetes هستید.
خوشه Kubernetes را ایجاد کنید
در Cloud Shell، دستور زیر را برای ایجاد یک خوشه Kubernetes اجرا کنید. لطفاً تأیید کنید که مقدار منطقه زیر ناحیه ای است که برای ایجاد مخزن رجیستری مصنوع استفاده خواهید کرد. اگر منطقه مخزن شما منطقه را پوشش نمی دهد، مقدار منطقه 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
رجیستری مصنوعات و راه اندازی اسکافولد
اکنون ما یک خوشه Kubernetes آماده برای استقرار داریم. در مرحله بعد ما برای یک رجیستری کانتینر برای کانتینرهای فشار و استقرار آماده می کنیم. برای این مراحل، باید یک Artifact Registry (GAR) و skaffold برای استفاده از آن راه اندازی کنیم.
راه اندازی رجیستری مصنوع
به منوی "Artifact Registry" بروید و دکمه ENABLE را فشار دهید.
پس از چند لحظه، مرورگر مخزن GAR را مشاهده خواهید کرد. روی دکمه "ایجاد مخزن" کلیک کنید و نام مخزن را وارد کنید.
در این codelab، من مخزن جدید trace-codelab
را نام میبرم. فرمت این مصنوع "Docker" و نوع مکان "Region" است. منطقه ای نزدیک به منطقه ای را که برای منطقه پیش فرض موتور محاسباتی Google تنظیم کرده اید، انتخاب کنید. به عنوان مثال، این مثال در بالا "us-central1-f" را انتخاب کرد، بنابراین در اینجا "us-central1 (آیووا)" را انتخاب می کنیم. سپس روی دکمه "CREATE" کلیک کنید.
اکنون "trace-codelab" را در مرورگر مخزن مشاهده می کنید.
ما بعداً به اینجا باز خواهیم گشت تا مسیر رجیستری را بررسی کنیم.
راه اندازی داربست
Skaffold ابزاری مفید برای ساختن میکروسرویس هایی است که روی Kubernetes اجرا می شوند. گردش کار ساخت، هل دادن و استقرار کانتینرهای برنامه ها را با مجموعه کوچکی از دستورات کنترل می کند. Skaffold به طور پیشفرض از Docker Registry بهعنوان رجیستری کانتینر استفاده میکند، بنابراین باید skaffold را برای شناسایی GAR در هنگام هل دادن کانتینرها پیکربندی کنید.
دوباره Cloud Shell را باز کنید و تأیید کنید که skaffold نصب شده است. (Cloud Shell به طور پیش فرض skaffold را در محیط نصب می کند.) دستور زیر را اجرا کنید و نسخه skaffold را ببینید.
skaffold version
خروجی فرمان
v1.38.0
اکنون، می توانید مخزن پیش فرض را برای استفاده از skaffold ثبت کنید. برای به دست آوردن مسیر رجیستری، خود را به داشبورد آرتیفکت رجیستری بروید و روی نام مخزنی که در مرحله قبل تنظیم کرده اید کلیک کنید.
سپس مسیرهای پودر سوخاری را در بالای صفحه خواهید دید. کلیک کنید برای کپی کردن مسیر رجیستری در کلیپ بورد.
با کلیک بر روی دکمه کپی، گفتگو را در پایین مرورگر با پیامی مانند:
"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
اکنون میتوانید مرحله بعدی را برای راهاندازی یک ظرف Kubernetes در GKE انجام دهید.
خلاصه
در این مرحله، محیط Codelab خود را تنظیم می کنید:
- Cloud Shell را راه اندازی کنید
- یک مخزن رجیستری Artifact برای رجیستری کانتینر ایجاد کرد
- برای استفاده از رجیستری کانتینر، skaffold را تنظیم کنید
- یک خوشه Kubernetes ایجاد کرد که در آن میکروسرویس های Codelab اجرا می شوند
بعدی
در مرحله بعدی، میکروسرویس های خود را روی خوشه ایجاد، فشار داده و مستقر خواهید کرد
3. ساخت، فشار دادن و استقرار میکروسرویس ها
مطالب Codelab را دانلود کنید
در مرحله قبل تمام پیش نیازهای این کد لبه را تنظیم کرده ایم. اکنون شما آماده هستید تا کل میکروسرویس ها را روی آنها اجرا کنید. مواد Codelab در 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
- manifests: فایل های مانیفست Kubernetes
- proto: تعریف پروتو برای ارتباط بین مشتری و سرور
- src: دایرکتوری برای کد منبع هر سرویس
- skaffold.yaml: فایل پیکربندی برای skaffold
در این لبه کد، کد منبع واقع در پوشه step0
را به روز می کنید. همچنین می توانید برای پاسخ در مراحل زیر به کد منبع در پوشه های step[1-6]
مراجعه کنید. (قسمت 1 مرحله 0 تا 4 را پوشش می دهد و قسمت 2 مرحله 5 و 6 را پوشش می دهد)
دستور skaffold را اجرا کنید
در نهایت شما آماده ساخت، فشار دادن و استقرار کل محتوا در خوشه Kubernetes هستید که به تازگی ایجاد کرده اید. به نظر می رسد که شامل چندین مرحله است، اما واقعیت این است که skaffold همه چیز را برای شما انجام می دهد. بیایید آن را با دستور زیر امتحان کنیم:
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
خلاصه
در این مرحله، مواد Codelab را در محیط خود آماده کرده اید و طبق انتظار اجراهای skaffold را تأیید کرده اید.
بعدی
در مرحله بعد، کد منبع سرویس loadgen را برای ابزار دقیق اطلاعات ردیابی تغییر می دهید.
4. ابزار دقیق برای HTTP
مفهوم ابزار دقیق و انتشار
قبل از ویرایش کد منبع، اجازه دهید به طور خلاصه نحوه عملکرد ردیابی های توزیع شده را در یک نمودار ساده توضیح دهم.
در این مثال، ما کد را برای صادر کردن اطلاعات Trace و Span به Cloud Trace و انتشار متن ردیابی در درخواست از سرویس loadgen به سرویس سرور، ابزار میکنیم.
برنامهها باید ابردادههای Trace مانند Trace ID و Span ID را ارسال کنند تا Cloud Trace همه دهانههایی را که دارای شناسه ردیابی یکسان هستند در یک ردیابی جمع کند. همچنین برنامه نیاز به انتشار زمینه های ردیابی (ترکیبی از شناسه ردیابی و Span ID دهانه والد) در درخواست خدمات پایین دستی دارد، به طوری که آنها می توانند از اینکه با کدام بافت ردیابی مدیریت می کنند آگاه باشند.
OpenTelemetry به شما کمک می کند:
- برای تولید Trace ID و Span ID منحصر به فرد
- برای صادرات Trace ID و Span ID به باطن
- برای انتشار زمینه های ردیابی به سایر خدمات
- برای جاسازی ابرداده اضافی که به تجزیه و تحلیل ردیابی ها کمک می کند
اجزای موجود در OpenTelemetry Trace
فرآیند ردیابی ابزار ابزار با OpenTelemetry به شرح زیر است:
- یک صادرکننده ایجاد کنید
- یک TracerProvider ایجاد کنید که صادرکننده را در 1 پیوند دهد و آن را جهانی تنظیم کنید.
- TextMapPropagaror را برای تنظیم روش انتشار تنظیم کنید
- Tracer را از TracerProvider دریافت کنید
- Span را از Tracer ایجاد کنید
در حال حاضر، شما نیازی به درک ویژگی های دقیق در هر جزء ندارید، اما مهمترین چیزهایی که باید به خاطر بسپارید عبارتند از:
- صادرکننده در اینجا قابل اتصال به TracerProvider است
- TracerProvider تمام تنظیمات مربوط به نمونه برداری و صادرات ردیابی را در اختیار دارد
- همه ردیابی ها در شی Tracer دسته بندی می شوند
با درک این موضوع، اجازه دهید به کار کدگذاری واقعی برویم.
دهانه اول ابزار
خدمات ژنراتور بار ابزار
Cloud Shell Editor را با فشار دادن دکمه باز کنید در سمت راست بالای Cloud Shell. 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
. در پیاده سازی فعلی، بخش دارای 2 خط ورود به سیستم است که شروع و پایان فراخوانی تابع را ثبت می کند. حالا بیایید اطلاعات Span را ابزار کنیم تا تأخیر فراخوانی تابع را ردیابی کنیم.
ابتدا، همانطور که در بخش قبل ذکر شد، بیایید کل تنظیمات را برای 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 صادر می کند.
سپس آن را از تابع main فراخوانی می کنید. 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) ...
پس از اتمام تنظیمات، باید یک Span با شناسه Trace و Span ID منحصر به فرد ایجاد کنید. OpenTelemetry یک کتابخانه مفید برای آن فراهم می کند. بسته های جدید اضافی را به سرویس گیرنده HTTP ابزار اضافه کنید.
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" )
از آنجایی که مولد بار در حال فراخوانی سرویس مشتری در HTTP با net/http
در تابع runQuery
است، ما از بسته contrib برای net/http
استفاده می کنیم و ابزار دقیق را با پسوند httptrace
و بسته otelhttp
فعال می کنیم.
ابتدا یک بسته متغیر جهانی httpClient برای فراخوانی درخواست های HTTP از طریق کلاینت ابزاردار اضافه کنید.
step0/src/loadgen/main.go
var httpClient = http.Client{ Transport: otelhttp.NewTransport(http.DefaultTransport) }
سپس ابزار دقیق را در تابع runQuery
اضافه کنید تا با استفاده از OpenTelemetry، دامنه سفارشی را ایجاد کنید و دامنه تولید خودکار از مشتری HTTP سفارشی را ایجاد کنید. کاری که انجام خواهید داد این است:
- یک Tracer از
TracerProvider
جهانی باotel.Tracer()
دریافت کنید - با متد
Tracer.Start()
یک root span ایجاد کنید - پایان دادن به ریشه در یک زمان بندی دلخواه (در این مورد، پایان تابع
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 (برنامه مشتری HTTP) تمام شده است. لطفاً حتماً go.mod
و go.sum
خود را با دستور go mod
به روز کنید.
go mod tidy
خدمات مشتری ابزار
در قسمت قبل، قسمت محصور شده در مستطیل قرمز را در نقاشی زیر ابزارسازی کردیم. ما اطلاعات دهانه را در سرویس مولد بار ابزار دقیق کردیم. مشابه سرویس مولد بار، اکنون باید سرویس مشتری را ابزار دقیق کنیم. تفاوت با سرویس مولد بار در این است که سرویس مشتری باید اطلاعات Trace ID منتشر شده از سرویس مولد بار در هدر HTTP را استخراج کند و از شناسه برای تولید Spans استفاده کند.
Cloud Shell Editor را باز کنید و بستههای مورد نیاز را مانند سرویس load generator اضافه کنید.
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
را از loadgen کپی و پیست کنید و آن را در تابع 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 }
اکنون نوبت به دهانه های ساز رسیده است. از آنجایی که سرویس مشتری نیاز به پذیرش درخواست های HTTP از سرویس loadgen دارد، نیاز به ابزار دقیق کنترل کننده دارد. سرور HTTP در سرویس کلاینت با net/http پیاده سازی می شود و شما می توانید از بسته otelhttp
مانند کاری که در loadgen انجام دادیم استفاده کنید.
ابتدا ثبت handler را با otelhttp
Handler جایگزین می کنیم. در تابع main
، خطوطی را پیدا کنید که در آن هندلر HTTP با 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)
سپس، دهانه واقعی را در داخل هندلر ابزار می کنیم. تابع (*clientService) handler() را پیدا کنید و ابزار دقیق span را با 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
. همچنین متوجه می شوید که ویژگی embed "query"
دارای رشته پرس و جو است که به سرویس مشتری ارسال می شود.
خلاصه
در این مرحله، سرویس مولد بار و سرویس سرویس گیرنده را که در HTTP با هم ارتباط برقرار میکنند، تنظیم کردهاید و تأیید کردهاید که میتوانید با موفقیت Trace Context را در بین سرویسها منتشر کنید و اطلاعات Span را از هر دو سرویس به stdout صادر کنید.
بعدی
در مرحله بعد، سرویس سرویس گیرنده و سرویس سرور را برای تأیید نحوه انتشار Trace Context از طریق gRPC، ابزار میدهید.
5. ابزار دقیق برای gRPC
در مرحله قبل، نیمه اول درخواست را در این میکروسرویس ابزارسازی کردیم. در این مرحله سعی می کنیم ارتباط gRPC بین سرویس مشتری و سرویس سرور را ابزار کنیم. (مستطیل سبز و بنفش در تصویر زیر)
ابزار دقیق برای مشتری gRPC
اکوسیستم OpenTelemetry کتابخانههای مفید زیادی را ارائه میکند که به توسعهدهندگان کمک میکنند تا برنامههای کاربردی را ابزار کنند. در مرحله قبل از ابزار دقیق برای بسته net/http
استفاده کردیم. در این مرحله، همانطور که میخواهیم Trace Context را از طریق gRPC منتشر کنیم، از کتابخانه برای آن استفاده میکنیم.
ابتدا بسته gRPC از پیش ساخته شده به نام otelgrpc
را وارد می کنید.
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 می نامیم. اضافه کردن بسته جدید به بخش واردات مانند:
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
اکنون دوباره، شما یک دسته از اطلاعات span را در 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] } ...
متوجه میشوید که هیچ نام span را تعبیه نکردهاید و بهطور دستی دهانهها را با trace.Start()
یا span.SpanFromContext()
ایجاد نکردهاید. هنوز تعداد زیادی دهانه دریافت می کنید زیرا رهگیرهای gRPC آنها را ایجاد کرده اند.
خلاصه
در این مرحله، شما ارتباطات مبتنی بر gRPC را با پشتیبانی از کتابخانههای اکوسیستم OpenTelemetry ابزارسازی کردید.
بعدی
در مرحله بعد، در نهایت ردیابی را با Cloud Trace تجسم خواهید کرد و یاد خواهید گرفت که چگونه دهانه های جمع آوری شده را تجزیه و تحلیل کنید.
6. ردیابی را با Cloud Trace تجسم کنید
شما در کل سیستم با OpenTelemetry، ردیابیها را ابزارسازی کردهاید. شما تاکنون نحوه ابزاردهی سرویس های HTTP و gRPC را یاد گرفته اید. اگرچه یاد گرفته اید که چگونه آنها را ابزار کنید، اما هنوز یاد نگرفته اید که چگونه آنها را تجزیه و تحلیل کنید. در این بخش، صادرکنندگان stdout را با صادرکنندگان Cloud Trace جایگزین میکنید و یاد میگیرید که چگونه ردیابیهای خود را تجزیه و تحلیل کنید.
از صادرکننده 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 اطلاعات span زیادی را در قالب گزارشهای ساختاری مشاهده نمیکنید، زیرا صادرکننده را با Cloud Trace one جایگزین کردهاید.
خروجی فرمان
[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 دسترسی پیدا کنید و به "Trace list" بروید. دسترسی به آن از کادر جستجو آسان است. در غیر این صورت، می توانید روی منوی موجود در صفحه سمت چپ کلیک کنید.
سپس می بینید که تعداد زیادی لکه های آبی در سراسر نمودار تأخیر توزیع شده اند. هر نقطه نشان دهنده یک اثر واحد است.
روی یکی از آنها کلیک کنید و می توانید جزئیات داخل ردیابی را ببینید.
حتی از این نگاه سریع ساده، شما در حال حاضر بینش های زیادی را می دانید. به عنوان مثال، از نمودار آبشار ، میتوانید ببینید که علت تأخیر بیشتر به دلیل دامنهای به نام shakesapp.ShakespeareService/GetMatchCount
است. (نگاه کنید به 1 در تصویر بالا) شما می توانید آن را از جدول خلاصه تایید کنید. (راست ترین ستون، مدت زمان هر بازه را نشان می دهد.) همچنین، این ردیابی برای پرس و جو "friend" بود. (2 را در تصویر بالا ببینید)
با توجه به این تجزیه و تحلیل های کوتاه، ممکن است متوجه شوید که باید دهانه های دانه بندی بیشتری را در روش GetMatchCount
بدانید. در مقایسه با اطلاعات stdout، تجسم قدرتمند است. برای کسب اطلاعات بیشتر در مورد جزئیات Cloud Trace، لطفاً از اسناد رسمی ما دیدن کنید.
خلاصه
در این مرحله، صادرکننده stdout را با Cloud Trace one جایگزین کردید و ردیابیها را در Cloud Trace مشاهده کردید. همچنین یاد گرفتید که چگونه شروع به تجزیه و تحلیل ردیابی کنید.
بعدی
در مرحله بعد، کد منبع سرویس سرور را تغییر می دهید تا یک زیر دامنه در GetMatchCount اضافه کنید.
7. برای تجزیه و تحلیل بهتر، زیر دامنه را اضافه کنید
در مرحله قبل، متوجه شدید که علت زمان رفت و برگشت مشاهده شده از loadgen، بیشتر فرآیند داخل متد GetMatchCount، کنترلگر gRPC، در سرویس سرور است. با این حال، از آنجایی که ما هیچ چیز دیگری غیر از کنترل کننده را ابزار نکرده ایم، نمی توانیم بینش بیشتری از نمودار آبشار پیدا کنیم. این یک مورد رایج زمانی است که ما ابزار دقیق میکروسرویس ها را شروع می کنیم.
در این بخش، ما میخواهیم یک زیر دامنه را که سرور در آن Google Cloud Storage را فراخوانی میکند، ابزار کنیم، زیرا در مواردی که برخی از ورودی/خروجی شبکههای خارجی زمان زیادی را در این فرآیند میبرند، رایج است و تشخیص اینکه آیا تماس علت آن است یا خیر، بسیار مهم است.
ابزار یک زیر دامنه در سرور
main.go
را در سرور باز کنید و تابع readFiles
پیدا کنید. این تابع در حال فراخوانی درخواستی به Google Cloud Storage برای واکشی همه فایلهای متنی آثار شکسپیر است. در این تابع، می توانید یک زیر دامنه ایجاد کنید، مانند کاری که برای ابزار دقیق سرور HTTP در سرویس مشتری انجام دادید.
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 برای آن زبان ابزار کنید.
همچنین، اگر میخواهید پس از این در مورد پروفایلکننده اطلاعات کسب کنید، لطفاً به قسمت 2 بروید. در آن صورت میتوانید از بخش پاکسازی زیر صرفنظر کنید.
تمیز کردن
پس از این کد، لطفاً خوشه 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 & Admin" > "Settings" را انتخاب کنید و سپس روی دکمه "SHUT DOWN" کلیک کنید.
سپس شناسه پروژه (نه نام پروژه) را در فرم موجود در گفتگو وارد کرده و خاموش شدن را تأیید کنید.