無 Proxy gRPC 應用程式的可觀測性
微服務可觀測性工具可讓您檢測應用程式,以便在 Cloud Monitoring、Cloud Logging 和 Cloud Trace 中收集及顯示從gRPC 工作負載 (包括 Cloud Service Mesh 中的 gRPC 工作負載) 擷取的遙測資料。 Google Cloud
gRPC 用戶端和伺服器會與 OpenCensus 整合,將指標和追蹤記錄匯出至各種後端,包括 Trace 和 Monitoring。您可以使用下列 gRPC 語言執行此操作:
- C++
- Go
- Java
請參閱「微服務觀測功能總覽」,然後按照「設定微服務觀測功能」中的操作說明,為以下項目收集 gRPC 工作負載:
- Cloud Monitoring 和查看指標。
- Cloud Logging 和查看記錄檔。
- Cloud Trace 和查看追蹤記錄。
請按照本文件中的操作說明完成下列工作:
在 Trace 中查看追蹤記錄
完成設定程序後,您已檢測的 gRPC 用戶端和伺服器就會將追蹤記錄傳送至 Trace。 Google Cloud 控制台的「Trace Overview」(追蹤記錄總覽) 頁面會列出最近的追蹤記錄。您可以選取個別追蹤記錄,查看流量細目,類似於下一個章節所述。
追蹤與 Envoy Proxy 的相容性
如「Envoy 的觀測功能」一文所述,使用 Cloud Service Mesh 和 Envoy Proxy 將追蹤記錄匯出至 Trace,會使用 Envoy 的 OpenCensus 追蹤器設定,讓從無 Proxy gRPC 應用程式和 Envoy Proxy 匯出的追蹤記錄,在服務網格中完全相容。為了與無 Proxy gRPC 相容,Envoy 自動啟動程序需要設定追蹤記錄內容,以便在其 OpenCensusConfig
中加入 GRPC_TRACE_BIN
追蹤記錄格式。例如:
tracing: http: name: envoy.tracers.opencensus typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.OpenCensusConfig stackdriver_exporter_enabled: "true" stackdriver_project_id: "PROJECT_ID" incoming_trace_context: ["CLOUD_TRACE_CONTEXT", "GRPC_TRACE_BIN"] outgoing_trace_context: ["CLOUD_TRACE_CONTEXT", "GRPC_TRACE_BIN"]
公開管理介面
有時指標和追蹤資料不足以解決問題。您可能需要查看應用程式中 gRPC 程式庫的設定或執行階段狀態。這項資訊包括解析器資訊、與同儕的連線狀態、管道上的 RPC 統計資料,以及從 Cloud Service Mesh 收到的設定。
為取得這類資訊,gRPC 應用程式可在特定通訊埠上公開管理介面。接著,您可以查詢應用程式,瞭解服務的設定方式和執行方式。本節提供如何設定以各個支援語言編寫的應用程式管理介面的操作說明。
建議您在應用程式中建構另一個 gRPC 伺服器,並讓該伺服器監聽專門用於此用途的通訊埠。這樣一來,即使因設定錯誤或網路問題而無法存取資料端口,您還是可以存取 gRPC 應用程式。建議您只在 localhost
或 Unix 網域 Socket 上公開管理介面。
以下程式碼片段說明如何建立管理員介面。
C++
在 C++ 中,使用以下程式碼建立管理介面:
#include <grpcpp/ext/admin_services.h> grpc::ServerBuilder builder; grpc::AddAdminServices(&builder); builder.AddListeningPort(":50051", grpc::ServerCredentials(...)); std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
Go
在 Go 中,請使用以下程式碼建立管理介面:
import "google.golang.org/grpc/admin" lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) } defer lis.Close() grpcServer := grpc.NewServer(...opts) cleanup, err := admin.Register(grpcServer) if err != nil { log.Fatalf("failed to register admin services: %v", err) } defer cleanup() if err := grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) }
Java
在 Java 中,請使用以下程式碼建立管理介面:
import io.grpc.services.AdminInterface; server = ServerBuilder.forPort(50051) .useTransportSecurity(certChainFile, privateKeyFile) .addServices(AdminInterface.getStandardServices()) .build() .start(); server.awaitTermination();
Python
在 Python 中,請使用以下程式碼建立管理介面:
import grpc_admin server = grpc.server(futures.ThreadPoolExecutor()) grpc_admin.add_admin_servicers(server) server.add_insecure_port('[::]:50051') server.start() server.wait_for_termination()
使用 SSH 連線至 VM
gRPC Wallet 範例已啟用管理介面。您可以提供下列標記,變更管理介面連接埠:
--admin-port=PORT
預設管理員通訊埠為 localhost:28881
。
如要對 gRPC 應用程式進行偵錯,您可以使用 SSH 連線至提供 wallet-service
的其中一個 VM。這樣一來,您就能存取 localhost
。
# List the Wallet VMs $ gcloud compute instances list --filter="zone:(us-central1-a)" --filter="name~'grpcwallet-wallet-v2'" NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS grpcwallet-wallet-v2-mig-us-central1-ccl1 us-central1-a n1-standard-1 10.240.0.38 35.223.42.98 RUNNING grpcwallet-wallet-v2-mig-us-central1-k623 us-central1-a n1-standard-1 10.240.0.112 35.188.133.75 RUNNING # Pick one of the Wallet VMs to debug $ gcloud compute ssh grpcwallet-wallet-v2-mig-us-central1-ccl1 --zone=us-central1-a
安裝 grpcdebug
工具
如要存取管理介面,您需要一個 gRPC 用戶端,才能與 gRPC 應用程式中的管理服務通訊。在以下範例中,您會使用名為 grpcdebug
的工具,您可以在執行 gRPC 應用程式的 VM 或 Pod 上下載及安裝這項工具。grpcdebug
的存放區位於 grpc-ecosystem/grpcdebug。
最低支援的 Golang 版本為 1.12。Golang 網站提供官方 Golang 安裝指南。如果您按照指南為 wallet-service
建立 Linux VM,可以使用下列指令安裝 Golang 1.16:
sudo apt update && sudo apt install -y wget wget https://golang.org/dl/go1.16.3.linux-amd64.tar.gz sudo rm -rf /usr/local/go sudo tar -C /usr/local -xzf go1.16.3.linux-amd64.tar.gz export PATH=$PATH:/usr/local/go/bin sudo ln -sf /usr/local/go/bin/go /usr/bin/go go version # go version go1.16.3 linux/amd64
您可以使用下列指令安裝 grpcdebug
工具:
go install -v github.com/grpc-ecosystem/grpcdebug@latest export PATH=$PATH:$(go env GOPATH)/bin
您現在可以使用 grpcdebug
指令列介面。說明輸出內容包含支援的指令資訊:
$ grpcdebug -h grpcdebug is a gRPC service admin command-line interface Usage: grpcdebug <target address> [flags] <command> Available Commands: channelz Display gRPC states in human readable way. health Check health status of the target service (default ""). help Help about any command xds Fetch xDS related information. Flags: --credential_file string Sets the path of the credential file; used in [tls] mode -h, --help Help for grpcdebug --security string Defines the type of credentials to use [tls, google-default, insecure] (default "insecure") --server_name_override string Overrides the peer server name if non empty; used in [tls] mode -t, --timestamp Print timestamp as RFC 3339 instead of human readable strings -v, --verbose Print verbose information for debugging
如要進一步瞭解特定指令,請使用下列指令:
grpcdebug <target address> [command] --help
使用 grpcdebug
工具對應用程式進行偵錯
您可以使用 grpcdebug
工具來偵錯應用程式。grpcdebug
工具提供類似 ssh_config
的設定,支援別名、主機名稱重寫和連線安全性設定 (不安全/TLS)。如要進一步瞭解這項進階功能,請參閱 grpcdebug/Connect&Security
。
以下各節將說明管理介面公開的服務,以及如何存取這些服務。
使用 Channelz
Channelz 服務可讓您存取應用程式 gRPC 程式庫中不同層級連線的執行階段資訊。您可以使用這項功能,針對可能有設定或網路相關問題的應用程式進行即時分析。以下範例假設您已按照「使用無 Proxy gRPC 服務設定進階流量管理」一文的操作說明,部署 gRPC Wallet 範例,並提供下列標記:
--admin-port=PORT
從測試用戶端傳送一些 RPC 後 (如驗證設定所示),請使用下列指令存取 gRPC 服務的 Channelz 資料:
- 使用 SSH 連線至執行
wallet-service
的 VM。 - 設定
grpcdebug
以連線至執行中的 gRPC 應用程式。
grpcdebug
的預設輸出內容為控制台友善的表格格式。如果您提供 --json
標記,輸出內容會以 JSON
編碼。
grpcdebug channelz
指令可用於擷取 Channelz 服務中的偵錯資訊並顯示。這項指令適用於 gRPC 用戶端和 gRPC 伺服器。
對於 gRPC 用戶端,grpcdebug channelz channels
指令會提供現有管道清單和一些基本資訊:
$ grpcdebug localhost:28881 channelz channels Channel ID Target State Calls(Started/Succeeded/Failed) Created Time 1 xds:///account.grpcwallet.io:10080 READY 0/0/0 59 seconds ago 2 trafficdirector.googleapis.com:443 READY 2/0/0 59 seconds ago 4 xds:///stats.grpcwallet.io:10080 READY 0/0/0 59 seconds ago
如果您需要特定管道的其他資訊,可以使用 grpcdebug channelz channel [CHANNEL_ID]
檢查該管道的詳細資訊。頻道 ID 或目標位址 (如果只有一個目標位址) 都可以做為頻道 ID。gRPC 管道可包含多個子管道,這是 gRPC 在 TCP 連線之上的抽象概念。
$ grpcdebug localhost:28881 channelz channel 2 Channel ID: 2 Target: trafficdirector.googleapis.com:443 State: READY Calls Started: 2 Calls Succeeded: 0 Calls Failed: 0 Created Time: 10 minutes ago --- Subchannel ID Target State Calls(Started/Succeeded/Failed) CreatedTime 3 trafficdirector.googleapis.com:443 READY 2/0/0 10 minutes ago --- Severity Time Child Ref Description CT_INFO 10 minutes ago Channel Created CT_INFO 10 minutes ago parsed scheme: "" CT_INFO 10 minutes ago scheme "" not registered, fallback to default scheme CT_INFO 10 minutes ago ccResolverWrapper: sending update to cc: {[{trafficdirector.googleapis.com:443 <nil> 0 <nil>}] <nil> <nil>} CT_INFO 10 minutes ago Resolver state updated: {Addresses:[{Addr:trafficdirector.googleapis.com:443 ServerName: Attributes:<nil> Type:0 Metadata:<nil>}] ServiceConfig:<nil> Attributes:<nil>} (resolver returned new addresses) CT_INFO 10 minutes ago ClientConn switching balancer to "pick_first" CT_INFO 10 minutes ago Channel switches to new LB policy "pick_first" CT_INFO 10 minutes ago subchannel(subchannel_id:3 ) Subchannel(id:3) created CT_INFO 10 minutes ago Channel Connectivity change to CONNECTING CT_INFO 10 minutes ago Channel Connectivity change to READY
你也可以檢查子頻道的詳細資訊:
$ grpcdebug localhost:28881 channelz subchannel 3 Subchannel ID: 3 Target: trafficdirector.googleapis.com:443 State: READY Calls Started: 2 Calls Succeeded: 0 Calls Failed: 0 Created Time: 12 minutes ago --- Socket ID Local->Remote Streams(Started/Succeeded/Failed) Messages(Sent/Received) 9 10.240.0.38:60338->142.250.125.95:443 2/0/0 214/132
您可以擷取 TCP 通訊端的相關資訊:
$ grpcdebug localhost:28881 channelz socket 9 Socket ID: 9 Address: 10.240.0.38:60338->142.250.125.95:443 Streams Started: 2 Streams Succeeded: 0 Streams Failed: 0 Messages Sent: 226 Messages Received: 141 Keep Alives Sent: 0 Last Local Stream Created: 12 minutes ago Last Remote Stream Created: a long while ago Last Message Sent Created: 8 seconds ago Last Message Received Created: 8 seconds ago Local Flow Control Window: 65535 Remote Flow Control Window: 966515 --- Socket Options Name Value SO_LINGER [type.googleapis.com/grpc.channelz.v1.SocketOptionLinger]:{duration:{}} SO_RCVTIMEO [type.googleapis.com/grpc.channelz.v1.SocketOptionTimeout]:{duration:{}} SO_SNDTIMEO [type.googleapis.com/grpc.channelz.v1.SocketOptionTimeout]:{duration:{}} TCP_INFO [type.googleapis.com/grpc.channelz.v1.SocketOptionTcpInfo]:{tcpi_state:1 tcpi_options:7 tcpi_rto:204000 tcpi_ato:40000 tcpi_snd_mss:1408 tcpi_rcv_mss:1408 tcpi_last_data_sent:8212 tcpi_last_data_recv:8212 tcpi_last_ack_recv:8212 tcpi_pmtu:1460 tcpi_rcv_ssthresh:88288 tcpi_rtt:2400 tcpi_rttvar:3012 tcpi_snd_ssthresh:2147483647 tcpi_snd_cwnd:10 tcpi_advmss:1408 tcpi_reordering:3} --- Security Model: TLS Standard Name: TLS_AES_128_GCM_SHA256
在伺服器端,您可以使用 Channelz 檢查伺服器應用程式的狀態。舉例來說,您可以使用 grpcdebug
channelz servers
指令取得伺服器清單:
$ grpcdebug localhost:28881 channelz servers Server ID Listen Addresses Calls(Started/Succeeded/Failed) Last Call Started 5 [127.0.0.1:28881] 9/8/0 now 6 [[::]:50051] 159/159/0 4 seconds ago
如要進一步瞭解特定伺服器,請使用 grpcdebug channelz
server
指令。您可以採用檢查用戶端通訊端口的方式檢查伺服器通訊端口。
$ grpcdebug localhost:28881 channelz server 6 Server Id: 6 Listen Addresses: [[::]:50051] Calls Started: 174 Calls Succeeded: 174 Calls Failed: 0 Last Call Started: now --- Socket ID Local->Remote Streams(Started/Succeeded/Failed) Messages(Sent/Received) 25 10.240.0.38:50051->130.211.1.39:44904 68/68/0 68/68 26 10.240.0.38:50051->130.211.0.167:32768 54/54/0 54/54 27 10.240.0.38:50051->130.211.0.22:32768 52/52/0 52/52
使用用戶端狀態探索服務
Client Status Discovery Service (CSDS) API 是 xDS API 的一部分。在 gRPC 應用程式中,CSDS 服務會提供從 Cloud Service Mesh 接收的設定 (也稱為 xDS 設定) 存取權。這可協助您找出並解決網格中的設定相關問題。
以下範例假設您已按照「透過無 Proxy gRPC 服務設定進階流量管理」一文中的指示,部署 gRPC Wallet 範例。
如何使用 CSDS 檢查設定:
- 使用 SSH 連線至執行
wallet-service
的 VM。請參閱「使用 SSH 連線至 VM」一節中的操作說明。 - 執行
grpcdebug
用戶端。
如要取得設定狀態的概略資料,請執行下列指令:
grpcdebug localhost:28881 xds status
您會看到類似下列的結果:
Name Status Version Type LastUpdated account.grpcwallet.io:10080 ACKED 1618529574783547920 type.googleapis.com/envoy.config.listener.v3.Listener 3 seconds ago stats.grpcwallet.io:10080 ACKED 1618529574783547920 type.googleapis.com/envoy.config.listener.v3.Listener 3 seconds ago URL_MAP/830293263384_grpcwallet-url-map_0_account.grpcwallet.io:10080 ACKED 1618529574783547920 type.googleapis.com/envoy.config.route.v3.RouteConfiguration 3 seconds ago URL_MAP/830293263384_grpcwallet-url-map_1_stats.grpcwallet.io:10080 ACKED 1618529574783547920 type.googleapis.com/envoy.config.route.v3.RouteConfiguration 3 seconds ago cloud-internal-istio:cloud_mp_830293263384_3566964729007423588 ACKED 1618529574783547920 type.googleapis.com/envoy.config.cluster.v3.Cluster 3 seconds ago cloud-internal-istio:cloud_mp_830293263384_7383783194368524341 ACKED 1618529574783547920 type.googleapis.com/envoy.config.cluster.v3.Cluster 3 seconds ago cloud-internal-istio:cloud_mp_830293263384_3363366193797120473 ACKED 1618529574783547920 type.googleapis.com/envoy.config.cluster.v3.Cluster 3 seconds ago cloud-internal-istio:cloud_mp_830293263384_3566964729007423588 ACKED 86 type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment 2 seconds ago cloud-internal-istio:cloud_mp_830293263384_3363366193797120473 ACKED 86 type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment 2 seconds ago cloud-internal-istio:cloud_mp_830293263384_7383783194368524341 ACKED 86 type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment 2 seconds ago
如要瞭解設定狀態的定義,請參閱 Envoy 代理伺服器的說明文件。簡單來說,xDS 資源的狀態為 REQUESTED
、DOES_NOT_EXIST
、ACKED
或 NACKED
之一。
如要取得原始的 xDS 設定快照,請執行下列指令:
grpcdebug localhost:28881 xds config
您會看到 PerXdsConfig
物件的 JSON
清單:
{ "config": [ { "node": { "id": "projects/830293263384/networks/default/nodes/6e98b038-6d75-4a4c-8d35-b0c7a8c9cdde", "cluster": "cluster", "metadata": { "INSTANCE_IP": "10.240.0.38", "TRAFFICDIRECTOR_GCP_PROJECT_NUMBER": "830293263384", "TRAFFICDIRECTOR_NETWORK_NAME": "default" }, "locality": { "zone": "us-central1-a" }, "userAgentName": "gRPC Go", "userAgentVersion": "1.37.0", "clientFeatures": [ "envoy.lb.does_not_support_overprovisioning" ] }, "xdsConfig": [ { "listenerConfig": { "versionInfo": "1618529930989701137", "dynamicListeners": [ { ...
如果原始設定輸出內容過於冗長,您可以使用 grpcdebug
依據特定 xDS 類型進行篩選。例如:
$ grpcdebug localhost:28881 xds config --type=cds { "versionInfo": "1618530076226619310", "dynamicActiveClusters": [ { "versionInfo": "1618530076226619310", "cluster": { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", "name": "cloud-internal-istio:cloud_mp_830293263384_7383783194368524341", "altStatName": "/projects/830293263384/global/backendServices/grpcwallet-stats-service", "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "initialFetchTimeout": "15s", ...
您也可以同時轉儲多個 xDS 類型的設定:
$ grpcdebug localhost:28881 xds config --type=lds,eds { "versionInfo": "1618530076226619310", "dynamicListeners": [...] } { "dynamicEndpointConfigs": [...] }
後續步驟
- 如需相關資訊,請參閱「透過 Envoy 進行可觀察性」。
- 如要解決部署無 Proxy gRPC 服務時的設定問題,請參閱解決使用無 Proxy gRPC 的部署問題。