1. مقدمة
تاريخ آخر تعديل: 15/07/2022
رصد التطبيق
إمكانية المراقبة وOpenTelemetry
قابلية المراقبة هي المصطلح المستخدَم لوصف سمة نظام معيّن. يتيح النظام الذي يتضمّن ميزة "إمكانية المراقبة" للفرق تصحيح أخطاء نظامها بشكل نشط. في هذا السياق، تشكّل السجلّات والمقاييس والتتبّعات ثلاثة من ركائز قابلية المراقبة، وهي الأدوات الأساسية التي يحصل بها النظام على قابلية المراقبة.
OpenTelemetry هي مجموعة من المواصفات والمكتبات والعوامل التي تسريع عملية قياس بيانات المراقبة وتصديرها (السجلّات والمقاييس والتتبّعات) التي تتطلّبها ميزة "الرصد". OpenTelemetry هو مشروع مفتوح المصدر يستند إلى معايير مفتوحة ويديره المجتمع، وهو تابع لمؤسسة CNCF. من خلال استخدام المكتبات التي يوفّرها المشروع والمنظومة المتكاملة، يتمكّن المطوّرون من قياس أداء تطبيقاتهم بطريقة محايدة تجاه المورّدين ووفقًا لتصاميم متعددة.
بالإضافة إلى الركائز الثلاث للمراقبة، تشكّل ميزة "الملف الشخصي المستمر" عنصرًا رئيسيًا آخر للمراقبة، وهي توسّع قاعدة المستخدمين في المجال. إنّ أداة Cloud Profiler هي إحدى الأدوات الأصلية التي توفّر واجهة سهلة للتوغّل في مقاييس الأداء في تسلسلات استدعاء التطبيقات.
هذا الدرس التطبيقي حول الترميز هو الجزء 1 من السلسلة، ويتناول تجهيز عمليات التتبّع الموزّعة في الخدمات المصغرة باستخدام OpenTelemetry وCloud Trace. سيتناول الجزء 2 إعداد الملفات الشخصية المستمرة باستخدام Cloud Profiler.
التتبُّع الموزَّع
من بين السجلات والمقاييس والملفات المُتتبّعة، يُعدّ التتبّع هو بيانات المراقبة التي تُظهر وقت استجابة جزء معيّن من العملية في النظام. وخصوصًا في عصر الخدمات المصغرة، تُعدّ التتبُّع الموزّع عاملاً قويًا لتحديد نقاط الاختناق في وقت الاستجابة في النظام الموزّع بشكل عام.
عند تحليل عمليات التتبّع الموزّعة، يُعدّ تصور بيانات التتبّع هو المفتاح لفهم أوقات استجابة النظام الإجمالية بنظرة سريعة. في التتبُّع الموزّع، نعالج مجموعة من طلبات معالجة طلب واحد إلى نقطة دخول النظام في شكل تتبُّع يحتوي على عدة عمليات span.
تمثّل الفترة وحدة فردية من العمل الذي يتمّ تنفيذه في نظام موزّع، وتُسجّل أوقات البدء والتوقف. غالبًا ما تكون هناك علاقات هرمية بين النطاقات. في الصورة أدناه، جميع النطاقات الأصغر هي نطاقات فرعية لنطاق /messages كبير، ويتم تجميعها في تتبع واحد يعرض مسار العمل من خلال نظام.
Google Cloud Trace هو أحد خيارات الخلفية لتتبُّع الأداء الموزّع، وهو مدمج بشكل جيد مع المنتجات الأخرى في Google Cloud.
التطبيق الذي ستصممه
في هذا الدرس التعليمي حول رموز البرامج، ستستخدِم أداة تتبُّع المعلومات في الخدمات التي تُعرف باسم "تطبيق Shakespeare" (المعروف أيضًا باسم Shakesapp) الذي يعمل على مجموعة Google Kubernetes Engine. في ما يلي بنية Shakesapp:
- تُرسِل أداة Loadgen سلسلة طلب إلى العميل باستخدام بروتوكول HTTP.
- يُرسِل العملاء طلب البحث من LoadGen إلى الخادم في gRPC.
- يقبل الخادم طلب البحث من العميل، ويُجلب جميع أعمال شكسبير بتنسيق نصي من Google Cloud Storage، ويبحث في السطور التي تحتوي على طلب البحث ويعرض رقم السطر الذي تطابق مع العميل.
ستُعدّ معلومات التتبّع في الطلب. بعد ذلك، عليك تضمين وكيل ملفّ تعريف في الخادم والتحقيق في نقطة الاختناق.
ما ستتعرّف عليه
- كيفية بدء استخدام مكتبات تتبُّع OpenTelemetry في مشروع Go
- كيفية إنشاء نطاق باستخدام المكتبة
- كيفية نشر سياقات النطاقات على مستوى التطبيق بين مكوّنات التطبيق
- كيفية إرسال بيانات التتبّع إلى Cloud Trace
- كيفية تحليل التتبّع في Cloud Trace
يوضّح هذا الدليل التعليمي كيفية قياس أداء خدماتك المصغرة. لتسهيل فهم هذا المثال، لا يحتوي إلا على 3 مكوّنات (مُنشئ الحمل والعميل والخادم)، ولكن يمكنك تطبيق العملية نفسها الموضّحة في هذا الدليل التعليمي على الأنظمة الأكثر تعقيدًا وكبرًا.
المتطلبات
- معرفة أساسية بلغة Go
- معرفة أساسية بنظام Kubernetes
2. الإعداد والمتطلبات
إعداد البيئة حسب السرعة التي تناسبك
إذا لم يكن لديك حساب على Google (Gmail أو Google Apps)، عليك إنشاء حساب. سجِّل الدخول إلى وحدة تحكُّم Google Cloud Platform ( console.cloud.google.com) وأنشِئ مشروعًا جديدًا.
إذا كان لديك مشروع، انقر على القائمة المنسدلة لاختيار المشروع في أعلى يمين وحدة التحكّم:
انقر على الزر "مشروع جديد" في مربّع الحوار الناتج لإنشاء مشروع جديد:
إذا لم يكن لديك مشروع، من المفترض أن يظهر لك مربّع حوار مثل هذا لإنشاء مشروعك الأول:
يتيح لك مربّع الحوار اللاحق لإنشاء المشروع إدخال تفاصيل مشروعك الجديد:
تذكَّر معرّف المشروع، وهو اسم فريد في جميع مشاريع Google Cloud (سبق أن تم استخدام الاسم أعلاه ولن يكون متاحًا لك). وسيتم الإشارة إليه لاحقًا في هذا الدليل التعليمي باسم PROJECT_ID.
بعد ذلك، عليك تفعيل الفوترة في Developers Console إذا لم يسبق لك ذلك لاستخدام موارد Google Cloud وتفعيل 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" سيكون مجانيًا بالكامل.
إعداد Google Cloud Shell
على الرغم من أنّه يمكن تشغيل Google Cloud وGoogle Cloud Trace عن بُعد من الكمبيوتر المحمول، سنستخدم في هذا الدليل التعليمي Google Cloud Shell، وهي بيئة سطر أوامر تعمل في السحابة الإلكترونية.
تم تجهيز هذا الجهاز الافتراضي المستنِد إلى Debian بجميع أدوات التطوير التي ستحتاج إليها. ويقدّم هذا الدليل دليلاً منزليًا دائمًا بسعة 5 غيغابايت ويتم تشغيله في Google Cloud، ما يُحسِّن بشكل كبير أداء الشبكة والمصادقة. وهذا يعني أنّ كل ما ستحتاجه لاستخدام هذا البرنامج التعليمي هو متصفّح (نعم، يعمل على جهاز Chromebook).
لتفعيل Cloud Shell من Cloud Console، ما عليك سوى النقر على رمز تفعيل 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 Engine (GKE). في ما يلي خطوات هذا الدليل التعليمي حول الرموز البرمجية:
- تنزيل المشروع الأساسي في Cloud Shell
- إنشاء خدمات صغيرة في حاويات
- تحميل الحاويات إلى Google Artifact Registry (GAR)
- نشر الحاويات على GKE
- تعديل رمز الخدمات المصدر لأدوات تتبُّع الأداء
- الانتقال إلى الخطوة 2
تفعيل Kubernetes Engine
أولاً، نُعدّ مجموعة Kubernetes التي يعمل عليها تطبيق Shakesapp على GKE، لذا علينا تفعيل GKE. انتقِل إلى قائمة "محرك Kubernetes" واضغط على زر ENABLE (تفعيل).
أنت الآن جاهز لإنشاء مجموعة 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 وSkaffold
لدينا الآن مجموعة Kubernetes جاهزة للنشر. بعد ذلك، نستعد لإنشاء مستودع حاويات لدفع الحاويات ونشرها. لتنفيذ هذه الخطوات، علينا إعداد "مستودع العناصر" (GAR) وSkaflold لاستخدامه.
إعداد Artifact Registry
انتقِل إلى قائمة "مستودع العناصر" واضغط على الزر "تفعيل".
بعد بضع لحظات، سيظهر لك متصفّح مستودع GAR. انقر على الزر "إنشاء مستودع" وأدخِل اسم المستودع.
في هذا الدليل التعليمي حول الرموز البرمجية، سنسمي المستودع الجديد trace-codelab
. تنسيق العنصر هو "Docker" ونوع الموقع الجغرافي هو "المنطقة". اختَر المنطقة القريبة من المنطقة التي ضبطتها للمنطقة التلقائية في Google Compute Engine. على سبيل المثال، تم اختيار "us-central1-f" أعلاه، لذلك نختار هنا "us-central1 (Iowa)". بعد ذلك، انقر على الزر "إنشاء".
سيظهر لك الآن "trace-codelab" في متصفّح المستودع.
سنعود إلى هذه الصفحة لاحقًا للتحقّق من مسار السجلّ.
إعداد Skaffold
Skaffold هي أداة مفيدة عند العمل على إنشاء خدمات مصغّرة تعمل على Kubernetes. وتتولى هذه الأداة سير عمل إنشاء حاويات التطبيقات ودفعها ونشرها باستخدام مجموعة صغيرة من الأوامر. يستخدم Skaffold تلقائيًا Docker Registry كسجلّ حاويات، لذا عليك ضبط Skaffold للتعرّف على GAR عند دفع الحاويات إليه.
افتح Cloud Shell مرة أخرى وتأكَّد مما إذا كان skaffold مثبّتًا. (تثبِّت أداة Cloud Shell حزمة skaffold في البيئة تلقائيًا). نفِّذ الأمر التالي واطّلِع على إصدار skaffold.
skaffold version
ناتج الأمر
v1.38.0
يمكنك الآن تسجيل المستودع التلقائي لاستخدامه في skaffold. للحصول على مسار التسجيل، انتقِل إلى لوحة بيانات "مستودع العناصر" وانقر على اسم المستودع الذي أعددته للتو في الخطوة السابقة.
بعد ذلك، ستظهر لك مسارات أشرطة التنقّل في أعلى الصفحة. انقر على رمز لنسخ مسار التسجيل إلى الحافظة.
عند النقر على زر النسخ، سيظهر لك مربّع الحوار في أسفل المتصفّح مع رسالة مثل:
تم نسخ "us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab"
ارجع إلى Cloud Shell. نفِّذ الأمر 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 Registry لقاعدة بيانات المسجّلين للحاويات
- إعداد skaffold لاستخدام قاعدة بيانات حاويات التطبيقات
- إنشاء مجموعة Kubernetes التي يتم فيها تشغيل الخدمات المصغرة في الدرس التطبيقي
الخطوة التالية
في الخطوة التالية، عليك إنشاء خدماتك المصغرة ودفعها ونشرها على المجموعة.
3- إنشاء الخدمات المصغرة ودفعها ونشرها
تنزيل مواد الدرس التطبيقي حول الترميز
في الخطوة السابقة، أعددنا جميع المتطلبات الأساسية لهذا البرنامج التعليمي. أنت الآن جاهز لتشغيل خدمات ميكرو كاملة عليها. يتم استضافة مواد ورشة رموز البرامج على GitHub، لذا نزِّلها إلى بيئة Cloud Shell باستخدام الأمر git التالي.
cd ~ git clone https://github.com/ymotongpoo/opentelemetry-trace-codelab-go.git cd opentelemetry-trace-codelab-go
بنية الدليل للمشروع هي على النحو التالي:
. ├── README.md ├── step0 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step1 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step2 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step3 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step4 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step5 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src └── step6 ├── manifests ├── proto ├── skaffold.yaml └── src
- ملفات البيان: ملفات بيان Kubernetes
- proto: تعريف 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
ملخّص
في هذه الخطوة، أعددت مادة ورشة رموز البرامج في بيئتك وتأكّدت من أنّ أداة skaffold تعمل على النحو المتوقّع.
الخطوة التالية
في الخطوة التالية، عليك تعديل رمز المصدر لخدمة loadgen لإعداد معلومات التتبّع.
4. قياس حالة HTTP
مفهوم أدوات تتبُّع الأخطاء ونشرها
قبل تعديل رمز المصدر، دعني أشرح لك بإيجاز طريقة عمل عمليات التتبّع الموزّعة في مخطّط بياني بسيط.
في هذا المثال، نُعدّ الرمز البرمجي لتصدير معلومات التتبّع وSpan إلى Cloud Trace ونشر سياق التتبّع على مستوى الطلب من خدمة loadgen إلى خدمة الخادم.
يجب أن تُرسِل التطبيقات البيانات الوصفية للتتبّع، مثل معرّف التتبّع ومعرّف النطاق، لكي يتمكّن Cloud Trace من تجميع كل النطاقات التي لها معرّف التتبّع نفسه في عملية تتبّع واحدة. يجب أيضًا أن ينشر التطبيق سياقات التتبّع (مجموعة معرّف التتبّع ومعرّف الفاصل الزمني للفاصل الزمني الرئيسي) عند طلب الخدمات في مرحلة ما بعد المعالجة، حتى يتمكّن من معرفة سياق التتبّع الذي يعالجه.
تساعدك OpenTelemetry في:
- لإنشاء معرّفَي Trace ID وSpan ID فريدَين
- لتصدير معرّف التتبّع ومعرّف النطاق إلى الخلفية
- لنشر سياقات التتبُّع إلى خدمات أخرى
- لتضمين بيانات وصفية إضافية تساعد في تحليل عمليات التتبّع
المكوّنات في "تتبُّع OpenTelemetry"
في ما يلي خطوات إعداد عملية تتبُّع التطبيقات باستخدام OpenTelemetry:
- إنشاء مصدر
- أنشئ TracerProvider يربط المُصدِّر في 1 واضبطه على أنّه عام.
- اضبط TextMapPropagaror لتحديد طريقة النشر.
- الحصول على أداة التتبّع من TracerProvider
- إنشاء مسار استكشاف من أداة التتبُّع
في الوقت الحالي، لا تحتاج إلى فهم السمات التفصيلية في كل مكوّن، ولكن أهم ما يجب تذكُّره هو:
- يمكن توصيل أداة التصدير هذه بـ TracerProvider.
- يحتوي TracerProvider على جميع الإعدادات المتعلّقة بتحليل عيّنات التتبُّع وتصديرها.
- يتم تجميع جميع عمليات التتبّع في عنصر Tracer
بعد فهم ذلك، لننتقل إلى عمل الترميز الفعلي.
النطاق الأول للأداة
خدمة أداة إنشاء الحمل
افتح "محرر Cloud Shell" من خلال الضغط على الزر في أعلى يسار 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
فيها. في التنفيذ الحالي، يتضمّن القسم سطرَي سجلّ يسجّلان بداية طلب الدالة ونهايته. الآن، لنستخدم معلومات 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 بتنسيق منظَّم.
بعد ذلك، يمكنك استدعاؤها من الدالة الرئيسية. اتصل بـ 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 ID وSpan ID فريدَين. توفّر OpenTelemetry مكتبة مفيدة لذلك. أضِف حِزمًا جديدة إضافية إلى برنامج HTTP client الخاص بالتطبيق.
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 المخصّص. إليك الخطوات التي يجب اتّباعها:
- الحصول على جهاز التتبُّع
TracerProvider
منotel.Tracer()
- إنشاء عنصر span للجذر باستخدام الطريقة
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 (تطبيق عميل HTTP). يُرجى التأكّد من تعديل go.mod
وgo.sum
باستخدام الأمر go mod
.
go mod tidy
خدمة عملاء Instrument
في القسم السابق، جهزنا الجزء المُدرَج في المستطيل الأحمر في الرسم أدناه. لقد زوّدنا خدمة "مولد الحمل" بمعلومات عن النطاق. على غرار خدمة إنشاء الحمل، نحتاج الآن إلى تجهيز خدمة العميل. يختلف ذلك عن خدمة إنشاء الحملات في أنّ خدمة العميل تحتاج إلى استخراج معلومات رقم تعريف التتبّع التي يتم نشرها من خدمة إنشاء الحملات في عنوان HTTP واستخدام رقم التعريف لإنشاء وحدات المعالجة.
افتح محرِّر Cloud Shell وأضِف الحِزم المطلوبة كما فعلنا مع خدمة إنشاء الحملات.
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.
أولاً، نستبدل تسجيل المعالِج بمعالِج otelhttp
. في الدالة 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)
بعد ذلك، نُجهِّز النطاق الفعلي داخل المعالج. ابحث عن func (*clientService) handler()، وأضِف أدوات قياس المدة باستخدام 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)) ...
بعد تنفيذ جميع عمليات الرصد أعلاه، تكون قد أكملت عملية تتبُّع الأداء بين loadgen والعميل. لنطّلع على آلية عملها. شغِّل الرمز باستخدام 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
هذه الرسائل. ستلاحظ أنّ العناصر الرئيسية لجميع النطاقات التي تم إنشاؤها بواسطة loadgen تحتوي على TraceID: 00000000000000000000000000000000
، لأنّ هذا هو النطاق الجذر، أي النطاق الأول في التتبُّع. وتجد أيضًا أنّ سمة التضمين "query"
تحتوي على سلسلة طلب البحث التي يتم تمريرها إلى خدمة العملاء.
ملخّص
في هذه الخطوة، تمّ إعداد خدمة إنشاء الحمل وخدمة العميل اللتين تتواصلان باستخدام بروتوكول HTTP، وتم التأكّد من أنّه يمكنك نشر سياق التتبّع بنجاح على مستوى الخدمات وتصدير معلومات "وحدة التنفيذ" من كلتا الخدمتَين إلى stdout.
الخطوة التالية
في الخطوة التالية، ستُعدّ خدمة العميل وخدمة الخادم لتأكيد كيفية نشر سياق التتبّع عبر gRPC.
5- قياس حالة تطبيق gRPC
في الخطوة السابقة، جهزنا النصف الأول من الطلب في هذه الخدمات المصغرة. في هذه الخطوة، نحاول تجهيز اتصالات gRPC بين خدمة العميل وخدمة الخادم. (المستطيل الأخضر والأرجواني في الصورة أدناه)
أدوات القياس قبل الإنشاء لعميل gRPC
توفّر منظومة OpenTelemetry المتكاملة الكثير من المكتبات المفيدة التي تساعد المطوّرين في قياس أداء التطبيقات. في الخطوة السابقة، استخدمنا أدوات القياس قبل الإنشاء لحزمة net/http
. في هذه الخطوة، وبينما نحاول نشر سياق التتبّع من خلال 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 أولاً، تمامًا كما فعلنا مع loadgen وخدمات العميل.
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 هي التي أنشأتها.
ملخّص
في هذه الخطوة، تمّ إعداد أدوات للتواصل المستنِد إلى 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، لأنّك استبدلت أداة التصدير بأداة 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 في الصورة أعلاه) يمكنك تأكيد ذلك من جدول الملخّص. (يعرض العمود الأيمن إلى أقصى حد مدة كلّ نطاق). كان هذا التتبّع أيضًا لطلب البحث "صديق". (راجِع الرقم 2 في الصورة أعلاه)
استنادًا إلى هذه التحليلات الموجزة، قد تدرك أنّك بحاجة إلى معرفة فواصل أكثر دقة داخل طريقة GetMatchCount
. مقارنةً بمعلومات stdout، فإنّ أداة العروض المرئية فعّالة. للاطّلاع على مزيد من المعلومات عن تفاصيل Cloud Trace، يُرجى الانتقال إلى مستنداتنا الرسمية.
ملخّص
في هذه الخطوة، استبدلت أداة تصدير stdout بأداة Cloud Trace وعرضت عمليات التتبّع على 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؟ يمكنك الاطّلاع على التلميح هنا. - ربط سجلّات الأحداث بنطاقات الأداء والاطّلاع على كيفية عملها في "تتبُّع Google Cloud" و"تسجيل Google Cloud" يمكنك الاطّلاع على التلميح هنا.
- استبدِل بعض الخدمات بأخرى بلغة أخرى وحاول قياس أدائها باستخدام 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
بعد حذف المجموعة، اختَر "إدارة الهوية وإمكانية الوصول والمشرف" > "الإعدادات" من لوحة القائمة، ثم انقر على الزر "إيقاف".
بعد ذلك، أدخِل رقم تعريف المشروع (وليس اسم المشروع) في النموذج في مربّع الحوار وأكِّد إيقاف التشغيل.