Observabilidade com aplicativos gRPC sem proxy
As ferramentas de observabilidade de microsserviços oferecem a capacidade de instrumentar seus aplicativos para coletar e apresentar dados de telemetria no Cloud Monitoring, Cloud Logging e Cloud Trace usando cargas de trabalho do gRPC implantadas no Google Cloud, incluindo cargas de trabalho de gRPC no Cloud Service Mesh.
Os clientes e servidores gRPC são integrados ao OpenCensus para exportar métricas e traces para vários back-ends, incluindo o Trace e o Monitoring. Para fazer isso, use as seguintes linguagens do gRPC:
- C++
- Go
- Java
Leia a Visão geral da observabilidade de microsserviços e use as instruções em Configurar a observabilidade de microsserviços para instrumentar suas cargas de trabalho do gRPC para:
- Cloud Monitoring e visualização de métricas.
- Cloud Logging e visualização de registros.
- Cloud Trace e visualizar traces.
Use as instruções neste documento para as seguintes tarefas:
- Como visualizar traces.
- Exposição da interface do administrador.
- Como usar a ferramenta
grpcdebug
e outras ferramentas para depurar aplicativos.
Visualizar traces no Trace
Depois de concluir o processo de configuração, os clientes e servidores gRPC instrumentados enviam traces para o Trace. A página Visão geral do trace no Console do Google Cloud mostra uma lista de traces recentes. É possível selecionar um trace individual para ver um detalhamento do seu tráfego, de maneira semelhante ao que é descrito na seção a seguir.
Compatibilidade do Trace com o proxy Envoy
A exportação de traces para o Trace com o Cloud Service Mesh e o proxy
Envoy, conforme descrito em
Observabilidade com o Envoy, usa
a configuração do rastreador do OpenCensus do Envoy, que permite que os traces exportados de
aplicativos gRPC sem proxy e os proxies do Envoy sejam totalmente compatíveis em uma
malha de serviço. Para compatibilidade com o gRPC sem proxy, o bootstrap do Envoy precisa
configurar o contexto de rastreamento para incluir o formato de trace GRPC_TRACE_BIN
no OpenCensusConfig
. Exemplo:
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"]
Expor a interface de administração
Sometimess vezes, os dados de métricas e rastreamento não são suficientes para resolver um problema. Talvez seja necessário analisar a configuração ou o estado do ambiente de execução da biblioteca gRPC no seu aplicativo. Essas informações incluem informações do resolvedor, o estado da conectividade com peering, estatísticas de RPC em um canal e a configuração recebida do Cloud Service Mesh.
Para conseguir essas informações, os aplicativos do gRPC podem expor a interface administrativa em uma porta específica. Em seguida, consulte o aplicativo para entender como os serviços são configurados e como estão sendo executados. Nesta seção, você encontra instruções sobre como configurar a interface administrativa para aplicativos escritos em cada linguagem compatível.
Recomendamos que você crie um servidor gRPC separado no aplicativo que
detecte em uma porta reservada para essa finalidade. Isso permite que você
acesse seus aplicativos gRPC mesmo quando as portas de dados estão inacessíveis por causa
de problemas de configuração ou de rede. Recomendamos que a interface administrativa
seja exposta apenas em localhost
ou em um soquete de domínio Unix.
Os snippets de código a seguir mostram como criar uma interface de administração.
C++
Em C++, use este código para criar uma interface administrativa:
#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
No Go, use este código para criar uma interface administrativa:
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
Em Java, use este código para criar uma interface administrativa:
import io.grpc.services.AdminInterface; server = ServerBuilder.forPort(50051) .useTransportSecurity(certChainFile, privateKeyFile) .addServices(AdminInterface.getStandardServices()) .build() .start(); server.awaitTermination();
Python
No Python, use este código para criar uma interface administrativa:
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()
Usar SSH para se conectar a uma VM
O exemplo gRPC Wallet já ativa a interface do administrador. É possível alterar a porta da interface administrativa fornecendo a seguinte sinalização:
--admin-port=PORT
A porta administrativa padrão é
localhost:28881
.
Para depurar seu aplicativo gRPC, use o SSH para se conectar a uma das VMs que disponibilizam o wallet-service
. Isso dá acesso ao 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
Instalar a grpcdebug
ferramenta
Para acessar a interface administrativa, você precisa de um cliente gRPC que possa se comunicar
com os serviços administrativos no aplicativo gRPC. Nos exemplos a seguir, use
uma ferramenta chamada grpcdebug
. É possível fazer o download e instalá-la na VM ou no pod
em que o aplicativo gRPC está em execução. O repositório de grpcdebug
está
localizado em
grpc-ecosystem/grpcdebug.
A versão mínima de Golang compatível é 1.12. O guia de instalação oficial do Golang
está no site do Golang.
Se você estiver seguindo o guia para criar uma VM do Linux para wallet-service
,
poderá instalar o Golang 1.16 usando estes comandos:
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
Instale a ferramenta grpcdebug
com os seguintes comandos:
go install -v github.com/grpc-ecosystem/grpcdebug@latest export PATH=$PATH:$(go env GOPATH)/bin
Agora você tem acesso à interface de linha de comando grpcdebug
. A saída de ajuda contém informações
sobre os comandos compatíveis:
$ 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
Para ver mais informações sobre um determinado comando, use o seguinte:
grpcdebug <target address> [command] --help
Como usar a ferramenta grpcdebug
para depurar seus aplicativos
Use a ferramenta grpcdebug
para depurar seus aplicativos.
A ferramenta grpcdebug
fornece uma configuração semelhante a ssh_config
, que é compatível
com alias, regravação de nome do host e configuração de segurança da conexão (insegura/TLS).
Para mais informações sobre esse recurso avançado, consulte
grpcdebug/Connect&Security
.
As seções a seguir descrevem os serviços expostos pela interface administrativo e como acessá-los.
Usar Channelz
O serviço Channelz fornece acesso a informações no ambiente de execução sobre as conexões em diferentes níveis na biblioteca gRPC do aplicativo. Use isso para análise em tempo real de aplicativos que possam ter problemas relacionados à configuração ou à rede. Os exemplos a seguir presumem que você implantou o exemplo do gRPC Wallet usando as instruções em Configurar o gerenciamento de tráfego avançado com serviços gRPC sem proxy e que forneceu a seguinte sinalização:
--admin-port=PORT
Depois de enviar algumas RPCs de um cliente de teste, conforme mostrado em Como verificar a configuração, use os seguintes comandos para acessar os dados do Channelz para serviços gRPC.
- Use SSH para se conectar a uma VM que esteja executando o
wallet-service
. - Configure
grpcdebug
para se conectar ao aplicativo gRPC em execução.
A saída padrão de grpcdebug
está em um formato de tabela compatível com o console. Se você fornecer a sinalização --json
, a saída será codificada como JSON
.
O comando grpcdebug channelz
é usado para buscar e apresentar informações
de depuração do serviço Channelz. O comando funciona para clientes e
servidores gRPC.
Para clientes gRPC, o comando grpcdebug channelz channels
fornece uma lista de
canais existentes e algumas informações básicas:
$ 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
Se você precisar de mais informações sobre um canal específico, use
grpcdebug channelz channel [CHANNEL_ID]
para inspecionar as informações
detalhadas do canal. O identificador do canal pode ser o ID do canal
ou o endereço de destino, se houver apenas um endereço de destino. Um canal gRPC pode
conter vários subcanais, que é a abstração do gRPC sobre uma
conexão 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
Você também pode inspecionar informações detalhadas sobre um subcanal:
$ 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
É possível recuperar informações sobre soquetes 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
No lado do servidor, é possível usar o Channelz para inspecionar o status do aplicativo do
servidor. Por exemplo, é possível conseguir a lista de servidores usando o comando 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
Para mais informações sobre um servidor específico, use o comando grpcdebug channelz
server
. É possível inspecionar soquetes de servidor da mesma maneira que inspeciona soquetes de cliente.
$ 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
Usar o serviço de descoberta de status do cliente
A API Client Status Discovery Service (CSDS) faz parte das APIs xDS. Em um aplicativo gRPC, o serviço CSDS fornece acesso à configuração (também chamada de configuração xDS) que recebe do Cloud Service Mesh. Isso permite que você identifique e resolva problemas relacionados à configuração na malha.
Os exemplos a seguir presumem que você implantou o exemplo da carteira de gRPC usando as instruções em Configurar o gerenciamento de tráfego avançado com serviços gRPC sem proxy.
Para usar o CSDS para examinar a configuração:
- Use SSH para se conectar a uma VM que esteja executando o
wallet-service
. Siga as instruções em Usar SSH para se conectar a uma VM. - Execute o cliente
grpcdebug
.
Para ter uma visão geral do status de configuração, execute o seguinte comando:
grpcdebug localhost:28881 xds status
Você verá resultados parecidos com o seguinte:
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
A definição do status de configuração fica na documentação do proxy Envoy.
Em resumo, o status de um recurso xDS é REQUESTED
, DOES_NOT_EXIST
,
ACKED
ou NACKED
.
Para receber um dump de configuração xDS bruta, execute o seguinte comando:
grpcdebug localhost:28881 xds config
Aparecerá uma lista de JSON
do objeto PerXdsConfig
:
{ "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": [ { ...
Se a saída da configuração bruta for muito detalhada, o grpcdebug
permitirá filtrar
com base em tipos de xDS específicos. Exemplo:
$ 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", ...
Também é possível fazer o dump da configuração de vários tipos xDSs ao mesmo tempo:
$ grpcdebug localhost:28881 xds config --type=lds,eds { "versionInfo": "1618530076226619310", "dynamicListeners": [...] } { "dynamicEndpointConfigs": [...] }
A seguir
- Para encontrar informações relacionadas, consulte Observabilidade com o Envoy.
- Para resolver problemas de configuração ao implantar serviços gRPC sem proxy, consulte Solução de problemas em implantações que usam gRPC sem proxy.