1. Giới thiệu
Lần cập nhật gần đây nhất: ngày 14 tháng 07 năm 2022
Khả năng ghi nhận của ứng dụng
Khả năng ghi nhận và Trình phân tích tài nguyên liên tục
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.
Ngoài ra, ngoài 3 yếu tố chính của khả năng quan sát, tính năng lập hồ sơ liên tục là một thành phần quan trọng khác giúp ghi nhận khả năng quan sát và mở rộng cơ sở người dùng trong ngành. Trình phân tích tài nguyên trên đám mây là một trong những trình khởi tạo và cung cấp một giao diện dễ dàng để xem chi tiết các chỉ số hiệu suất trong ngăn xếp lệnh gọi ứng dụng.
Lớp học lập trình này là phần 2 của loạt bài học này, bao gồm việc đo lường một tác nhân trình phân tích tài nguyên liên tục. Phần 1 đề cập đến việc theo dõi phân tán bằng OpenTelemetry và Cloud Trace. Bạn sẽ tìm hiểu thêm về cách xác định nút thắt cổ chai của các dịch vụ vi mô một cách hiệu quả hơn trong phần 1.
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 lường tác nhân trình phân tích tài nguyên liên tục trong dịch vụ máy chủ của "Ứng dụng Shakespeare" (còn gọi là Shakesapp) chạy trên cụm Google Kubernetes Engine. Cấu trúc của Shakesapp được mô tả như dưới đây:
- Loadgen gửi một chuỗi truy vấn đến máy khách trong HTTP
- Ứng dụng chuyển truy vấn từ trình tạo tải đến máy chủ trong gRPC
- 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
Trong phần 1, bạn đã thấy nút thắt cổ chai tồn tại đâu đó trong dịch vụ máy chủ, nhưng bạn không thể xác định được nguyên nhân chính xác.
Kiến thức bạn sẽ học được
- Cách nhúng tác nhân trình phân tích tài nguyên
- Cách kiểm tra cổ chai trên Cloud Profiler
Lớp học lập trình này giải thích cách đo lường một tác nhân trình phân tích tài nguyên liên tục trong ứng dụng của bạn.
Bạn cần có
- Kiến thức cơ bản về cờ vây
- Kiến thức cơ bản về Kubernetes
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à Google Artifact Registry được nêu trong tài liệu chính thức.
- Giá cho bộ công cụ vận hành của Google Cloud | Bộ công cụ vận hành
- 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ả lệnh
<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 ngôn ngữ Go
Trong lớp học lập trình này, chúng ta sẽ sử dụng Go cho tất cả các mã nguồn. Chạy lệnh sau trên Cloud Shell và xác nhận xem phiên bản Go có phải là 1.17+ không
go version
Kết quả lệnh
go version go1.18.3 linux/amd64
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 sẽ 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-codelab2 \ --zone us-central1-f \ --release-channel rapid \ --preemptible \ --enable-autoscaling \ --max-nodes 8 \ --no-enable-ip-alias \ --scopes cloud-platform
Kết quả lệnh
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
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. Đối với các bước này, chúng ta cần thiết lập Sổ đăng ký cấu phần phần mềm (GAR) và skaffold để sử dụng Sổ đăng ký cấu phần phần mềm này.
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 nút "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 này 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 ứ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.38.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ự điều hướng đến trang tổng quan của Artifact Registry và nhấp vào tên của kho lưu trữ 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 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 để 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ẽ đo lường tác nhân trình phân tích tài nguyên liên tục trong dịch vụ máy chủ.
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/ymotongpoo/opentelemetry-trace-codelab-go.git cd opentelemetry-trace-codelab-go
Cấu trúc thư mục của dự án như sau:
. ├── 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
- 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: thư mục mã nguồn của từng dịch vụ
- skaffold.yaml: Tệp cấu hình cho skaffold
Trong lớp học lập trình này, bạn sẽ cập nhật mã nguồn trong thư mục step4
. Bạn cũng có thể tham khảo mã nguồn trong thư mục step[1-6]
để biết các thay đổi từ đầu. (Phần 1 bao gồm bước 0 đến bước 4 và Phần 2 bao gồm bước 5 và bước 6)
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. Nghe có vẻ như 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 step4 skaffold dev
Ngay khi chạy lệnh này, bạn sẽ thấy kết quả 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
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
[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
Lưu ý rằng tại thời điểm này, bạn muốn xem bất kỳ thư nào từ máy chủ. Được rồi, 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ụ.
Trước khi bắt đầu đo lường dịch vụ, vui lòng tắt cụm bằng phím Ctrl-C.
Kết quả lệnh
... [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
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. Khả năng đo lường của tác nhân Trình phân tích đám mây
Khái niệm về tính năng lập hồ sơ liên tục
Trước khi giải thích khái niệm lập hồ sơ liên tục, trước tiên, chúng ta cần hiểu rõ khái niệm đó. Phân tích tài nguyên là một trong những cách để phân tích động ứng dụng (phân tích chương trình động) và thường được thực hiện trong quá trình phát triển ứng dụng, như trong quy trình kiểm thử tải, v.v. Đây là một hoạt động bắn một lần để đo lường các chỉ số hệ thống, chẳng hạn như mức sử dụng CPU và bộ nhớ trong một khoảng thời gian cụ thể. Sau khi thu thập dữ liệu hồ sơ, nhà phát triển sẽ phân tích chúng bằng mã.
Lập hồ sơ liên tục là phương pháp mở rộng của tính năng lập hồ sơ thông thường: Giải pháp này chạy định kỳ các hồ sơ cửa sổ ngắn dựa trên ứng dụng chạy trong thời gian dài và thu thập một loạt dữ liệu hồ sơ. Sau đó, Google Analytics 4 tự động tạo bản phân tích thống kê dựa trên một thuộc tính nhất định của ứng dụng, chẳng hạn như số phiên bản, khu vực triển khai, thời gian đo lường, v.v. Bạn có thể xem thêm thông tin chi tiết về khái niệm này trong tài liệu của chúng tôi.
Vì mục tiêu là một ứng dụng đang chạy, nên có cách để thu thập dữ liệu hồ sơ theo định kỳ và gửi dữ liệu đó đến một phần phụ trợ nào đó để xử lý sau dữ liệu thống kê. Đó là tác nhân Cloud Profiler và bạn sẽ sớm nhúng tác nhân này vào dịch vụ máy chủ.
Nhúng tác nhân Trình phân tích tài nguyên trên đám mây
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ở
step4/src/server/main.go
trong trình khám phá ở ngăn bên trái rồi tìm hàm chính.
step4/src/server/main.go
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 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) healthpb.RegisterHealthServer(srv, svc) if err := srv.Serve(lis); err != nil { log.Fatalf("error serving server: %v", err) } }
Trong hàm main
, bạn sẽ thấy một số mã thiết lập cho OpenTelemetry và gRPC. Mã này đã được thực hiện trong phần 1 của lớp học lập trình. Bây giờ, bạn sẽ thêm khả năng đo lường cho tác nhân Trình phân tích đám mây tại đây. Giống như những gì chúng ta đã làm cho initTracer()
, bạn có thể viết một hàm tên là initProfiler()
để dễ đọc.
step4/src/server/main.go
import ( ... "cloud.google.com/go/profiler" // step5. add profiler package "cloud.google.com/go/storage" ... ) // step5: add Profiler initializer func initProfiler() { cfg := profiler.Config{ Service: "server", ServiceVersion: "1.0.0", NoHeapProfiling: true, NoAllocProfiling: true, NoGoroutineProfiling: true, NoCPUProfiling: false, } if err := profiler.Start(cfg); err != nil { log.Fatalf("failed to launch profiler agent: %v", err) } }
Hãy xem kỹ các tuỳ chọn được chỉ định trong đối tượng profiler.Config{}
.
- Dịch vụ: Tên dịch vụ mà bạn có thể chọn và bật trên trang tổng quan trình phân tích tài nguyên
- ServiceVersion: Tên phiên bản dịch vụ. Bạn có thể so sánh các tập dữ liệu hồ sơ dựa trên giá trị này.
- NoHeapProfiling: tắt chế độ phân tích mức tiêu thụ bộ nhớ
- NoAllocProfiling: tắt tính năng phân tích tài nguyên phân bổ bộ nhớ
- NoGoroutineProfiling: tắt tính năng lập hồ sơ goroutine
- NoCPUProfiling (NoCPUProfiling): tắt tính năng phân tích CPU
Trong lớp học lập trình này, chúng ta chỉ bật tính năng phân tích CPU.
Bây giờ, bạn chỉ cần gọi hàm này trong hàm main
. Hãy nhớ nhập gói Cloud Profiler (Trình phân tích đám mây) trong khối nhập.
step4/src/server/main.go
func main() { ... defer func() { if err := tp.Shutdown(context.Background()); err != nil { log.Fatalf("error shutting down TracerProvider: %v", err) } }() // step2. end setup // step5. start profiler go initProfiler() // step5. end svc := NewServerService() // step2: add interceptor ... }
Xin lưu ý rằng bạn đang gọi hàm initProfiler()
bằng từ khoá go
. Vì profiler.Start()
chặn nên bạn cần chạy mã này trong một goroutine khác. Bây giờ, công cụ này đã sẵn sàng để tạo. Hãy nhớ chạy go mod tidy
trước khi triển khai.
go mod tidy
Bây giờ, hãy triển khai cụm bằng dịch vụ máy chủ mới.
skaffold dev
Thường sẽ mất vài phút để xem được biểu đồ hình ngọn lửa trên Trình phân tích đám mây. Nhập "trình phân tích tài nguyên" vào hộp tìm kiếm ở trên cùng rồi nhấp vào biểu tượng Trình phân tích tài nguyên.
Sau đó, bạn sẽ thấy biểu đồ hình ngọn lửa dưới đây.
Tóm tắt
Ở bước này, bạn đã nhúng tác nhân Trình phân tích đám mây vào dịch vụ máy chủ và xác nhận rằng tác nhân này tạo biểu đồ hình ngọn lửa.
Tiếp theo
Trong bước tiếp theo, bạn sẽ điều tra nguyên nhân gây ra điểm tắc nghẽn trong ứng dụng bằng biểu đồ hình ngọn lửa.
5. Phân tích biểu đồ hình ngọn lửa của Trình phân tích đám mây
Biểu đồ ngọn lửa là gì?
Biểu đồ hình ngọn lửa là một trong những cách trực quan hoá dữ liệu hồ sơ. Để biết nội dung giải thích chi tiết, vui lòng tham khảo tài liệu của chúng tôi, nhưng phần tóm tắt ngắn gọn sẽ:
- Mỗi thanh biểu thị lệnh gọi phương thức/hàm trong ứng dụng
- Hướng dọc là ngăn xếp cuộc gọi; ngăn xếp lệnh gọi tăng từ trên xuống dưới
- Hướng ngang là mức sử dụng tài nguyên; càng dài thì càng tệ.
Do đó, hãy xem biểu đồ hình ngọn lửa thu được.
Phân tích biểu đồ hình ngọn lửa
Trong phần trước, bạn đã tìm hiểu rằng mỗi thanh trong biểu đồ hình ngọn lửa biểu thị lệnh gọi hàm/phương thức và độ dài của thanh đó có nghĩa là mức sử dụng tài nguyên trong hàm/phương thức. Biểu đồ hình ngọn lửa của Trình phân tích tài nguyên đám mây sắp xếp thanh theo thứ tự giảm dần hoặc độ dài từ trái sang phải. Trước tiên, bạn có thể bắt đầu xem ở góc trên cùng bên trái của biểu đồ.
Trong trường hợp này, rõ ràng là grpc.(*Server).serveStreams.func1.2
đang chiếm hầu hết thời gian của CPU và bằng cách xem qua ngăn xếp lệnh gọi từ trên xuống dưới, phần lớn thời gian này được dành cho main.(*serverService).GetMatchCount
, vốn là trình xử lý máy chủ gRPC trong dịch vụ máy chủ.
Trong GetMatchCount, bạn sẽ thấy một loạt hàm regexp: regexp.MatchString
và regexp.Compile
. Các quảng cáo này đến từ gói tiêu chuẩn: tức là các quảng cáo này phải được thử nghiệm kỹ càng từ nhiều khía cạnh, bao gồm cả hiệu suất. Tuy nhiên, kết quả ở đây cho thấy mức sử dụng tài nguyên thời gian của CPU cao trong regexp.MatchString
và regexp.Compile
. Dựa trên những dữ kiện đó, giả định ở đây là việc sử dụng regexp.MatchString
có liên quan đến các vấn đề về hiệu suất. Vì vậy, hãy đọc mã nguồn nơi hàm được sử dụng.
step4/src/server/main.go
func (s *serverService) GetMatchCount(ctx context.Context, req *shakesapp.ShakespeareRequest) (*shakesapp.ShakespeareResponse, error) { resp := &shakesapp.ShakespeareResponse{} texts, err := readFiles(ctx, bucketName, bucketPrefix) if err != nil { return resp, fmt.Errorf("fails to read files: %s", err) } for _, text := range texts { for _, line := range strings.Split(text, "\n") { line, query := strings.ToLower(line), strings.ToLower(req.Query) isMatch, err := regexp.MatchString(query, line) if err != nil { return resp, err } if isMatch { resp.MatchCount++ } } } return resp, nil }
Đây là nơi regexp.MatchString
được gọi. Bằng cách đọc mã nguồn, bạn có thể nhận thấy rằng hàm được gọi bên trong vòng lặp for lồng nhau. Do đó, cách sử dụng hàm này có thể không đúng. Hãy tra cứu regexp trên GoDoc.
Theo tài liệu này, regexp.MatchString
biên dịch mẫu biểu thức chính quy trong mọi lệnh gọi. Vì vậy, nguyên nhân của việc tiêu thụ tài nguyên lớn nghe có vẻ như thế này.
Tóm tắt
Trong bước này, bạn đã đưa ra giả định về nguyên nhân tiêu thụ tài nguyên bằng cách phân tích biểu đồ hình ngọn lửa.
Tiếp theo
Trong bước tiếp theo, bạn sẽ cập nhật mã nguồn của dịch vụ máy chủ và xác nhận thay đổi từ bản 1.0.0.
6. Cập nhật mã nguồn và so sánh biểu đồ ngọn lửa
Cập nhật mã nguồn
Ở bước trước, bạn đã giả định rằng việc sử dụng regexp.MatchString
có liên quan đến việc tiêu thụ tài nguyên lớn. Vì vậy, hãy giải quyết vấn đề này. Mở mã và thay đổi phần đó một chút.
step4/src/server/main.go
func (s *serverService) GetMatchCount(ctx context.Context, req *shakesapp.ShakespeareRequest) (*shakesapp.ShakespeareResponse, error) { resp := &shakesapp.ShakespeareResponse{} texts, err := readFiles(ctx, bucketName, bucketPrefix) if err != nil { return resp, fmt.Errorf("fails to read files: %s", err) } // step6. considered the process carefully and naively tuned up by extracting // regexp pattern compile process out of for loop. query := strings.ToLower(req.Query) re := regexp.MustCompile(query) for _, text := range texts { for _, line := range strings.Split(text, "\n") { line = strings.ToLower(line) isMatch := re.MatchString(line) // step6. done replacing regexp with strings if isMatch { resp.MatchCount++ } } } return resp, nil }
Như bạn thấy, hiện tại quy trình biên dịch mẫu biểu thức chính quy được trích xuất từ regexp.MatchString
và di chuyển ra khỏi vòng lặp for lồng nhau.
Trước khi triển khai mã này, hãy nhớ cập nhật chuỗi phiên bản trong hàm initProfiler()
.
step4/src/server/main.go
func initProfiler() { cfg := profiler.Config{ Service: "server", ServiceVersion: "1.1.0", // step6. update version NoHeapProfiling: true, NoAllocProfiling: true, NoGoroutineProfiling: true, NoCPUProfiling: false, } if err := profiler.Start(cfg); err != nil { log.Fatalf("failed to launch profiler agent: %v", err) } }
Giờ hãy cùng xem cách hoạt động. Triển khai cụm bằng lệnh skaffold.
skaffold dev
Sau một thời gian, hãy tải lại trang tổng quan của Trình phân tích tài nguyên trên đám mây để xem giao diện sẽ trông như thế nào.
Hãy nhớ thay đổi phiên bản thành "1.1.0"
để bạn chỉ thấy các hồ sơ từ phiên bản 1.1.0. Như bạn có thể thấy, độ dài của thanh GetMatchCount giảm và tỷ lệ sử dụng thời gian của CPU (tức là thanh này ngắn hơn).
Bạn không chỉ xem xét biểu đồ hình ngọn lửa của một phiên bản đơn lẻ mà còn có thể so sánh sự khác biệt giữa hai phiên bản.
Thay đổi giá trị của mục "So sánh với" danh sách thả xuống thành "Phiên bản" và thay đổi giá trị của "Phiên bản so sánh" thành "1.0.0", phiên bản gốc.
Bạn sẽ thấy loại biểu đồ hình ngọn lửa này. Hình dạng của biểu đồ giống như 1.1.0 nhưng màu sắc khác nhau. Trong chế độ so sánh, ý nghĩa của màu:
- Xanh dương: giá trị (mức sử dụng tài nguyên) đã giảm
- Cam: giá trị (mức tiêu thụ tài nguyên) đã nhận được
- Xám: trung tính
Dựa trên chú giải, hãy tìm hiểu kỹ hơn về hàm này. Khi nhấp vào thanh bạn muốn phóng to, bạn có thể xem thêm thông tin chi tiết bên trong ngăn xếp. Vui lòng nhấp vào thanh main.(*serverService).GetMatchCount
. Ngoài ra, bằng cách di chuột lên thanh này, bạn sẽ thấy thông tin chi tiết về phép so sánh.
Nó nói tổng thời gian của CPU giảm từ 5,26 giây xuống còn 2,88 giây (tổng cộng là 10 giây = khoảng thời gian lấy mẫu). Đây là một bước tiến lớn!
Giờ đây, bạn có thể cải thiện hiệu suất của ứng dụng nhờ việc phân tích dữ liệu hồ sơ.
Tóm tắt
Trong bước này, bạn đã chỉnh sửa trong dịch vụ máy chủ và xác nhận sự cải thiện đối với chế độ so sánh của Trình phân tích tài nguyên trên đám mây.
Tiếp theo
Trong bước tiếp theo, bạn sẽ cập nhật mã nguồn của dịch vụ máy chủ và xác nhận thay đổi từ bản 1.0.0.
7. Bước bổ sung: Xác nhận việc cải thiện trong thác nước Theo dõi
Sự khác biệt giữa dấu vết phân phối và lập hồ sơ liên tục
Trong phần 1 của lớp học lập trình, bạn đã xác nhận rằng mình có thể tìm ra dịch vụ gây nút thắt cổ chai trên các dịch vụ vi mô cho đường dẫn yêu cầu và bạn không tìm ra được nguyên nhân chính xác gây ra nút thắt cổ chai trong dịch vụ cụ thể. Trong lớp học lập trình phần 2 này, bạn đã được biết rằng việc lập hồ sơ liên tục cho phép bạn xác định nút thắt cổ chai bên trong một dịch vụ từ ngăn xếp lệnh gọi.
Trong bước này, hãy xem biểu đồ thác nước trong dấu vết phân phối (Cloud Trace) và tìm hiểu sự khác biệt so với quá trình lập hồ sơ liên tục.
Biểu đồ thác nước này là một trong các dấu vết với truy vấn "tình yêu". Tổng cộng mất khoảng 6,7 giây (6700 mili giây).
Và đây là sau khi cải tiến cho cùng một truy vấn. Như bạn đã biết, tổng độ trễ hiện là 1,5 giây (1500 mili giây), đây là một cải tiến rất lớn so với cách triển khai trước đó.
Điểm quan trọng ở đây là trong biểu đồ thác nước theo dõi được phân phối, thông tin ngăn xếp lệnh gọi sẽ không có sẵn trừ phi công cụ của bạn mở rộng ở mọi nơi. Ngoài ra, dấu vết được phân phối chỉ tập trung vào độ trễ trên các dịch vụ, trong khi việc lập hồ sơ liên tục tập trung vào tài nguyên máy tính (CPU, bộ nhớ, luồng hệ điều hành) của một dịch vụ.
Ở một khía cạnh khác, dấu vết được phân phối là cơ sở sự kiện, hồ sơ liên tục mang tính thống kê. Mỗi dấu vết có một biểu đồ độ trễ khác nhau và bạn cần một định dạng khác, chẳng hạn như phân phối để nhận được xu hướng thay đổi độ trễ.
Tóm tắt
Trong bước này, bạn đã kiểm tra sự khác biệt giữa tính năng theo dõi được phân phối và lập hồ sơ liên tục.
8. 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. (
grpc.health.v1.Health/Check
) Làm cách nào để lọc ra những khoảng thời gian đó trong Cloud Trace? 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ữ đó.
Ngoài ra, nếu bạn muốn tìm hiểu về trình phân tích tài nguyên sau phần này, vui lòng chuyển sang phần 2. Trong trường hợp đó, bạn có thể bỏ qua phần dọn dẹp dưới đây.
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 đó. Nếu đang chạy cụm bằng skaffold dev
, bạn chỉ cần nhấn Ctrl-C. Nếu bạn đang chạy cụm bằng skaffold run
, hãy chạy 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.