使用opentelemetry搭建全链路追踪系统

本文介绍了如何在分布式微服务架构中使用Go语言实现OpenTelemetry(otel)进行服务可观测性,包括使用otel-exporter收集和发送trace数据至otel-collector,以及将trace数据存储和可视化于Zipkin和Elasticsearch。还详细描述了docker部署和配置步骤。
摘要由CSDN通过智能技术生成

背景

由于项目是分布式微服务架构系统,为了实现服务的可观察性,决定搭建一套可观测的系统。 由于我们当前使用的是go,而opentelemetry标准也是目前比较推荐的,并且其支持多语言,于是就想到用otel来搞了。废话不多说,进入主题

架构设计

第一方案: 如下图所示

otel-exporter otel-collector zipkin elasticsearch web send trace push trace store trace web ui view otel-exporter otel-collector zipkin elasticsearch web
  1. otel-exporter:是我们微服里面调用otel/sdk来实现。把数据上传到otel-collector
  2. otel-collector:作为数据收集器,可以收集trace、metric、logs数据。
  3. zipkin:作为trace数据的服务组件,其可以存储trace,可以可视化trace。
  4. elasticsearch:数据存储组件。
  5. web:即通过chrome或其他浏览器,通过访问zipkin提供的http服务来查看链路数据。
    (补充说明: zipkin支持多种存储中间件, 默认为内存存储其重启数据就会丢失, 支持elasticsearch存储搜索快捷。 还有其他存储,有兴趣可以到其官网查看)

落地部署

otel-exporter
import (
	"context"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
	"go.opentelemetry.io/otel/propagation"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	"time"
	semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
)

func NewTracerProvider(cAddr string) (func(context.Context)error, error) {
	ctx := context.Background()
	res ,err := resource.New(ctx,
		resource.WithAttributes(
			semconv.ServiceName("service-name"),
			semconv.ServiceInstanceID("service-instance-id"),
			semconv.ContainerName("container"),
			semconv.ServerAddress("ip"),
			semconv.ServerPort(8888),
		),
	)
	if err != nil {
		return nil, err
	}
	traceExporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithInsecure(), otlptracegrpc.WithEndpoint(cAddr), otlptracegrpc.WithDialOption(grpc.WithBlock()))
	if err != nil {
		return nil, err
	}

	tracerProvider := sdktrace.NewTracerProvider(
		sdktrace.WithResource(res),
		sdktrace.WithBatcher(traceExporter, sdktrace.WithBatchTimeout(time.Minute)),
	)
	otel.SetTracerProvider(tracerProvider)

	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
	return tracerProvider.Shutdown, nil
}

以上是初始化一个tracer exporter。
接着就可以使用全局的tracer来记录trace了

import(
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/trace"
	"go.opentelemetry.io/otel"
	"context"
)

func myFunc(){
	ttrace := otel.Tracer("service-trace")
	ctx, span := ttrace.Start(context.Background(), "parenSpanName", trace.WithAttributes(attribute.String("key","value")))
	defer span.End()

	// do logic
}

当然这里可以支持 配置自己的parent-traceid,支持child-trace-span。 这些都可以通过官网搜索到。

exporter 就到这结束了。

otel-collector

目前组件都是通过docker来安装

 docker run -d --name=otel-collect \
  -p 4317:4317 \
  -p 55679:55679 \
  -v ${pwd}/config.yaml:/etc/otelcol/config.yaml \
  otel/collector:v0.96

配置模版

# To limit exposure to denial of service attacks, change the host in endpoints below from 0.0.0.0 to a specific network interface.
# See https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md#safeguards-against-denial-of-service-attacks

extensions:
  health_check:
  pprof:
    endpoint: 0.0.0.0:1777
  zpages:
    endpoint: 0.0.0.0:55679

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318
  opencensus:
    endpoint: 0.0.0.0:55678
processors:
  batch:
  memory_limiter:
    check_interval: 3s
    limit_mib: 1024
    spike_limit_mib: 1024

exporters:
  debug:
    verbosity: detailed
  zipkin:
    endpoint: http://127.0.0.1:9411/api/v2/spans
  prometheus:
    endpoint: 0.0.0.0:9190
  prometheusremotewrite:
    endpoint: http://127.0.0.1:9090/api/v1/write
    tls:
      insecure: true
  kafka/exporter:
    encoding: otlp_proto
    protocol_version: 2.7.0
    topic: zipkin
    brokers:
      - 127.0.0.1:9092
  otlp/jaeger:
    endpoint: 127.0.0.1:4317
    tls:
      insecure: true
  otlp/zipkin:
    endpoint: 127.0.0.1:9411
    tls:
      insecure: true    
  otlphttp/jaeger:
    endpoint: http://127.0.0.1:14268/api/traces 
service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [zipkin]

    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [logging,prometheus]

  extensions: [health_check, pprof, zpages]

好了 collector就这样配置完了,启动collector就可以了

zipkin
docker  run \
--name zipkin-server -d \
-p 9411:9411 \
-e JAVA_OPTS="-Xmx1G -Xms1G" \
-e STORAGE_THROTTLE_MAX_QUEUE_SIZE=8000 \
-e STORAGE_TYPE=elasticsearch \
-e ES_HOSTS=127.0.0.1:9200 \
openzipkin/zipkin-slim

这里配置es作为trace的存储。
好,现在我们就可以通过 http://localhost:9411/zipkin/ 来访问trace数据了。

效果图

我这里还没有数据

当执行开始写的代码时候,数据就会传输给collector,然后collector会把trace数据转到zipkin,zipkin把数据保存到es中,最后我们可以通过搜索功能搜索trace数据了。

显然这个框架需要优化的点还有很多,尤其是当并发量高的时候 zipkin经常挂。

优化待下一篇文章讲

  • 21
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值