1. Giới thiệu
Lần cập nhật gần đây nhất: 5/3/2021
Khả năng ghi nhận của ứng dụng
Khả năng quan sát và phương pháp OpenTelemetry
Khả năng quan sát 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 ghi nhận được cho phép các nhóm chủ động gỡ lỗi hệ thống của mình. Trong bối cảnh đó, 3 trụ cột của khả năng quan sát; nhật ký, chỉ số và dấu vết là các công cụ đo lường cơ bản để hệ thống thu thập khả năng quan sát.
OpenTelemetry là một bộ thông số kỹ thuật và SDK giúp tăng tốc độ đ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 dự án tiêu chuẩn mở và hướng đến cộng đồng theo 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, các 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à chống lại nhiều kiến trúc.
Dấu vết đã phân phối
Trong các 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 trong hệ thống. Đặc biệt trong thời đại của các dịch vụ vi mô, dấu vết phân tán là yếu tố thúc đẩy mạnh mẽ để phát hiện điểm tắc nghẽn về độ trễ trong hệ thống phân phối tổng thể.
Khi phân tích dấu vết được phân phối, hình ảnh dữ liệu theo dõi là chìa khoá để nắm bắt nhanh độ trễ tổng thể của hệ thống. Trong dấu vết được phân phối, 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 của hệ thống ở dạng Dấu vết chứa nhiều Span.
Span 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 phối, ghi lại thời gian bắt đầu và thời gian kết thúc. Các span 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 span nhỏ hơn là các span con của một /messages span và được tập hợp thành một Trace cho thấy lộ trình làm việc thông qua một hệ thống.
Google Cloud Trace là một trong những công cụ phụ trợ theo dõi phân tán và có thể tích hợp hiệu quả 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ẽ tìm hiểu thông tin theo dõi đo lường 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. Cấu trúc của Shakesapp được mô tả như dưới đây:
- Ứng dụng gửi một chuỗi truy vấn đến máy chủ
- Máy chủ chấp nhận truy vấn của ứng dụng, tìm nạp tất cả tác phẩm của Shakespare ở định dạng văn bản trong Google Cloud Storage, tìm các dòng chứa truy vấn và trả về số dòng khớp với ứng dụng.
Bạn sẽ đo lường thông tin theo dõi trong 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 span bằng thư viện
- Cách truyền bối cảnh span qua dây 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 dịch vụ vi mô 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, ứng dụng khách và máy chủ). Tuy nhiên, 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 lớn và phức tạp 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 tiến độ riêng
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) và tạo một dự án mới.
Nếu bạn đã có một dự án, hãy nhấp vào trình đơn kéo xuống để chọn dự án ở phía trên bên trái của bảng điều khiển:
và nhấp vào "Dự án MỚI" trong hộp thoại kết quả để tạo một dự án mới:
Nếu chưa có dự án nào, bạn sẽ thấy một hộp thoại như sau để tạo dự án đầu tiên:
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:
Xin lưu ý rằng mã dự án là tên duy nhất trong tất cả dự án Google Cloud (tên ở trên đã được sử dụng nên sẽ không phù hợp với bạn!). Mã này sẽ được đề cập sau trong lớp học lập trình này với tên PROJECT_ID.
Tiếp theo, nếu chưa làm như vậy, bạn sẽ cần bật tính năng thanh toán trong Developers Console để có thể sử dụng tài nguyên của Google Cloud và bật Cloud Trace API.
Bạn sẽ không mất quá vài đô la khi chạy lớp học lập trình này, nhưng có thể sẽ cao 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 để chúng 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à Sổ đăng ký Google Artifacat được trình bày trong tài liệu chính thức.
- Định giá cho khả năng quan sát của Google Cloud
- Giá | Tài liệu về Kubernetes Engine
- Giá của Artifact Registry | Tài liệu về Artifact Registry
Người dùng mới của Google Cloud Platform đủ điều kiện nhận 300 USD dùng thử miễn phí. Vì vậy, lớp học lập trình này sẽ hoàn toàn miễn phí.
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 trong Đám mây.
Máy ảo dựa trên Debian này được tải tất cả các công cụ phát triển mà bạn cần. Dịch vụ này cung cấp thư mục gốc 5 GB ổn định và chạy trong Google Cloud, giúp nâng cao đáng kể hiệu suất và khả năng xác thực của mạng. Tức là tất cả những gì bạn cần để thực hiện lớp học lập trình này là một trình duyệt (vâng, trình duyệt này hoạt động trên Chromebook).
Để kích hoạt Cloud Shell từ Cloud Console, bạn chỉ cần nhấp vào biểu tượng Kích hoạt Cloud Shell (chỉ mất vài phút để cấp phép và kết nối với môi trường).
Sau khi kết nối với Cloud Shell, bạn sẽ thấy mình đã được xác thực và dự án đã được đặt thành PROJECT_ID
.
gcloud auth list
Kết quả lệnh
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
Kết quả lệnh
[core] project = <PROJECT_ID>
Nếu vì lý do nào đó mà dự án không được thiết lập, chỉ cần phát hành lệnh sau:
gcloud config set project <PROJECT_ID>
Bạn đang tìm PROJECT_ID
? Hãy xem mã nhận dạng bạn đã sử dụng ở các bước thiết lập hoặc tra cứu trong trang tổng quan Cloud Console:
Cloud Shell cũng đặt một số biến môi trường theo mặc định. Điều này có thể hữu ích khi bạn chạy các lệnh sau này.
echo $GOOGLE_CLOUD_PROJECT
Kết quả
<PROJECT_ID>
Cuối cùng, đặ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 vùng khác nhau. Để biết thêm thông tin, hãy xem 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 từ "thơ" để quản lý các phiên bản gói. 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 cụm Google Kubernetes
Trong lớp học lập trình này, bạn sẽ vận hành một cụm dịch vụ vi mô trên Google Kubernetes Engine (GKE). Quy trình của lớp học lập trình này sẽ diễn ra như sau:
- Tải dự án cơ sở xuống Cloud Shell
- Xây dựng các dịch vụ vi mô trong vùng chứa
- Tải các vùng chứa lên Google Artifact Registry (GAR)
- Triển khai vùng chứa trên GKE
- Sửa đổi mã nguồn của dịch vụ để đo lường dấu vết
- Chuyển tới bước 2
Bật Kubernetes Engine
Trước tiên, chúng ta thiết lập một cụm Kubernetes mà trong đó 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" và nhấn nút BẬT.
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 rằng giá trị vùng thuộc khu vực mà bạn đã dùng để tạo kho lưu trữ Artifact Registry. Hãy thay đổi giá trị vùng us-central1-f
nếu vùng lưu trữ của bạn không bao gồm vùng này.
gcloud container clusters create otel-trace-codelab --zone us-central1-f \ --num-nodes 1 \ --machine-type e2-highcpu-4
Kết quả 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
Bây giờ, 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 sổ đăng ký vùng chứa để đẩy và triển khai vùng chứa. Ở bước này, chúng ta cần thiết lập GAR và skaffold để sử dụng nó.
Thiết lập Artifact Registry
Chuyển đến trình đơn của "Artifact Registry" và nhấn nút BẬT.
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 "TẠO KHỐI LƯỢNG" và nhập tên của kho lưu trữ.
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 mà 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 tôi chọn "us-central1 (Iowa)". Sau đó, hãy nhấp vào nút "TẠO" .
Bây giờ, bạn sẽ thấy "lớp học lập trình theo dõi" trên trình duyệt kho lưu trữ.
Chúng ta sẽ quay lại đây sau để kiểm tra đường dẫn đăng ký.
Thiết lập SafetyNet
Skaffold là một công cụ hữu ích khi bạn xây dựng các dịch vụ vi mô chạy trên Kubernetes. Thư viện này xử lý quy trình xây dựng, đẩy và triển khai vùng chứa của ứng dụng bằng một tập hợp nhỏ các lệnh. Theo mặc định, Skaffold sử dụng Sổ đăng ký Docker 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 vào.
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 cài đặt skaffold vào môi trường.) Chạy lệnh sau và xem phiên bản skaffold.
skaffold version
Kết quả lệnh
v1.20.0
Bây giờ, bạn có thể đăng ký kho lưu trữ mặc định để skaffold sử dụng. Để biết đường dẫn đăng ký, hãy tự chuyển đến trang tổng quan của Artifact Registry và nhấp vào tên kho lưu trữ mà bạn vừa thiết lập ở bước trước.
Sau đó, bạn sẽ thấy các đường dẫn breadcrumb (tập hợp liên kết phân cấp) ở đầu trang. Nhấp vào biểu tượng để sao chép đường dẫn sổ đăng ký vào bảng nhớ tạm.
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 với thông báo như sau:
"us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab" đã được sao chép
Quay lại vỏ đám mây. 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
Kết quả 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
Kết quả 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
Bây giờ, bạn có thể thực hiện bước tiếp theo để thiết lập 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 của lớp học lập trình:
- Thiết lập Cloud Shell
- Đã tạo kho lưu trữ Artifact Registy 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 để chạy các dịch vụ vi mô của lớp học lập trình
Tiếp theo
Trong bước tiếp theo, bạn sẽ xây dựng, đẩy và triển khai các dịch vụ vi mô trên cụm
3. Xây dựng, đẩy mạnh và triển khai các dịch vụ vi mô
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 mọi điều kiện tiên quyết cho lớp học lập trình này. Bây giờ, bạn đã sẵn sàng chạy toàn bộ các dịch vụ vi mô trên các dịch vụ đó. Tài liệu của lớp học lập trình này được lưu trữ trên GitHub, vì vậy hãy tải chúng 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
- tệp kê khai: tệp kê khai của Kubernetes
- proto: định nghĩa proto cho hoạt động giao tiếp giữa ứng dụng và máy chủ
- src: các thư mục cho mã nguồn của mỗi nhóm thiết bị
- 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 xây dựng, đẩy và triển khai toàn bộ nội dung trên cụm Kubernetes mà bạn vừa tạo. Điều này nghe có vẻ gồm nhiều bước, nhưng thực tế là skaffold làm hết mọi việc cho bạn. Hãy thử thực hiện điều đó bằng lệnh sau:
cd shakesapp-python skaffold run --tail
Ngay khi chạy lệnh này, bạn sẽ thấy đầu ra nhật ký của docker build
và có thể xác nhận rằng các tệp này đã được đẩy thành công vào sổ đăng ký.
Kết quả 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 bạn đẩy tất cả vùng chứa dịch vụ, các quy trình triển khai Kubernetes sẽ tự động bắt đầu.
Kết quả 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ư "Không có quyền truy cập đẩy vào kho lưu trữ hình ảnh được chỉ định", hãy kiểm tra xem lệnh skaffold có đang cố gắng đẩy hình ảnh vào Docker Hub (docker.io) bất kể cấu hình của bạn trong kho lưu trữ mặc định trong skaffold hay không. Trong trường hợp đó, hãy thử thêm "–default-repo" lựa chọn "skaffold run" như bên dưới.
$ skaffold run –tail –default-repo=us-central1-docker.pkg.dev/[mã dự án]/[tên kho lưu trữ]
Sau khi triển khai, bạn sẽ thấy nhật ký ứng dụng thực tế được phát ra cho stdout trong mỗi vùng chứa như sau:
Kết quả 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 cho ứ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ụ tải để đo lường thông tin theo dõi.
4. Đo lường cho HTTP
Khái niệm về khả năng đo lường và lan truyền dấu vết
Trước khi chỉnh sửa mã nguồn, hãy để tôi giải thích ngắn gọn cách dấu vết được phân phối hoạt động trong một sơ đồ đơn giản.
Trong ví dụ này, chúng ta sẽ đo lường mã để xuất thông tin Trace và Span sang Cloud Trace, đồng thời truyền ngữ cảnh theo dõi qua yêu cầu từ dịch vụ tạo tải đến dịch vụ máy chủ.
Ứng dụng cần gửi siêu dữ liệu về Theo dõi như Mã theo dõi và Mã Span để Cloud Trace tập hợp tất cả các span có cùng mã theo dõi 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 (kết hợp giữa Mã theo dõi và Span ID của span gốc) khi yêu cầu các dịch vụ hạ nguồn, để ứng dụng có thể biết được ngữ cảnh theo dõi nào đang được xử lý.
OpenTelemetry giúp bạn:
- để tạo Mã theo dõi và Span ID duy nhất
- để xuất mã theo dõi và mã span sang phần phụ trợ
- để truyền ngữ cảnh theo dõi đến các dịch vụ khác
Khoảng thời gian đầu tiên của công cụ
Dịch vụ tạo tải nhạc cụ
Mở Cloud Shell Editor bằng cách nhấn nút ở 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 rồi 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 cách triển khai hiện tại, sectoin có 2 dòng nhật ký ghi lại điểm bắt đầu và kết thúc của lệnh gọi hàm. Bây giờ, hãy đo lường thông tin Span để theo dõi độ trễ của lệnh gọi hàm.
Trước tiên, bạn cần tạo một Span có một Mã theo dõi và Mã span duy nhất. OpenTelemetry cung cấp thư viện hữu ích cho việc này. Thêm các dòng sau để nhập các 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 ta sử dụng gói tiện ích cho requests
và bật khả năng đo lường.
from opentelemetry.propagators.cloud_trace_propagator import CloudTraceFormatPropagator
+
+RequestsInstrumentor().instrument()
Sau đó, thiết lập thực thể Tracer xử lý chế độ cài đặt Trình theo dõi và 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à lớp học lập trình nhằm tìm hiểu cách thức hoạt động của công cụ đo lường dấu vết, nên chúng ta sẽ định cấu hình Trình theo dõi để ghi lại mọi yêu cầu và gửi các yêu cầu đó đến phần phụ trợ. (SimpleSpanProcessor()
) Phần này không phù hợp với môi trường phát hành công khai, vì vậy, hãy nhớ thay đổi phần này khi bạn đo lường ứng dụng chính thức.
Giờ đây, bạn có thể đo lường Spans bằng Tracer. Vấn đề ở đây là những gì bạn cần làm là tạo Span một cách rõ ràng, và thế là xong! Mặc dù có hai dòng thêm siêu dữ liệu sự kiện vào Span, nhưng bạn không cần tạo mã theo dõi duy nhất và mã Span theo cách thủ công rồi nhúng các mã này vào Span.
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)
Để bản dựng Docker tìm nạp các gói OpenTelemetry bắt buộc, 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 phần mô tả phần phụ thuộc tương ứng được viết bằng pyproject.toml
.
Dịch vụ khách hàng công cụ
Trong phần trước, chúng ta đã đo lường phần được đưa vào 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 về khoảng trống trong dịch vụ 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 cho 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 để tạo Span.
Mở Cloud Shell Editor và thêm các mô-đun bắt buộc như chúng tôi đã làm đối với 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
để bật công cụ đo lường tự động cho ứng dụng Flask thay mặt người dùng để trích xuất tiêu đề HTTP nhằm lấy Trace Contexts bằng một dòng mã duy nhất. Cộng đồng OpenTelemetry cung cấp các tiện ích tích hợp hữu ích tương tự với các thư viện lớn 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 đo lường, một lần nữa, bạn cần chuẩn bị thực thể 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():
....
Bây giờ, 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ụ tải trình tạo, 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 nội dung trên trang tổng quan Cloud Trace:
skaffold run --tail
Sau khi xem một số thông báo về bản dựng, thông báo đẩy và triển khai, bạn sẽ thấy nhật ký ứng dụng ở định dạng JSON. Chuyển đến phần Cloud Trace > Danh sách dấu vết để kiểm tra xem bạn có nhận được thông tin theo dõi hay không. Do dịch vụ trình tạo tải gửi yêu cầu tới dịch vụ ứng dụng theo định kỳ và bạn đã bật tính năng theo dõi cho tất cả yêu cầu, nên bạn bắt đầu thấy nhiều dấu chấm trên danh sách theo dõi.
Khi nhấp vào một trong các phần đó, bạn sẽ thấy biểu đồ thác nước như bên dưới giải thích rằng độ 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 thị sự kiện", sau đó bạn sẽ thấy chú thích bên trong biểu đồ thác nước. Các chú giải này là những chú giải bạn đo lường trong mã bằng phương thức span.add_event()
.
Bạn có thể nhận thấy rằng mình không thấy các span từ dịch vụ máy chủ. Đó là chính xác vì chúng tôi chưa đo lường Span trong dịch vụ máy chủ.
Tóm tắt
Ở bước này, bạn đã đo lường dịch vụ trình tạo tải và dịch vụ máy khách, đồng thời xác nhận rằng bạn có thể truyền thành công Trace Context giữa các dịch vụ và xuất thông tin Span từ cả hai dịch vụ sang Cloud Trace.
Tiếp theo
Trong 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 dịch vụ vi mô này. Ở bước này, chúng ta cố gắng đo lường hoạt độ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)
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 tiện dụng giúp các nhà phát triển đo lường ứng dụng. Ở bước trước, chúng ta đã sử dụng công cụ đo lường tự động cho "yêu cầu" . Ở bước này, khi chúng ta đang cố gắng phổ biến Trace Context (Ngữ cảnh theo dõi) thông qua gRPC, nên chúng ta sẽ sử dụng thư viện cho nó.
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ụ máy khách, việc chúng ta cần làm để đo lường là khá nhỏ. Việc chúng ta muốn làm là phổ biến Ngữ cảnh theo dõi, là sự kết hợp giữa Mã theo dõi và Span ID của Span 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 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
Tương tự như với ứng dụng gRPC, chúng tôi gọi công cụ đ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: Hãy nhớ gọi
GrpcInstrumentationServe()
ở bước này, không phải
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)
Hãy nhớ thêm các gói mới thêm 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 dịch vụ vi mô 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
Bây giờ, một lần nữa, bạn sẽ thấy một loạt dấu vết trong trang danh sách Theo dõi 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 trải nghiệm đó trải rộng trong yêu cầu từ dịch vụ trình tạo tải đến dịch vụ máy chủ.
Tóm tắt
Ở 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 phân phố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 dấu vết được phân phối bằng OpenTelemery và xác nhận độ trễ của yêu cầu trên dịch vụ vi mô trên Google Cloud Trace.
Đối với các bài tập mở rộng, bạn có thể thử tự mình thử các chủ đề sau.
- Phương thức triển khai hiện tại sẽ gửi tất cả các span được tạo bằng tính năng kiểm tra tình trạng. Google lọc ra những khoảng thời gian đó từ Cloud Traces bằng cách nào? Gợi ý có tại đây.
- Liên kết nhật ký sự kiện với span và xem cách thức hoạt động của nhật ký sự kiện trên Google Cloud Trace và Google Cloud Logging. Gợi ý có tại đây.
- Thay thế một dịch vụ bằng một 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 sẽ liên tục sử dụng tài nguyên.
Dọn dẹp
Sau 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 các khoản 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
Kết quả 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, trong ngăn trình đơn, hãy chọn "IAM và Quản trị viên" > "Cài đặt", sau đó nhấp vào "HUỶ XUỐNG" .
Sau đó, nhập Mã dự án (không phải Tên dự án) vào biểu mẫu trong hộp thoại và xác nhận tắt máy.