Thông tin theo dõi công cụ bằng OpenTelemetry

1. Giới thiệu

5af4a7e43b0feaab.png

Lần cập nhật gần đây nhất: 2021-03-05

Khả năng ghi nhận của ứng dụng

Khả năng ghi nhận và OpenTelemetry

Khả năng ghi nhận là thuật ngữ dùng để mô tả một thuộc tính của hệ thống. Một hệ thống có khả năng quan sát cho phép các nhóm chủ động gỡ lỗi hệ thống của họ. Trong bối cảnh đó, 3 trụ cột của khả năng ghi nhận (nhật ký, chỉ số và dấu vết) là khả năng đo lường cơ bản để hệ thống có được khả năng ghi nhận.

OpenTelemetry là một tập hợp các quy cách và SDK giúp tăng tốc quá trình đo lường và xuất dữ liệu đo từ xa (nhật ký, chỉ số và dấu vết) mà khả năng quan sát yêu cầu. OpenTelemetry là một tiêu chuẩn mở và dự án do cộng đồng điều hành thuộc CNCF. Bằng cách sử dụng các thư viện mà dự án và hệ sinh thái của dự án cung cấp, nhà phát triển có thể đo lường các ứng dụng của họ theo cách trung lập với nhà cung cấp và dựa trên nhiều cấu trúc.

Distributed Trace

Trong số nhật ký, chỉ số và dấu vết, dấu vết là dữ liệu đo từ xa cho biết độ trễ của một phần cụ thể trong quy trình của hệ thống. Đặc biệt là trong kỷ nguyên của các vi dịch vụ, dấu vết phân tán là yếu tố thúc đẩy mạnh mẽ việc tìm ra các điểm nghẽn về độ trễ trong hệ thống phân tán tổng thể.

Khi phân tích các dấu vết phân tán, hình ảnh hoá dữ liệu dấu vết là chìa khoá để nắm bắt độ trễ tổng thể của hệ thống trong nháy mắt. Trong dấu vết phân tán, chúng ta xử lý một tập hợp các lệnh gọi để xử lý một yêu cầu duy nhất đến điểm truy cập hệ thống dưới dạng Dấu vết chứa nhiều Khoảng thời gian.

Khoảng thời gian biểu thị một đơn vị công việc riêng lẻ được thực hiện trong một hệ thống phân tán, ghi lại thời gian bắt đầu và kết thúc. Các khoảng thời gian thường có mối quan hệ phân cấp với nhau – trong hình bên dưới, tất cả các khoảng thời gian nhỏ hơn đều là khoảng thời gian con của một khoảng thời gian lớn /tin nhắn và được hợp nhất thành một Dấu vết cho thấy đường dẫn công việc thông qua một hệ thống.

adbd3ecd69d410cb.png

Google Cloud Trace là một trong những lựa chọn cho phần phụ trợ theo dõi phân tán và được tích hợp tốt với các sản phẩm khác trong Google Cloud.

Sản phẩm bạn sẽ tạo ra

Trong lớp học lập trình này, bạn sẽ đo thông tin theo dõi trong các dịch vụ có tên là "Shakesapp" chạy trên một cụm Kubernetes chạy trên Google Kubernetes Engine. Kiến trúc của Shakesapp như mô tả bên dưới:

68873c018a7be7de.png

  • Máy khách gửi một chuỗi truy vấn đến máy chủ
  • Máy chủ chấp nhận truy vấn từ máy khách, tìm nạp tất cả các tác phẩm của Shakespeare ở định dạng văn bản từ Google Cloud Storage, tìm kiếm những dòng có chứa truy vấn và trả về số dòng khớp với máy khách.

Bạn sẽ đo lường thông tin theo dõi trên toàn bộ yêu cầu.

Kiến thức bạn sẽ học được

  • Cách bắt đầu sử dụng các thư viện Dấu vết OpenTelemetry trong dự án Python
  • Cách tạo một khoảng bằng thư viện
  • Cách truyền ngữ cảnh khoảng thời gian qua đường truyền giữa các thành phần ứng dụng
  • Cách gửi dữ liệu theo dõi đến Google Cloud Trace
  • Cách phân tích dấu vết trên Google Cloud Trace

Lớp học lập trình này giải thích cách đo lường các vi dịch vụ của bạn. Để dễ hiểu, ví dụ này chỉ chứa 3 thành phần (trình tạo tải, máy khách và máy chủ), nhưng bạn có thể áp dụng quy trình tương tự được giải thích trong lớp học lập trình này cho các hệ thống phức tạp và lớn hơn.

Bạn cần có

  • Kiến thức về Python 3

2. Thiết lập và yêu cầu

Thiết lập môi trường theo tốc độ của riêng bạn

Nếu chưa có Tài khoản Google (Gmail hoặc Google Apps), bạn phải tạo một tài khoản. Đăng nhập vào bảng điều khiển Google Cloud Platform ( console.cloud.google.com) rồi tạo một dự án mới.

Nếu bạn đã có dự án, hãy nhấp vào trình đơn thả xuống chọn dự án ở phía trên bên trái của bảng điều khiển:

15b8b6ac4d917005.png

rồi nhấp vào nút "DỰ ÁN MỚI" trong hộp thoại xuất hiện để tạo một dự án mới:

7136b3ee36ebaf89.png

Nếu chưa có dự án, bạn sẽ thấy một hộp thoại như thế này để tạo dự án đầu tiên:

90977ce514204b51.png

Hộp thoại tạo dự án tiếp theo cho phép bạn nhập thông tin chi tiết về dự án mới:

6d9573e346e930b4.png

Hãy nhớ mã dự án. Đây là tên duy nhất trên tất cả các dự án Google Cloud (tên ở trên đã được sử dụng và sẽ không hoạt động đối với bạn, xin lỗi!). Sau này trong lớp học lập trình này, chúng ta sẽ gọi đó là PROJECT_ID.

Tiếp theo, nếu chưa làm, bạn cần phải bật tính năng thanh toán trong Play Console để sử dụng các tài nguyên của Google Cloud và bật Cloud Trace API.

eb5325f65619ad6a.png

Việc thực hiện lớp học lập trình này sẽ không tốn của bạn quá vài đô la, nhưng có thể tốn nhiều hơn nếu bạn quyết định sử dụng nhiều tài nguyên hơn hoặc nếu bạn để các tài nguyên đó chạy (xem phần "dọn dẹp" ở cuối tài liệu này). Giá của Google Cloud Trace, Google Kubernetes Engine và Google Artifacat Registry được ghi trong tài liệu chính thức.

Người dùng mới của Google Cloud Platform đủ điều kiện dùng thử miễn phí trị giá 300 USD. Nhờ đó, bạn có thể hoàn toàn miễn phí tham gia lớp học lập trình này.

Thiết lập Google Cloud Shell

Mặc dù bạn có thể vận hành Google Cloud và Google Cloud Trace từ xa trên máy tính xách tay, nhưng trong lớp học lập trình này, chúng ta sẽ sử dụng Google Cloud Shell, một môi trường dòng lệnh chạy trên đám mây.

Máy ảo dựa trên Debian này được trang bị tất cả các công cụ phát triển mà bạn cần. Nền tảng này cung cấp một thư mục chính có dung lượng 5 GB và chạy trong Google Cloud, giúp tăng cường đáng kể hiệu suất mạng và hoạt động xác thực. Điều này có nghĩa là bạn chỉ cần một trình duyệt (có, trình duyệt này hoạt động trên Chromebook) cho lớp học lập trình này.

Để kích hoạt Cloud Shell từ Bảng điều khiển Cloud, bạn chỉ cần nhấp vào biểu tượng Kích hoạt Cloud Shell gcLMt5IuEcJJNnMId-Bcz3sxCd0rZn7IzT_r95C8UZeqML68Y1efBG_B0VRp7hc7qiZTLAF-TXD7SsOadxn8uadgHhaLeASnVS3ZHK39eOlKJOgj9SJua_oeGhMxRrbOg3qigddS2A (mất vài phút để cung cấp và kết nối với môi trường).

ff81d016724c4f67.png

fbe156ee6edfbb2e.png

Sau khi kết nối với Cloud Shell, bạn sẽ thấy rằng mình đã được xác thực và dự án đã được đặt thành PROJECT_ID.

gcloud auth list

Đầu ra của lệnh

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

Đầu ra của lệnh

[core]
project = <PROJECT_ID>

Nếu vì lý do nào đó mà dự án chưa được thiết lập, bạn chỉ cần đưa ra lệnh sau:

gcloud config set project <PROJECT_ID>

Bạn đang tìm PROJECT_ID? Kiểm tra mã nhận dạng bạn đã dùng trong các bước thiết lập hoặc tìm mã nhận dạng đó trong trang tổng quan của Cloud Console:

a3e716fc9e7454e9.png

Cloud Shell cũng đặt một số biến môi trường theo mặc định, có thể hữu ích khi bạn chạy các lệnh trong tương lai.

echo $GOOGLE_CLOUD_PROJECT

Đầu ra của lệnh

<PROJECT_ID>

Cuối cùng, hãy đặt cấu hình dự án và vùng mặc định.

gcloud config set compute/zone us-central1-f

Bạn có thể chọn nhiều múi giờ khác nhau. Để biết thêm thông tin, hãy xem phần Khu vực và vùng.

Thiết lập Python

Trong lớp học lập trình này, chúng ta sử dụng "poetry" để quản lý các phiên bản gói một cách nghiêm ngặt. Chạy lệnh sau trên Cloud Shell:

curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python3 -
source $HOME/.poetry/env

Thiết lập một Cụm Kubernetes của Google

Trong lớp học lập trình này, bạn sẽ chạy một cụm vi dịch vụ trên Google Kubernetes Engine (GKE). Quy trình của lớp học lập trình này như sau:

  1. Tải dự án cơ sở xuống Cloud Shell
  2. Tạo các vi dịch vụ vào vùng chứa
  3. Tải vùng chứa lên Google Artifact Registry (GAR)
  4. Triển khai vùng chứa trên GKE
  5. Sửa đổi mã nguồn của các dịch vụ để theo dõi khả năng đo lường
  6. Chuyển đến bước 2

Bật Kubernetes Engine

Trước tiên, chúng ta thiết lập một cụm Kubernetes nơi Shakesapp chạy trên GKE, vì vậy, chúng ta cần bật GKE. Chuyển đến trình đơn "Kubernetes Engine" rồi nhấn nút BẬT.

56c680e93e169731.png

Bây giờ, bạn đã sẵn sàng tạo một cụm Kubernetes.

Tạo cụm Kubernetes

Trên Cloud Shell, hãy chạy lệnh sau để tạo một cụm Kubernetes. Vui lòng xác nhận giá trị của vùng nằm trong khu vực mà bạn đã dùng để tạo kho lưu trữ Artifact Registry. Thay đổi giá trị khu vực us-central1-f nếu khu vực kho lưu trữ của bạn không bao gồm khu vực đó.

gcloud container clusters create otel-trace-codelab --zone us-central1-f \
--num-nodes 1 \
--machine-type e2-highcpu-4

Đầu ra của lệnh

Creating cluster otel-trace-codelab in us-central1-f... Cluster is being health-checked (master is healthy)...done.
Created [https://container.googleapis.com/v1/projects/psychic-order-307806/zones/us-central1-f/clusters/otel-trace-codelab].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1-f/otel-trace-codelab?project=psychic-order-307806
kubeconfig entry generated for otel-trace-codelab.
NAME                LOCATION       MASTER_VERSION    MASTER_IP        MACHINE_TYPE  NODE_VERSION      NUM_NODES  STATUS
otel-trace-codelab  us-central1-f  1.18.12-gke.1210  104.154.162.176  e2-medium     1.18.12-gke.1210  3          RUNNING

Thiết lập Artifact Registry và Skaffold

Giờ đây, chúng ta đã có một cụm Kubernetes sẵn sàng triển khai. Tiếp theo, chúng ta chuẩn bị cho một sổ đăng ký vùng chứa để đẩy và triển khai vùng chứa. Đối với các bước này, chúng ta cần thiết lập GAR và skaffold để sử dụng.

Thiết lập Artifact Registry

Chuyển đến trình đơn "Artifact Registry" rồi nhấn vào nút BẬT.

f7493243bae0cdf7.png

Sau vài phút, bạn sẽ thấy trình duyệt kho lưu trữ của GAR. Nhấp vào nút "TẠO KHO LƯU TRỮ" rồi nhập tên của kho lưu trữ.

f97f337f5476651.png

Trong lớp học lập trình này, tôi đặt tên cho kho lưu trữ mới là trace-codelab. Định dạng của cấu phần phần mềm là "Docker" và loại vị trí là "Khu vực". Chọn khu vực gần với khu vực bạn đặt cho vùng mặc định của Google Compute Engine. Ví dụ: ví dụ này chọn "us-central1-f" ở trên, vì vậy ở đây chúng ta chọn "us-central1 (Iowa)". Sau đó, hãy nhấp vào nút "TẠO".

2f04143077ca56db.png

Giờ đây, bạn sẽ thấy "trace-codelab" trên trình duyệt kho lưu trữ.

7a3c1f47346bea15.png

Chúng ta sẽ quay lại đây sau để kiểm tra đường dẫn sổ đăng ký.

Thiết lập Skaffold

Skaffold là một công cụ hữu ích khi bạn làm việc trên việc tạo các dịch vụ vi mô chạy trên Kubernetes. Công cụ này xử lý quy trình tạo, đẩy và triển khai các vùng chứa ứng dụng bằng một số ít lệnh. Theo mặc định, Skaffold sử dụng Docker Registry làm sổ đăng ký vùng chứa, vì vậy, bạn cần định cấu hình Skaffold để nhận dạng GAR khi đẩy vùng chứa đến.

Mở lại Cloud Shell và xác nhận xem skaffold đã được cài đặt hay chưa. (Theo mặc định, Cloud Shell sẽ cài đặt skaffold vào môi trường.) Chạy lệnh sau và xem phiên bản skaffold.

skaffold version

Đầu ra của lệnh

v1.20.0

Giờ đây, bạn có thể đăng ký kho lưu trữ mặc định để skaffold sử dụng. Để lấy đường dẫn đăng ký, hãy chuyển đến trang tổng quan Artifact Registry rồi nhấp vào tên kho lưu trữ mà bạn vừa thiết lập ở bước trước.

55173fe922f40327.png

Sau đó, bạn sẽ thấy đường dẫn breadcrumb ở đầu trang. Nhấp vào biểu tượng e157b1359c3edc06.png để sao chép đường dẫn đăng ký vào bảng nhớ tạm.

a9b0fa44c37e0178.png

Khi nhấp vào nút sao chép, bạn sẽ thấy hộp thoại ở cuối trình duyệt có thông báo như sau:

Đã sao chép "us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab"

Quay lại Cloud Shell. Chạy lệnh skaffold config set default-repo bằng giá trị mà bạn vừa sao chép từ trang tổng quan.

skaffold config set default-repo us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab

Đầu ra của lệnh

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

Ngoài ra, bạn cần định cấu hình sổ đăng ký cho cấu hình Docker. Chạy lệnh sau:

gcloud auth configure-docker us-central1-docker.pkg.dev --quiet

Đầu ra của lệnh

{
  "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

Giờ đây, bạn đã sẵn sàng chuyển sang bước tiếp theo để thiết lập một vùng chứa Kubernetes trên GKE.

Tóm tắt

Ở bước này, bạn sẽ thiết lập môi trường lớp học lập trình:

  • Thiết lập Cloud Shell
  • Đã tạo một kho lưu trữ Artifact Registry cho sổ đăng ký vùng chứa
  • Thiết lập skaffold để sử dụng sổ đăng ký vùng chứa
  • Tạo một cụm Kubernetes nơi các vi dịch vụ của lớp học lập trình chạy

Tiếp theo

Trong bước tiếp theo, bạn sẽ tạo, đẩy và triển khai các vi dịch vụ của mình lên cụm

3. Tạo, chuyển và triển khai các vi dịch vụ

Tải tài liệu của lớp học lập trình xuống

Ở bước trước, chúng ta đã thiết lập tất cả các điều kiện tiên quyết cho lớp học lập trình này. Giờ đây, bạn đã sẵn sàng chạy toàn bộ các vi dịch vụ trên các vùng này. Tài liệu của lớp học lập trình được lưu trữ trên GitHub, vì vậy, hãy tải tài liệu xuống môi trường Cloud Shell bằng lệnh git sau.

cd ~
git clone https://github.com/GoogleCloudPlatform/opentelemetry-trace-codelab-python.git

Cấu trúc thư mục của dự án như sau:

shakesapp-python
├── LICENSE
├── manifests
│   ├── client.yaml
│   ├── loadgen.yaml
│   └── server.yaml
├── proto
│   └── shakesapp.proto
├── skaffold.yaml
└── src
    ├── client
    ├── loadgen
    └── server
  • manifests: Tệp kê khai Kubernetes
  • proto: định nghĩa proto cho hoạt động giao tiếp giữa ứng dụng và máy chủ
  • src: thư mục cho mã nguồn của từng dịch vụ
  • skaffold.yaml: Tệp cấu hình cho skaffold

Chạy lệnh skaffold

Cuối cùng, bạn đã sẵn sàng tạo, truyền và triển khai toàn bộ nội dung lên cụm Kubernetes mà bạn vừa tạo. Nghe có vẻ có nhiều bước, nhưng thực tế là Skaffold sẽ làm mọi thứ cho bạn. Hãy thử làm việc đó bằng lệnh sau:

cd shakesapp-python
skaffold run --tail

Ngay sau khi chạy lệnh, bạn sẽ thấy thông tin xuất trong nhật ký của docker build và có thể xác nhận rằng các thông tin này đã được chuyển thành công vào sổ đăng ký.

Đầu ra của lệnh

...
---> 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

Sau khi đẩy tất cả các vùng chứa dịch vụ, quá trình triển khai Kubernetes sẽ tự động bắt đầu.

Đầu ra của lệnh

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

Thận trọng: Nếu bạn gặp lỗi như "No push access to specified image repository" (Không có quyền đẩy vào kho lưu trữ hình ảnh đã chỉ định), hãy kiểm tra xem lệnh skaffold có đang cố gắng đẩy hình ảnh lên Docker Hub (docker.io) hay không, bất kể cấu hình của bạn trên kho lưu trữ mặc định trong skaffold. Trong trường hợp đó, hãy thử thêm lựa chọn "–default-repo" vào "skaffold run" như bên dưới.

$ skaffold run –tail –default-repo=us-central1-docker.pkg.dev/[project ID]/[repository name]

Sau khi triển khai, bạn sẽ thấy nhật ký ứng dụng thực tế được phát ra stdout trong mỗi vùng chứa như sau:

Đầu ra của lệnh

[server] {"event": "starting server: 0.0.0.0:5050", "severity": "info", "timestamp": "2021-03-17T05:25:56.758575Z"}
[client] [2021-03-17 05:25:54 +0000] [1] [INFO] Starting gunicorn 20.0.4
[client] [2021-03-17 05:25:54 +0000] [1] [INFO] Listening at: http://0.0.0.0:8080 (1)
[client] [2021-03-17 05:25:54 +0000] [1] [INFO] Using worker: threads
[client] [2021-03-17 05:25:54 +0000] [7] [INFO] Booting worker with pid: 7
[client] {"event": "server address is serverservice:5050", "severity": "info", "timestamp": "2021-03-17T05:25:54.888627Z"}
[client] {"event": "request to server with query: world", "severity": "info", "timestamp": "2021-03-17T05:26:11.550923Z"}
[server] {"event": "query: world", "severity": "info", "timestamp": "2021-03-17T05:26:11.567048Z"}
[loadgen] {"event": "check connectivity: http://clientservice:8080/_healthz", "severity": "info", "timestamp": "2021-03-17T05:26:11.533605Z"}
[loadgen] {"event": "/_healthz response: ok", "severity": "info", "timestamp": "2021-03-17T05:26:11.544267Z"}
[loadgen] {"event": "confirmed connection ot clientservice", "severity": "info", "timestamp": "2021-03-17T05:26:11.544527Z"}

Cuối cùng, bạn đã sẵn sàng bắt đầu đo lường ứng dụng của mình bằng OpenTelemetry để theo dõi phân tán các dịch vụ.

Tóm tắt

Ở bước này, bạn đã chuẩn bị tài liệu của lớp học lập trình trong môi trường của mình và xác nhận rằng skaffold chạy như mong đợi.

Tiếp theo

Trong bước tiếp theo, bạn sẽ sửa đổi mã nguồn của dịch vụ loadgen để đo lường thông tin theo dõi.

4. Khả năng đo lường cho HTTP

Khái niệm về tính năng đo lường và truyền dấu vết

Trước khi chỉnh sửa mã nguồn, tôi sẽ giải thích ngắn gọn cách hoạt động của tính năng dấu vết phân tán trong một sơ đồ đơn giản.

c8c659deaa9c9091.png

Trong ví dụ này, chúng ta sẽ đo lường mã để xuất thông tin về Dấu vết và Khoảng thời gian sang Cloud Trace, đồng thời truyền bối cảnh dấu vết trên yêu cầu từ dịch vụ loadgen đến dịch vụ máy chủ.

Ứng dụng cần gửi siêu dữ liệu Dấu vết (chẳng hạn như Mã dấu vết và Mã khoảng thời gian) trong Cloud Trace để tập hợp tất cả các khoảng thời gian có cùng Mã dấu vết thành một dấu vết. Ngoài ra, ứng dụng cần truyền các bối cảnh theo dõi (sự kết hợp giữa Mã theo dõi và Mã khoảng thời gian của khoảng thời gian mẹ) khi yêu cầu các dịch vụ hạ nguồn, để các dịch vụ này có thể biết được bối cảnh theo dõi mà chúng đang xử lý.

OpenTelemetry giúp bạn:

  • để tạo Trace ID và Span ID riêng biệt
  • để xuất Mã theo dõi và Mã khoảng thời gian sang phần phụ trợ
  • để truyền bối cảnh theo dõi đến các dịch vụ khác

Đo khoảng thời gian đầu tiên

Dịch vụ trình tạo tải công cụ

Mở Cloud Shell Editor bằng cách nhấn vào nút 776a11bfb2122549.png ở trên cùng bên phải của Cloud Shell. Mở src/loadgen/loadgen.py trong trình khám phá ở ngăn bên trái và tìm hàm main.

src/loadgen/loadgen.py

def main():
    ...
    # start request loop to client service
    logger.info("start client request loop")
    addr = f"http://{target}"
    while True:
        logger.info("start request to client")
        call_client(addr)
        logger.info("end request to client")
        time.sleep(2.0)

Trong hàm main, bạn sẽ thấy vòng lặp gọi hàm call_client trong đó. Trong quá trình triển khai hiện tại, phần này có 2 dòng nhật ký ghi lại thời điểm bắt đầu và kết thúc lệnh gọi hàm. Giờ hãy đo lường thông tin về khoảng thời gian để theo dõi độ trễ của lệnh gọi hàm.

Trước tiên, bạn cần tạo một khoảng thời gian có Mã theo dõi và Mã khoảng thời gian riêng biệt. OpenTelemetry cung cấp thư viện tiện dụng cho việc này. Thêm các dòng sau để nhập thư viện OpenTelemetry vào mã của bạn.

 import structlog
+from opentelemetry import propagate, trace
+from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
+from opentelemetry.sdk.trace import TracerProvider
+from opentelemetry.instrumentation.requests import RequestsInstrumentor
+from opentelemetry.sdk.trace.export import SimpleSpanProcessor
+from opentelemetry.propagators.cloud_trace_propagator import CloudTraceFormatPropagator

Vì trình tạo tải đang gọi ứng dụng khách trong HTTP thông qua mô-đun requests, nên chúng tôi sử dụng gói tiện ích cho requests và bật tính năng đo lường.

 from opentelemetry.propagators.cloud_trace_propagator import CloudTraceFormatPropagator
+
+RequestsInstrumentor().instrument()

Sau đó, hãy thiết lập phiên bản Trình theo dõi xử lý Trace Context và chế độ cài đặt trình xuất

     target = os.environ.get("CLIENT_ADDR", "0.0.0.0:8080")

+    exporter = CloudTraceSpanExporter()
+    trace.get_tracer_provider().add_span_processor(SimpleSpanProcessor(exporter))
+    tracer = trace.get_tracer(__name__)
+    propagate.set_global_textmap(CloudTraceFormatPropagator())
+    trace.set_tracer_provider(TracerProvider())
+
     # connectivity check to client service
     healthz = f"http://{target}/_healthz"
     logger.info(f"check connectivity: {healthz}")

Xin lưu ý rằng vì đây là một lớp học lập trình để tìm hiểu cách hoạt động của tính năng đo lường dấu vết, nên chúng ta sẽ định cấu hình Tracer để ghi lại từng yêu cầu và gửi chúng đến phần phụ trợ. (SimpleSpanProcessor()) Điều này không phù hợp với môi trường phát hành chính thức, vì vậy, hãy nhớ thay đổi phần này khi bạn đo lường ứng dụng phát hành chính thức của mình.

Giờ đây, bạn có thể đo lường các khoảng thời gian bằng Tracer. Vấn đề ở đây là bạn cần tạo một Span một cách rõ ràng, và thế là xong! Mặc dù có 2 dòng thêm siêu dữ liệu sự kiện vào Khoảng thời gian, nhưng bạn không cần tạo Mã theo dõi và Mã khoảng thời gian duy nhất theo cách thủ công rồi nhúng chúng vào Khoảng thời gian.

     logger.info("start client request loop")
     addr = f"http://{target}"
     while True:
-        logger.info("start request to client")
-        call_client(addr)
-        logger.info("end request to client")
+        with tracer.start_as_current_span("loadgen") as root_span:
+            root_span.add_event(name="request_start")
+            logger.info("start request to client")
+            call_client(addr)
+            root_span.add_event(name="request_end")
+            logger.info("end request to client")
         time.sleep(2.0)

Để Docker build tìm nạp các gói OpenTelemetry cần thiết, hãy chạy lệnh sau:

poetry add "opentelemetry-exporter-gcp-trace=^1.0.0rc0"
poetry add "opentelemetry-propagator-gcp=^1.0.0rc0"
poetry add "opentelemetry-instrumentation-requests=^0.20b0"

Bạn có thể xác nhận rằng nội dung mô tả phần phụ thuộc tương ứng được viết trong pyproject.toml.

Dịch vụ khách hàng của nhạc cụ

Trong phần trước, chúng ta đã đo lường phần nằm trong hình chữ nhật màu đỏ trong bản vẽ bên dưới. Chúng tôi đã đo lường thông tin khoảng thời gian trong dịch vụ trình tạo tải. Tương tự như dịch vụ trình tạo tải, giờ đây, chúng ta cần đo lường dịch vụ ứng dụng. Điểm khác biệt so với dịch vụ trình tạo tải là dịch vụ ứng dụng cần trích xuất thông tin Mã theo dõi được truyền từ dịch vụ trình tạo tải trong tiêu đề HTTP và sử dụng mã nhận dạng này để tạo các khoảng thời gian.

ae074d4513c9931f.png

Mở Cloud Shell Editor và thêm các mô-đun cần thiết như cách chúng ta đã làm cho dịch vụ trình tạo tải.

src/client/client.py

 import flask
 import grpc
 import structlog
+from opentelemetry import propagate, trace
+from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
+from opentelemetry.instrumentation.flask import FlaskInstrumentor
+from opentelemetry.sdk.trace import TracerProvider
+from opentelemetry.sdk.trace.export import SimpleSpanProcessor
+from opentelemetry.propagators.cloud_trace_propagator import \
+    CloudTraceFormatPropagator

 import shakesapp_pb2
 import shakesapp_pb2_grpc

Bạn nhận thấy rằng bạn vừa nhập FlaskInstrumentor cho phép khả năng đo lường tự động cho ứng dụng Flask thay cho người dùng để trích xuất tiêu đề HTTP nhằm lấy Ngữ cảnh theo dõi chỉ bằng một dòng mã. Cộng đồng OpenTelemetry cung cấp các hoạt động tích hợp hữu ích tương tự với các thư viện chính khác. Để biết thêm thông tin, bạn có thể tham khảo tài liệu chính thức.

 app = flask.Flask(__name__)
+FlaskInstrumentor().instrument_app(app)

Trước khi bắt đầu khả năng đo lường, bạn cần chuẩn bị phiên bản Tracer tương tự như những gì chúng ta đã làm trong dịch vụ trình tạo tải.

 logger.info(f"server address is {SERVER_ADDR}")

+exporter = CloudTraceSpanExporter()
+trace.get_tracer_provider().add_span_processor(SimpleSpanProcessor(exporter))
+propagate.set_global_textmap(CloudTraceFormatPropagator())
+trace.set_tracer_provider(TracerProvider())

 @app.route("/")
 def main_handler():
    ....

Giờ đây, bạn đã có thể thêm khả năng đo lường vào trình xử lý. Tìm main_handler() và sửa đổi phần gửi yêu cầu gRPC đến dịch vụ máy chủ.

@app.route("/")
def main_handler():
    q, count = random.choice(list(queries.items()))

    # get Tracer
    tracer = trace.get_tracer(__name__)

    with tracer.start_as_current_span("client") as cur_span:
        channel = grpc.insecure_channel(SERVER_ADDR)
        stub = shakesapp_pb2_grpc.ShakespeareServiceStub(channel)
        logger.info(f"request to server with query: {q}")
        cur_span.add_event("server_call_start")
        resp = stub.GetMatchCount(shakesapp_pb2.ShakespeareRequest(query=q))
        cur_span.add_event("server_call_end")
        if count != resp.match_count:
            raise UnexpectedResultError(
                f"The expected count for '{q}' was {count}, but result was {resp.match_count } obtained"
            )
        result = str(resp.match_count)
        logger.info(f"matched count for '{q}' is {result}")
    return result

Tương tự như dịch vụ trình tạo tải, hãy thêm các gói bắt buộc vào pyproject.toml bằng lệnh sau.

poetry add "opentelemetry-exporter-gcp-trace=^1.0.0rc0"
poetry add "opentelemetry-propagator-gcp=^1.0.0rc0"
poetry add "opentelemetry-instrumentation-flask=^0.20b0"

Sau đó, hãy thử chạy ứng dụng bằng lệnh skaffold run và xem trang tổng quan Cloud Trace hiển thị những gì:

skaffold run --tail

Sau khi thấy một số thông báo về bản dựng, lệnh đẩy và triển khai, bạn sẽ thấy nhật ký ứng dụng ở định dạng JSON. Chuyển đến Cloud Trace > Danh sách dấu vết để kiểm tra xem bạn có nhận được thông tin dấu vết hay không. Vì dịch vụ trình tạo tải gửi yêu cầu đến dịch vụ máy khách theo định kỳ và bạn đã bật tính năng theo dõi cho tất cả các yêu cầu, nên bạn sẽ thấy rất nhiều dấu chấm trên danh sách theo dõi.

f7440360551980e.png

Khi nhấp vào một trong các chỉ số đó, bạn sẽ thấy một biểu đồ dạng thác nước như bên dưới. Biểu đồ này giải thích độ trễ của từng phần trong quá trình yêu cầu và phản hồi. Tìm hộp đánh dấu bên cạnh mục "Hiện sự kiện", sau đó bạn sẽ thấy chú thích trong biểu đồ thác nước. Đây là những chú giải mà bạn đã đo lường trong mã bằng phương thức span.add_event().

67596a4a313738.png

Bạn có thể nhận thấy rằng bạn không thấy các khoảng thời gian từ dịch vụ máy chủ. Điều này là chính xác vì chúng ta chưa từng đo lường các khoảng thời gian trong dịch vụ máy chủ.

Tóm tắt

Trong bước này, bạn đã thiết lập dịch vụ trình tạo tải và dịch vụ khách hàng, đồng thời xác nhận rằng bạn có thể truyền thành công Ngữ cảnh theo dõi trên các dịch vụ và xuất thông tin về khoảng thời gian từ cả hai dịch vụ sang Cloud Trace.

Tiếp theo

Ở bước tiếp theo, bạn sẽ đo lường dịch vụ máy khách và dịch vụ máy chủ để xác nhận cách truyền Ngữ cảnh theo dõi thông qua gRPC.

5. Khả năng đo lường cho gRPC

Ở bước trước, chúng ta đã đo lường nửa đầu của yêu cầu trong các vi dịch vụ này. Trong bước này, chúng ta sẽ cố gắng đo lường giao tiếp gRPC giữa dịch vụ ứng dụng và dịch vụ máy chủ. (Hình chữ nhật màu xanh lục và màu tím trong hình bên dưới)

c4dec3e741c3ab4f.png

Khả năng đo lường tự động cho ứng dụng gRPC

Hệ sinh thái của OpenTelemetry cung cấp nhiều thư viện hữu ích giúp nhà phát triển đo lường các ứng dụng. Ở bước trước, chúng ta đã sử dụng tính năng đo lường tự động cho mô-đun "requests". Trong bước này, vì đang cố gắng truyền Ngữ cảnh theo dõi thông qua gRPC, nên chúng ta sẽ sử dụng thư viện cho việc này.

src/client/client.py

 import flask
 import grpc
 import structlog
 from opentelemetry import propagate, trace
 from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
 from opentelemetry.instrumentation.flask import FlaskInstrumentor
+from opentelemetry.instrumentation.grpc import GrpcInstrumentorClient
 from opentelemetry.sdk.trace import TracerProvider
 from opentelemetry.sdk.trace.export import SimpleSpanProcessor
 from opentelemetry.propagators.cloud_trace_propagator import \
     CloudTraceFormatPropagator
 import shakesapp_pb2
 import shakesapp_pb2_grpc


 app = flask.Flask(__name__)
 FlaskInstrumentor().instrument_app(app)
+GrpcInstrumentorClient().instrument()

Đối với dịch vụ khách hàng, những gì chúng ta cần làm cho khả năng đo lường là khá nhỏ. Chúng ta muốn truyền Ngữ cảnh theo dõi, là sự kết hợp giữa Mã theo dõi và Mã khoảng thời gian của Khoảng thời gian hiện tại thông qua gRPC. Vì vậy, chúng ta gọi GrpcInstrumentatorClient.instrument() để ứng dụng gRPC trong hàm trình xử lý có thể nhúng Ngữ cảnh theo dõi vào tiêu đề HTTP bên dưới.

Hãy nhớ thêm các phần phụ thuộc mới vào pyproject.toml bằng lệnh poetry add:

poetry add "opentelemetry-instrumentation-grpc=^0.20b0"

Khả năng đo lường tự động cho máy chủ gRPC

Giống như những gì chúng ta đã làm cho ứng dụng gRPC, chúng ta gọi tính năng đo lường tự động cho máy chủ gRPC. Thêm các lệnh nhập như sau và gọi GrpcInstrumentationServer().instrument() ở đầu tệp.

Thận trọng: Nhớ gọi

GrpcInstrumentationServe() 

trong bước này, không

GrpcInstrumentationClient()

.

src/server/server.py

 import grpc
 import structlog
 from google.cloud import storage
 from grpc_health.v1 import health_pb2, health_pb2_grpc
+from opentelemetry import propagate, trace
+from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
+from opentelemetry.instrumentation.grpc import GrpcInstrumentorServer
+from opentelemetry.sdk.trace import TracerProvider
+from opentelemetry.sdk.trace.export import SimpleSpanProcessor
+from opentelemetry.propagators.cloud_trace_propagator import CloudTraceFormatPropagator

 import shakesapp_pb2
 import shakesapp_pb2_grpc


 BUCKET_NAME = "dataflow-samples"
 BUCKET_PREFIX = "shakespeare/"

+# enable auto gRPC server trace instrumentation
+GrpcInstrumentorServer().instrument()
+

Tiếp theo, bạn sẽ thêm trình xuất để gửi thông tin theo dõi đến phần phụ trợ Cloud Trace. Thêm mã sau vào hàm serve().

def serve():
+    # start trace exporter
+    trace.set_tracer_provider(TracerProvider())
+    trace.get_tracer_provider().add_span_processor(
+        SimpleSpanProcessor(CloudTraceSpanExporter())
+    )
+    propagators.set_global_textmap(CloudTraceFormatPropagator())
+
+    # add gRPC services to server
     server = grpc.server(futures.ThreadPoolExecutor(max_workers=4))
     service = ShakesappService()
     shakesapp_pb2_grpc.add_ShakespeareServiceServicer_to_server(service, server)
     health_pb2_grpc.add_HealthServicer_to_server(service, server)

Đảm bảo thêm các gói mới vào dịch vụ máy chủ.

poetry add "opentelemetry-exporter-gcp-trace=^1.0.0rc0"
poetry add "opentelemetry-instrumentation-grpc=^0.20b0"
poetry add "opentelemetry-propagator-gcp=^1.0.0rc0"
poetry add "opentelemetry-instrumentation=^0.20b0"

Chạy vi dịch vụ và xác nhận dấu vết

Sau đó, hãy chạy mã đã sửa đổi bằng lệnh skaffold.

skaffold run --tail

Giờ đây, bạn sẽ thấy một loạt dấu vết trên trang Danh sách dấu vết của Cloud Trace. Nhấp vào một trong các dấu vết và giờ đây, bạn sẽ thấy các khoảng thời gian trên yêu cầu từ dịch vụ trình tạo tải đến dịch vụ máy chủ.

141cb620245b689d.png

Tóm tắt

Trong bước này, bạn đã đo lường hoạt động giao tiếp dựa trên gRPC với sự hỗ trợ của các thư viện hệ sinh thái OpenTelemetry. Ngoài ra, bạn xác nhận rằng Ngữ cảnh theo dõi được tạo trong dịch vụ trình tạo tải đã được gửi thành công đến dịch vụ máy chủ.

6. Xin chúc mừng

Bạn đã tạo thành công các dấu vết phân tán bằng OpenTelemetry và xác nhận độ trễ của yêu cầu trên các vi dịch vụ trên Google Cloud Trace.

Đối với các bài tập mở rộng, bạn có thể tự mình thử các chủ đề sau.

  • Quá trình triển khai hiện tại sẽ gửi tất cả các khoảng thời gian do quy trình kiểm tra tình trạng tạo ra. Làm cách nào để lọc những khoảng thời gian đó khỏi Cloud Trace? Gợi ý tại đây.
  • Tương quan nhật ký sự kiện với khoảng thời gian và xem cách hoạt động của nhật ký trên Google Cloud Trace và Google Cloud Logging. Gợi ý tại đây.
  • Thay thế một số dịch vụ bằng dịch vụ bằng ngôn ngữ khác và thử đo lường bằng OpenTelemetry cho ngôn ngữ đó

Thận trọng: Google Kubernetes Engine và Google Artifact Registry liên tục sử dụng tài nguyên.

Dọn dẹp

Sau khi hoàn thành lớp học lập trình này, vui lòng dừng cụm Kubernetes và nhớ xoá dự án để bạn không bị tính phí ngoài dự kiến trên Google Kubernetes Engine, Google Cloud Trace, Google Artifact Registry.

Trước tiên, hãy xoá cụm bằng lệnh sau:

skaffold delete

Đầu ra của lệnh

Cleaning up...
 - deployment.apps "clientservice" deleted
 - service "clientservice" deleted
 - deployment.apps "loadgen" deleted
 - deployment.apps "serverservice" deleted
 - service "serverservice" deleted

Sau khi xoá cụm, trên ngăn trình đơn, hãy chọn "IAM & Admin" (IAM và Quản trị) > "Settings" (Cài đặt), rồi nhấp vào nút "SHUT DOWN" (TẮT).

578ca2b72a161e9d.png

Sau đó, hãy nhập Mã dự án (không phải Tên dự án) vào biểu mẫu trong hộp thoại rồi xác nhận tắt.