美文网首页
Go微服务架构实战 下篇:1. gRPC + Opentraci

Go微服务架构实战 下篇:1. gRPC + Opentraci

作者: stackfuture | 来源:发表于2022-01-11 17:18 被阅读0次

Go微服务架构实战-【公粽号:堆栈future】

原文
Go微服务架构实战目录

1. 微服务架构上篇

1. grpc技术介绍

2. grpc+protobuf+网关实战

3. etcd技术介绍

4. 基于etcd的服务发现与注册

5. 基于etcd的分布式锁实战

2. 微服务架构中篇

1. k8s架构介绍

2. 基于k8s的容器化部署

3. 基于k8s的Deployment工作负载

4. 基于k8s的ingress实战

5. 基于ingress和service实现灰度发布

6. 常见的服务治理策略

3. 微服务架构下篇

分布式链路追踪实战

干货:


什么是APM

什么是Opentracing

什么是SpanID

什么是TraceID

基于zipkin构建链路追踪


1. 什么是APM

APM(Application Performance Management,即应用性能管理,在分布式领域也称为分布式跟踪管理)对企业的应用系统进行实时监控,它是用于实现对应用程序性能管理和故障管理的系统化的解决方案。

APM核心功能:

  • 服务调用跟踪
  • 应用系统存活检测
  • 监控告警

开源APM管理工具:

  • ZipKin
  • PinPoint
  • SkyWalking
  • Prometheus

我们这篇文章主要是讲解APM的核心功能之一:服务调用跟踪,用到的工具是ZipKin,本来想用Prometheus搭建一个监控平台,想来想去比较简单,大家直接在本地就可以搭建单机版的监控平台。

2. 什么是Opentracing

OpenTracing通过提供平台无关、厂商无关的API,使得开发人员能够方便的添加(或更换)追踪系统的实现。

不过OpenTracing并不是标准。因为CNCF不是官方标准机构,但是它的目标是致力为分布式追踪创建更标准的API和工具。

3. 什么是TraceID

一个trace代表了一个事务或者流程在(分布式)系统中的执行过程,而这个过程会有唯一ID去标识,这个唯一ID就是Trace ID,通俗解释就是一个API请求的完整调用流程。

4. 什么是SpanID

一个span代表在分布式系统中完成的单个工作单元,这个工作单元有唯一ID去标识,这个唯一ID就是Span ID。也包含其他span的“引用”,这允许将多个spans组合成一个完整的Trace。

通俗解释就是在Trace这样一个完整调用的流程中,Span扮演的角色就是每次执行的一次IO或者非IO操作。所以你通过Trace找到整个链路,然后从链路中找到确定的Span,这样就可以准确定位一次问题或者性能查询。

5. 其他名称解释

Span tags(跨度标签)可以理解为用户自定义的Span注释。便于查询、过滤和理解跟踪数据。

Span logs(跨度日志)可以记录Span内特定时间或事件的日志信息。主要用于捕获特定Span的日志信息以及应用程序本身的其他调试或信息输出。

SpanContext 代表跨越进程边界,传递到子级Span的状态。常在追踪示意图中创建上下文时使用。

6. 案例

-[]

图中可以看到以下内容:

  • 执行时间的上下文
  • 服务间的层次关系
  • 服务间串行或并行调用链

结合以上信息,在实际场景中我们可以通过整个系统的调用链的上下文、性能等指标信息,一下子就能够发现系统的痛点在哪儿。

7. 什么是ZipKin

Zipkin是分布式追踪系统。它的作用是收集解决微服务架构中的延迟问题所需的时序数据。它管理这些数据的收集和查找。

Zipkin的设计基于Google Dapper论文。

8. 基于ZipKin构建链路追踪

首先在基于之前的项目之中,把server.go修改一下,让其支持分布式链路追踪。server.go:

<pre data-tool="mdnice编辑器" style="box-sizing: border-box !important; margin: 10px 0px; padding: 0px; outline: 0px; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 14px; overflow: auto; display: block; color: rgb(33, 37, 41); max-width: 100%; overflow-wrap: break-word !important; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.8px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0.8px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">`const (
SERVICE_NAME = "simple_zipkin_server"
ZIPKIN_HTTP_ENDPOINT = "http://127.0.0.1:9411/api/v2/spans" //上报到ZipKin中的链路
ZIPKIN_RECORDER_HOST_PORT = "0.0.0.0"
)

func main() {
...

//链路日志输出到哪
reporter := httpreporter.NewReporter(ZIPKIN_HTTP_ENDPOINT)
defer reporter.Close()

//记录服务名称和端口
endpoint, err := zipkin.NewEndpoint(SERVICE_NAME, ZIPKIN_RECORDER_HOST_PORT)
if err != nil {
log.Fatalf("zipkin.NewEndpoint err: %v", err)
}

tracer, err := zipkin.NewTracer(reporter, zipkin.WithLocalEndpoint(endpoint))
if err != nil {
log.Fatalf("zipkin.NewTracer err: %v", err)
}

//接入opentracing
t := zipkinot.Wrap(tracer)
opentracing.SetGlobalTracer(t)

logrus.Infof("starting hello service at: %s", *port)

//初始化grpc server,并注册中间件
s := grpc.NewServer(
// otgrpc.LogPayloads 是否记录 入参和出参
// otgrpc.SpanDecorator 装饰器,回调函数
// otgrpc.IncludingSpans 是否记录
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(otgrpc.OpenTracingServerInterceptor(t,
otgrpc.LogPayloads(),
// IncludingSpans是请求前回调
otgrpc.IncludingSpans(func(parentSpanCtx opentracing.SpanContext, method string, req, resp interface{}) bool {
log.Printf("method: %s", method)
log.Printf("req: %+v", req)
log.Printf("resp: %+v", resp)
return true
}),
// SpanDecorator是请求后回调
otgrpc.SpanDecorator(func(span opentracing.Span, method string, req, resp interface{}, grpcError error) {
log.Printf("method: %s", method)
log.Printf("req: %+v", req)
log.Printf("resp: %+v", resp)
log.Printf("grpcError: %+v", grpcError)
}),
))),
)

//注册服务
pb.RegisterGreeterServer(s, &server{})
fmt.Println("ddd")
s.Serve(lis)
}` </pre>

至此我们的grpc服务就有了链路追踪功能,接下来我们演示下,启动server.go:k8s-grpc-demo go run cmd/svr/svr.go -port 50004

然后启动客户端:k8s-grpc-demo go run cmd/cli/cli.go

我们可以看下server.go的日志: 图片 我们发现日志完美记录到ZipKin中,接下来我们看下ZipKin地址: 图片 当我们点击RUN QUERY的时候可以看到如下: 图片

当我们点击某一个Trace的时候,就进入这个Trace的整个调用链路详情中:

图片

这样我就基于gRPC + Opentracing + Zipkin的分布式链路追踪系统就搭建完成了,大家下去可以自己尝试下。

9. 小结

各位读者朋友们,我们的Go微服务架构实战【上中下】系列课程到这里就基本上结束了,写作过程中虽然很累,很艰辛,但是这个系列能在有限的业余时间坚持创作完实属不易,希望在之后的业余时间当中能继续为大家带来更棒的系列课程,欢迎大家点赞、关注和分享。

最后再次感谢大家对本系列课程的大力支持,由于个人能力有限,难免哪里写的有问题欢迎大家指出,也欢迎各位能在百忙之中抽出时间学习,最后和各位分享一句话:简单的东西不一定是最好的,但最好的东西一定是简单的。

相关文章

网友评论

      本文标题:Go微服务架构实战 下篇:1. gRPC + Opentraci

      本文链接:https://www.haomeiwen.com/subject/kcticrtx.html