Observabilidad con aplicaciones de gRPC sin proxy

En este documento, se proporcionan instrucciones para usar las funciones de observabilidad de gRPC con servicios que usan Traffic Director. Estas funciones brindan acceso a las métricas de seguimiento y supervisión que ayudan a resolver problemas con la implementación.

También se muestra cómo exportar la información a Cloud Trace y Cloud Monitoring.

Requisitos previos

Para crear los ejemplos de este documento, haz lo siguiente:

Algunas de las funciones de observabilidad requieren parámetros de línea de comandos adicionales para las aplicaciones de gRPC. estos parámetros se describen en este documento. Las características y funcionalidades que se describen en este documento son parte de la biblioteca de gRPC. No tienes que configurar más Traffic Director.

Métricas y seguimiento

Los clientes y servidores de gRPC están integrados en OpenCensus para exportar métricas y seguimientos a varios backends, incluido Trace y Monitoring. En este documento, se proporcionan ejemplos en los siguientes lenguajes de gRPC:

  • C++
  • Go
  • Java

Las implementaciones de OpenCensus en otros lenguajes pueden admitir algunas de las funciones descritas en este documento, pero no garantizamos que estas funcionen. Para obtener más detalles, consulta la documentación de OpenCensus.

Cuando las métricas y el seguimiento están habilitados, los clientes y servidores de gRPC exportan las vistas (agregaciones de una métrica determinada) que se mencionan en la especificación de métricas de gRPC de OpenCensus:

  • grpc.io/{client,server}/sent_bytes_per_rpc
  • grpc.io/{client,server}/received_bytes_per_rpc
  • grpc.io/{client,server}/sent_messages_per_rpc
  • grpc.io/{client,server}/received_messages_per_rpc
  • grpc.io/{client,server}/started_rpcs
  • grpc.io/client/roundtrip_latency
  • grpc.io/server/server_latency

Habilita las API de Cloud Monitoring y Cloud Trace

La integración de OpenCensus de gRPC admite una amplia gama de backends para exportar métricas y seguimientos. En los siguientes ejemplos, se muestra cómo exportar esta información a Monitoring y Trace. Estas se denominan de forma colectiva stackdriver en las dependencias en otras partes de este documento.

Para que estos ejemplos funcionen y te permitan visualizar las métricas y los seguimientos en la consola de Google Cloud, sigue las instrucciones a fin de habilitar la API de Monitoring yAPI de Cloud Trace.

Instrumenta aplicaciones de gRPC

El código de ejemplo de Wallet de gRPC ya está instrumentado para las métricas y el seguimiento. Para habilitar las métricas y el seguimiento, ejecuta el cliente de gRPC y los servidores con la siguiente función experimental de línea de comandos:

 --gcp_client_project=PROJECT_ID

Reemplaza PROJECT_ID por el ID de tu proyecto: Si usas create_service.sh script desde el repositorio de ejemplo de Spanner de gRPC como se documenta en Configura la administración avanzada del tráfico con servicios de gRPC sin proxy, agrega esta marca como el último argumento proporcionado a la secuencia de comandos de shell.

Por ejemplo:

./create_service.sh go stats 50052 stats \
    --account_server="xds:///account.grpcwallet.io" \
    --gcp_client_project=PROJECT_ID'

A continuación, se muestran los cambios de código necesarios para agregar la instrumentación a una aplicación de gRPC existente. Como práctica recomendada en tus propias aplicaciones, sugerimos activar el código de la instrumentación detrás de una función experimental de línea de comandos o una variable de entorno, lo que permite que las implementaciones de gRPC sin proxy elijan de forma dinámica habilitar o inhabilitar las métricas y el seguimiento sin necesidad de realizar cambios adicionales en el código.

En el código de ejemplo, se muestra cómo configurar las métricas y el seguimiento al mismo tiempo. También puedes configurarlos por separado o usar uno y no el otro. En el código, se muestra cómo configurarlos juntos porque los pasos para ambos son similares.

C++

El complemento C++ de gRPC de OpenCensus requiere la compilación con Bazel. Debes modificar dos archivos de compilación para incluir las dependencias de OpenCensus.

  1. Agrega lo siguiente al archivo WORKSPACE:

    load("@com_google_googleapis//:repository_rules.bzl", "switched_rules_by_language")
    
    http_archive(
        name = "com_google_googleapis",
        sha256 = "150be57ff83646e5652e03683c949f0830d9a0e73ef787786864210e45537fe0",
        strip_prefix = "googleapis-6e3b55e26bf5a9f7874b6ba1411a0cc50cb87a48",
       urls =       ["https://github.com/googleapis/googleapis/archive/6e3b55e26bf5a9f7874b6ba1411a0cc50cb87a48.zip"],
    )
    
    switched_rules_by_language(
        name = "com_google_googleapis_imports",
        cc = True,
        grpc = True,
    )
    
  2. Agrega las siguientes dependencias al destino de compilación en tu archivo BUILD:

    cc_binary(
       name = "client",
       srcs = ["client.cc"],
       defines = ["BAZEL_BUILD"],
       deps = [
           # New dependencies:
           "@com_github_grpc_grpc//:grpc_opencensus_plugin",
           "@io_opencensus_cpp//opencensus/trace:trace",
           "@io_opencensus_cpp//opencensus/stats:stats",
           "@io_opencensus_cpp//opencensus/exporters/trace/stackdriver:stackdriver_exporter",
           "@io_opencensus_cpp//opencensus/exporters/stats/stackdriver:stackdriver_exporter",
       ],
    )
    
  3. Instrumenta tu aplicación de C++. Los clientes y los servidores se instrumentan de manera global dentro del proceso de la siguiente manera:

    #include <grpcpp/opencensus.h>
    #include "opencensus/exporters/stats/stackdriver/stackdriver_exporter.h"
    #include "opencensus/exporters/trace/stackdriver/stackdriver_exporter.h"
    
    ABSL_FLAG(std::string, gcp_client_project, "", "Google Cloud project for metric/trace uploads");
    
    int main(int argc, char** argv) {
      // Optionally configure OpenCensus before using gRPC
      if (!absl::GetFlag(FLAGS_gcp_client_project).empty()) {
        grpc::RegisterOpenCensusPlugin();
        grpc::RegisterOpenCensusViewsForExport();
        // For demo purposes, always sample (probability=1.0)
        opencensus::trace::TraceConfig::SetCurrentTraceParams(
            {128, 128, 128, 128, opencensus::trace::ProbabilitySampler(1.0)});
        opencensus::exporters::trace::StackdriverOptions trace_opts;
        trace_opts.project_id = absl::GetFlag(FLAGS_gcp_client_project);
        opencensus::exporters::trace::StackdriverExporter::Register(std::move(trace_opts));
        opencensus::exporters::stats::StackdriverOptions stats_opts;
        stats_opts.project_id = absl::GetFlag(FLAGS_gcp_client_project);
        // This must be unique among all processes exporting to Stackdriver
        stats_opts.opencensus_task = "wallet-server-" + std::to_string(getpid());
        opencensus::exporters::stats::StackdriverExporter::Register(std::move(stats_opts));
      }
    
      // Now use gRPC as usual.
    }
    

Go

Para Go, sigue estos pasos.

  1. Instrumenta un cliente mediante un ClientHandler:

    import (
      "go.opencensus.io/plugin/ocgrpc"
      "go.opencensus.io/stats/view"
      "go.opencensus.io/trace"
      "contrib.go.opencensus.io/exporter/stackdriver"
    )
    
    if gcpClientProject != "" {
        view.Register(ocgrpc.DefaultClientViews...)
        sd, err := stackdriver.NewExporter(stackdriver.Options{
            ProjectID:    gcpClientProject,
        })
        defer sd.Flush()
        trace.RegisterExporter(sd)
        sd.StartMetricsExporter()
        defer sd.StopMetricsExporter()
        trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
    
        channel, err := grpc.Dial(serverAddr, grpc.WithInsecure(),
           grpc.WithStatsHandler(new(ocgrpc.ClientHandler)))
    }
    
  2. Instrumenta un servidor mediante un ServerHandler:

    import (
      "go.opencensus.io/plugin/ocgrpc"
      "go.opencensus.io/stats/view"
      "go.opencensus.io/trace"
      "contrib.go.opencensus.io/exporter/stackdriver"
    )
    
    if gcpClientProject != "" {
        view.Register(ocgrpc.DefaultServerViews...)
        sd, err := stackdriver.NewExporter(stackdriver.Options{
            ProjectID:    gcpClientProject,
        })
        defer sd.Flush()
        trace.RegisterExporter(sd)
        sd.StartMetricsExporter()
        defer sd.StopMetricsExporter()
        trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
    
        srv := grpc.NewServer(grpc.StatsHandler(&ocgrpc.ServerHandler{}))
    }
    

Java

Para Java, agrega las siguientes dependencias a tu archivo build.gradle:

def opencensusVersion = "0.28.0"
def grpcVersion = "1.35.0"

dependencies {
  // New dependencies:
  compile "io.grpc:grpc-census:{$grpcVersion}",
               "io.opencensus:opencensus-api:${opencensusVersion}",
               "io.opencensus:opencensus-contrib-grpc-metrics:${opencensusVersion}",
               "io.opencensus:opencensus-exporter-stats-stackdriver:${opencensusVersion}",
               "io.opencensus:opencensus-exporter-trace-stackdriver:${opencensusVersion}"
 runtime "io.opencensus:opencensus-impl:${opencensusVersion}"
}

Para clientes y servidores Java, agregar la dependencia en io.grpc:grpc-census agrega automáticamente la instrumentación de métricas y de seguimiento a tus RPC. Sin embargo, debes especificar un exportador de OpenCensus para obtener datos:

import io.opencensus.contrib.grpc.metrics.RpcViews;
import io.opencensus.exporter.stats.stackdriver.StackdriverStatsConfiguration;
import io.opencensus.exporter.stats.stackdriver.StackdriverStatsExporter;
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceConfiguration;
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter;
import io.opencensus.trace.Tracing;
import io.opencensus.trace.config.TraceConfig;
import io.opencensus.trace.samplers.Samplers;

if (gcpClientProject != "") {
  // Configure export to Monitoring and Trace
  RpcViews.registerAllViews();
  TraceConfig traceConfig = Tracing.getTraceConfig();
  traceConfig.updateActiveTraceParams(
      traceConfig.getActiveTraceParams().toBuilder()
          .setSampler(Samplers.alwaysSample())
          .build());

  StackdriverStatsExporter.createAndRegister(
      StackdriverStatsConfiguration.builder().setProjectId(gcpClientProject).build());
  StackdriverTraceExporter.createAndRegister(
      StackdriverTraceConfiguration.builder().setProjectId(gcpClientProject).build());
}

Visualiza métricas en el panel de Monitoring

Una vez que tus aplicaciones están instrumentadas, las métricas de gRPC se exportan a Monitoring y se pueden ver en el Explorador de métricas de la consola de Google Cloud.

Consola

Para ver las métricas, haz lo siguiente:

  1. En la consola de Google Cloud, ve a la página Monitoring.

    Ir a Monitoring

  2. En la navegación de la izquierda, haz clic en Explorador de métricas.

  3. En Crea tu propia consulta, elige Instancia de VM o Contenedor de GKE como el tipo de recurso.

  4. En el campo Métrica elige cualquiera de los nombres de métricas que se enumeran en Métricas y seguimiento, como OpenCensus/grpc.io/client/roundtrip_latency.

  5. En la lista desplegable Agregador, selecciona Media como el tipo. Deberías ver un gráfico similar al siguiente:

    Explorador de métricas
    Explorador de métricas (haz clic para ampliar)

    Además de las vistas detalladas de Monitoring estándar, como el filtrado para ver solo las estadísticas de un grupo de instancias específico, puedes desglosar las estadísticas por grpc_client_method o grpc_server_method, ya que cada métrica que envía OpenCensus se anota con el nombre de método de gRPC correspondiente.

    Puedes incorporar estas vistas de métricas en paneles y gráficos de Monitoring, y usarlas como base para las alertas automatizadas.

Visualiza seguimientos en Trace

Después de completar el proceso de configuración, tus clientes y servidores de gRPC instrumentados envían seguimientos a Trace. En la página Descripción general de Trace de la consola de Google Cloud, se muestra una lista de los seguimientos recientes. Puedes seleccionar un seguimiento individual para ver un desglose de tu tráfico, similar a lo que se describe en la siguiente sección.

Compatibilidad de Trace con el proxy de Envoy

En la exportación de seguimientos a Trace con Traffic Director y el proxy de Envoy, como se describe en Observabilidad con Envoy, se usa la configuración del seguimiento de OpenCensus de Envoy, que permite que los seguimientos exportados desde aplicaciones de gRPC sin proxy y proxies de Envoy sean totalmente compatibles dentro de una malla de servicios Para obtener compatibilidad con gRPC sin proxy, el arranque de Envoy debe configurar el contexto de seguimiento a fin de incluir el formato de seguimiento GRPC_TRACE_BIN en su OpenCensusConfig. Por ejemplo:

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

Exposición de la interfaz del administrador

A veces, las métricas y los datos de seguimiento no son suficientes para resolver un problema. Es posible que debas observar la configuración o el estado del entorno de ejecución de la biblioteca de gRPC en tu aplicación. Esta información incluye información sobre el agente de resolución, el estado de la conectividad a pares, estadísticas de RPC en un canal y la configuración recibida de Traffic Director.

Para obtener esa información, las aplicaciones de gRPC pueden exponer la interfaz del administrador en un puerto en particular. Luego, puedes consultar la aplicación para comprender cómo se configuran y cómo se ejecutan los servicios. En esta sección, puedes encontrar instrucciones para configurar la interfaz del administrador de las aplicaciones escritas en cada lenguaje compatible.

Te recomendamos que compiles un servidor de gRPC independiente en tu aplicación que escuche en un puerto reservado para este fin. Esto te permite acceder a las aplicaciones de gRPC incluso cuando los puertos de datos son inaccesibles debido a problemas de configuración o de red. Te recomendamos que expongas la interfaz del administrador solo en localhost o en un socket de dominio Unix.

En los siguientes fragmentos de código, se muestra cómo crear una interfaz de administrador.

C++

En C++, usa este código para crear una interfaz de administrador:

#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

En Go, usa este código para crear una interfaz de administrador:

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

En Java, usa este código para crear una interfaz de administrador:

import io.grpc.services.AdminInterface;

server = ServerBuilder.forPort(50051)
        .useTransportSecurity(certChainFile, privateKeyFile)
        .addServices(AdminInterface.getStandardServices())
        .build()
        .start();
server.awaitTermination();

Python

En Python, usa este código para crear una interfaz de administrador:

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()

Usa SSH para conectar a una VM

En el ejemplo de Wallet de gRPC, ya se habilita la interfaz de administrador. Para cambiar el puerto de la interfaz del administrador, proporciona la siguiente marca:

 --admin-port=PORT

El puerto de administrador predeterminado es localhost:28881.

A fin de depurar tu aplicación de gRPC, puedes usar SSH para conectarte a una de las VM que entregan wallet-service. Esto te da acceso a 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

Instala la herramienta grpcdebug

Para acceder a la interfaz del administrador, necesitas un cliente de gRPC que pueda comunicarse con los servicios de administrador en la aplicación de gRPC. En los ejemplos siguientes, usarás una herramienta llamada grpcdebug que puedes descargar y, luego, instalar en la VM o Pod en la que se ejecuta tu aplicación de gRPC. El repositorio para grpcdebug se encuentra en grpc-ecosystem/grpcdebug.

La versión mínima de Golang de asistencia es 1.12. La guía de instalación oficial de Golang se encuentra en el sitio de Golang. Si sigues la guía a fin de crear una VM de Linux para wallet-service, puedes instalar Golang 1.16 con estos 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

Instala la herramienta de grpcdebug con los siguientes comandos:

go install -v github.com/grpc-ecosystem/grpcdebug@latest
export PATH=$PATH:$(go env GOPATH)/bin

Ahora tienes acceso a la interfaz de línea de comandos de grpcdebug. El resultado de ayuda contiene información sobre los comandos compatibles:

$ 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 obtener más información sobre un comando en particular, usa lo siguiente:

 grpcdebug <target address> [command] --help

Usa la herramienta grpcdebug para depurar tus aplicaciones

Puedes usar la herramienta grpcdebug para depurar tus aplicaciones. La herramienta grpcdebug proporciona una configuración similar a ssh_config que admite alias, reescritura de nombre de host y configuración de seguridad de conexión (no segura/TLS). Para obtener más información sobre esta función avanzada, consulta grpcdebug/Connect&Security.

En las siguientes secciones, se describen los servicios que expone la interfaz del administrador y cómo acceder a ellos.

Usa Channelz

El servicio Channelz proporciona acceso a la información del entorno de ejecución sobre las conexiones en diferentes niveles de la biblioteca de gRPC de tu aplicación. Puedes usar esto para el análisis en vivo de las aplicaciones que podrían tener problemas relacionados con la configuración o la red. En los siguientes ejemplos, se supone que implementaste el ejemplo de gRPC mediante las instrucciones de Configura la administración avanzada del tráfico con servicios de gRPC sin proxy y que proporcionaste la siguiente marca:

 --admin-port=PORT

Después de enviar algunas RPC desde un cliente de prueba, como se muestra en Verifica la configuración, usa los siguientes comandos para acceder a los datos de Channelz para los servicios de gRPC:

  1. Usa SSH para conectarte a una VM que ejecuta wallet-service.
  2. Configura grpcdebug para conectarte a la aplicación de gRPC en ejecución.

El resultado predeterminado de grpcdebug está en un formato de tabla compatible con la consola. Si proporcionas la marca --json, el resultado se codifica como JSON.

El comando grpcdebug channelz se usa para recuperar y presentar información de depuración del servicio de Channelz. El comando funciona para los clientes de gRPC y los servidores de gRPC.

Para los clientes de gRPC, el comando grpcdebug channelz channels proporciona una lista de los canales existentes e información básica:

$ 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

Si necesitas información adicional sobre un canal en particular, puedes usar grpcdebug channelz channel [CHANNEL_ID] para inspeccionar información detallada de ese canal. El identificador de canal puede ser el ID del canal o la dirección de destino, si solo hay una dirección de destino. Un canal de gRPC puede contener varios subcanales, que es la abstracción de gRPC sobre una conexión 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

También puedes inspeccionar información detallada sobre un 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

Puedes recuperar información sobre los sockets 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

En el servidor, puedes usar Channelz para inspeccionar el estado de la aplicación del servidor. Por ejemplo, puedes obtener la lista de servidores con el 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 obtener más información sobre un servidor específico, usa el comando grpcdebug channelz server. Puedes inspeccionar los sockets del servidor de la misma manera que inspeccionas los sockets del 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

Usa el servicio de descubrimiento de estado de cliente

La API del Servicio de descubrimiento de estado del cliente (CSDS) forma parte de las API de xDS. En una aplicación de gRPC, el servicio de CSDS proporciona acceso a la configuración (también llamada configuración de xDS) que recibe de Traffic Director. Esto te permite identificar y resolver problemas relacionados con la configuración en tu malla.

En los ejemplos siguientes, se supone que implementaste el ejemplo de gRPC por medio de las instrucciones en Configura la administración avanzada del tráfico con servicios de gRPC sin proxy.

Si deseas usar CSDS para examinar la configuración, haz lo siguiente:

  1. Usa SSH para conectarte a una VM que ejecuta wallet-service. Usa las instrucciones que aparecen en Usa SSH para conectarte a una VM.
  2. Ejecuta el cliente grpcdebug

Para obtener una descripción general del estado de la configuración, ejecuta el siguiente comando:

grpcdebug localhost:28881 xds status

Deberías ver resultados similares a los siguientes:

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

Puedes encontrar la definición del estado de configuración en la documentación del proxy de Envoy. En resumen, el estado de un recurso xDS es REQUESTED, DOES_NOT_EXIST, ACKED o NACKED.

Para obtener un volcado de configuración de xDS sin procesar, ejecuta el siguiente comando:

grpcdebug localhost:28881 xds config

Verás una lista de JSON del 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":  [
              {
...

Si el resultado de la configuración sin procesar es demasiado detallado, grpcdebug te permite filtrar en función de tipos de xDS específicos. Por ejemplo:

$ 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",
...

También puedes volcar la configuración de los varios tipos de xDS al mismo tiempo:

$ grpcdebug localhost:28881 xds config --type=lds,eds
{
  "versionInfo":  "1618530076226619310",
  "dynamicListeners":  [...]
}
{
  "dynamicEndpointConfigs":  [...]
}

¿Qué sigue?