Si necesita rastreo distribuido para una aplicación Go y ya utiliza Zipkin en su pila tecnológica, puede enviar los datos de rastreo directamente a Managed Service for OpenTelemetry. Tras la integración, podrá consultar la topología de la aplicación, los rastros, las transacciones lentas o con errores y el análisis de SQL en la consola.
Para obtener funciones más completas, capacidades avanzadas de rastreo y una mejor experiencia, conecte su aplicación a Managed Service for OpenTelemetry mediante el protocolo OpenTelemetry. Para más información, consulte Preparations.
ARMS ofrece un agente desarrollado internamente con soporte comercial para aplicaciones Go. Este agente permite una instrumentación no intrusiva y proporciona un conjunto de funciones más amplio y mayor estabilidad. Para más información, consulte Monitor Go applications.
Funcionamiento
Zipkin es un sistema de rastreo distribuido de código abierto desarrollado por Twitter que agrega datos de monitoreo en tiempo real provenientes de varios sistemas heterogéneos.
Su aplicación Go utiliza la biblioteca cliente de Zipkin para crear spans y enviarlos al endpoint de Managed Service for OpenTelemetry a través de HTTP:
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
Un entorno de desarrollo Go
Acceso a la consola de Managed Service for OpenTelemetry
El endpoint de Zipkin correspondiente a su región (consulte Obtención del endpoint de Zipkin)
Obtención del endpoint de Zipkin
Inicie sesión en la consola de Managed Service for OpenTelemetry.
En el panel de navegación izquierdo, haga clic en Cluster Configurations. En la página que se muestra, haga clic en la pestaña Access point information.
En la barra de navegación superior, seleccione una región. En la sección Cluster Information, active Show Token.
Establezca Client en Jaeger o Zipkin. En este ejemplo, se selecciona Jaeger.
Copie el endpoint de la columna Related Information.

Si su aplicación se ejecuta en un entorno de producción de Alibaba Cloud, utilice el endpoint de VPC. De lo contrario, use el endpoint público. Utilice el endpoint v2 a menos que tenga un motivo específico para usar v1.
Inicio rápido
Ejecute una demostración precompilada para verificar que los datos de rastreo llegan a Managed Service for OpenTelemetry antes de instrumentar su propia aplicación.
Descargue el proyecto de demostración.
Abra
utils.goy reemplace<endpoint>con el endpoint de Zipkin que obtuvo en Obtención del endpoint de Zipkin.-
Instale las dependencias:
dep ensure -
Ejecute la aplicación:
go run main.go -
Verifique los datos de rastreo en la consola:
Inicie sesión en la consola de ARMS.
En el panel de navegación izquierdo, vaya a Application Monitoring > Applications.
Haga clic en el nombre de la aplicación para consultar sus datos de rastreo.
Si aparece el icono
en la columna Language, la aplicación está conectada a Application Monitoring. Si aparece un guion (-), la aplicación está conectada a Managed Service for OpenTelemetry.
Instrumentación de su aplicación
Esta sección describe cada paso de la instrumentación: agregar dependencias, crear un tracer, registrar spans, etiquetar spans y propagar el contexto entre servicios.
Agregar dependencias
Agregue la biblioteca Zipkin Go y un router a su proyecto:
[[constraint]]
name = "github.com/openzipkin/zipkin-go"
version = "0.1.1"
[[constraint]]
name = "github.com/gorilla/mux"
version = "1.6.2"
Crear un tracer
Un tracer genera spans que registran los tiempos y metadatos de las operaciones distribuidas. Configúrelo con el endpoint de reporte, la identidad del servicio local y una estrategia de muestreo.
func getTracer(serviceName string, ip string) *zipkin.Tracer {
// Create a reporter that sends spans to the Zipkin endpoint.
// Replace the URL with your actual endpoint from the console.
reporter := httpreporter.NewReporter("http://tracing-analysis-dc-hz.aliyuncs.com/adapt_aokcdqnxyz@123456ff_abcdef123@abcdef123/api/v2/spans")
// Set the local endpoint so spans are tagged with this service's identity.
endpoint, _ := zipkin.NewEndpoint(serviceName, ip)
// Sample every request. Increase the modulo value to reduce sampling
// and lower reporting costs (e.g., NewModuloSampler(10) samples 1 in 10).
sampler := zipkin.NewModuloSampler(1)
// Initialize the tracer with the reporter, endpoint, and sampler.
tracer, _ := zipkin.NewTracer(
reporter,
zipkin.WithLocalEndpoint(endpoint),
zipkin.WithSampler(sampler),
)
return tracer
}
Crear spans
Un span raíz registra la operación de nivel superior de una solicitud:
span := tracer.StartSpan("some_operation")
// ... perform the operation ...
span.Finish()
Para rastrear suboperaciones dentro de una solicitud, cree spans secundarios pasando el contexto padre:
childSpan := tracer.StartSpan("some_operation2", zipkin.Parent(span.Context()))
// ... perform the sub-operation ...
childSpan.Finish()
Agregar etiquetas y anotaciones personalizadas (opcional)
Las etiquetas asocian metadatos de clave-valor a un span para facilitar el filtrado y la depuración. Por ejemplo, registre el código de estado HTTP:
childSpan.Tag("http.status_code", statusCode)
Las anotaciones registran eventos con marca de tiempo dentro de un span. Úselas para registrar errores con trazas de pila:
childSpan := tracer.StartSpan("some_operation2", zipkin.Parent(span.Context()))
// ... perform the operation ...
var events = make(map[string]string)
events["event"] = "error"
events["stack"] = "Runtime Exception: unable to find userid"
jsonStr, err := json.Marshal(events)
if err == nil {
childSpan.Annotate(time.Now(), string(jsonStr))
}
childSpan.Finish()
Propagar el contexto entre servicios
El contexto de rastreo (TraceId, ParentSpanId, SpanId y Sampled) debe viajar con cada llamada a procedimiento remoto (RPC) para que los spans de diferentes servicios se vinculen en un solo rastro. Zipkin utiliza encabezados B3 para propagar el contexto a través de HTTP y gRPC.

Lado del cliente: inyectar el contexto en la solicitud saliente
req, _ := http.NewRequest("GET", "/", nil)
// Inject trace context as B3 headers into the HTTP request.
injector := b3.InjectHTTP(req)
injector(sp.Context())
Lado del servidor: extraer el contexto de la solicitud entrante
req, _ := http.NewRequest("GET", "/", nil)
b3.InjectHTTP(req)(sp.Context())
b.ResetTimer()
_ = b3.ExtractHTTP(copyRequest(req))
Solución de problemas
Ausencia de datos tras la instrumentación
Revise la salida de errores de su aplicación:
**
failed the request with status code 403**: El nombre de usuario o la contraseña no son válidos. Copie el endpoint completo, incluido el segmento de autenticación, desde la pestaña Access point information.Sin errores pero sin datos: Compruebe que la URL del endpoint incluya el protocolo (
http://ohttps://) y la ruta completa que termina en/api/v2/spans. Confirme también que su red permita conexiones salientes hacia el endpoint.Configuración de muestreo:
NewModuloSamplercon un valor mayor que 1 muestrea solo una fracción de las solicitudes. Establézcalo en1durante las pruebas para capturar todas las solicitudes.