热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Jaeger链路追踪

[toc]文章介绍这里将来介绍什么是链路追踪,为什么需要链路追踪,用jaeger做服务链路追踪什么是链路追踪链路这里的链路指的是客户端向服务发起一个请求,该请求所经过的路线,也可以






[toc]


文章介绍

这里将来介绍什么是链路追踪,为什么需要链路追踪, 用jaeger做服务链路追踪


什么是链路追踪


链路

这里的链路指的是客户端向服务发起一个请求,该请求所经过的路线,也可以说是该请求经过的流量

例如: 客户端发起一个下订单的请求其流量过程:

request—>service—>order-web—>order_srv—>mysql—>order_srv—>order-web—>service—>response

这就一个请求的完整链路


链路追踪

指我们通过一些手段将链路进行监控, 对于系统调试和维护链路追踪是非常重要的,尤其微服务中,我们知道各

个微服务部署在不同的服务器上,并且每一个微服务可能是不同的人开发的,如果我们不做链路追踪,微服务之

间相互调用,假如有的微服务出问题了,整个系统都会受影响,那么我们怎么知道是哪一个微服务出的问题,找

谁维护等一系列问题。


Jaeger的安装(docker)

docker run \
--rm \
--name jaeger \
-p6831:6831/udp \
-p16686:16686 \
jaegertracing/all-in-one:latest

启动成功后可以访问:localhost:16686

架构:

mxshop-files.oss-cn-hangzhou.aliyu...


Jaeger的快速使用

使用jaeger就行链路追踪

package main
import (
"time"
"github.com/opentracing/opentracing-go"
"github.com/uber/jaeger-client-go"
jaegercfg "github.com/uber/jaeger-client-go/config"
)
func main() {
//初始化配置
cfg := jaegercfg.Configuration{
Sampler: &jaegercfg.SamplerConfig{
Type: jaeger.SamplerTypeConst,
Param: 1,
},
Reporter: &jaegercfg.ReporterConfig{
LogSpans: true,
LocalAgentHostPort: "127.0.0.1:6831",
},
ServiceName: "mxshop",
}
//初始化跟踪链
Tracer, Closer, err := cfg.NewTracer(jaegercfg.Logger(jaeger.StdLogger))
if err != nil {
panic(err)
}
//将跟踪连设置为项目全局变量
opentracing.SetGlobalTracer(Tracer)
//span1 := opentracing.StartSpan("funcA")
//time.Sleep(time.Second * 1)
//span1.Finish()
defer Closer.Close()
span1 := Tracer.StartSpan("funcA") //开始追踪
time.Sleep(time.Second * 1)
span1.Finish() //完成追踪
span2 := Tracer.StartSpan("funcC") //开始追踪
time.Sleep(time.Second * 2)
span2.Finish() //完成追踪
}

我们在ui界面可以看到

两个Traces即:funcC和funcA,里面有运行的时间等信息


截屏2022-11-13 下午8.36.40

funcC:


截屏2022-11-13 下午8.36.53

层级关系:

package main
import (
"time"
"github.com/opentracing/opentracing-go"
"github.com/uber/jaeger-client-go"
jaegercfg "github.com/uber/jaeger-client-go/config"
)
func main() {
//初始化配置
cfg := jaegercfg.Configuration{
Sampler: &jaegercfg.SamplerConfig{
Type: jaeger.SamplerTypeConst,
Param: 1,
},
Reporter: &jaegercfg.ReporterConfig{
LogSpans: true,
LocalAgentHostPort: "10.2.118.0:6831",
},
ServiceName: "test",
}
//初始化跟踪连
Tracer, Closer, err := cfg.NewTracer(jaegercfg.Logger(jaeger.StdLogger))
if err != nil {
panic(err)
}
defer Closer.Close()
Parents := Tracer.StartSpan("main")
span1 := Tracer.StartSpan("funcD", opentracing.ChildOf(Parents.Context()))
time.Sleep(time.Second * 1)
span1.Finish()
span2 := Tracer.StartSpan("funcE", opentracing.ChildOf(Parents.Context()))
time.Sleep(time.Second * 2)
span2.Finish()
}

可以看到

main:

​ funcD:———1s———

​ funcE —————————-2s———————

![截屏2022-11-13 下午8.55.53](/Users/feng/Desktop/截屏2022-11-13 下午8.55.53.png)


将jaeger集成到grpc服务中

我们需要向获取Jaeger-grpc的代码:github.com/iceymoss/Learning-notes 的jaeger_test中

这里我们对Grpc不做介绍了,如果您不了解Grpc您需要先了解Grpc详解

Server:

package main
import (
"context"
"fmt"
"log"
"net"
"StudyGin/jaeger_test/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
)
type HelloSerivce struct{}
func (h *HelloSerivce) SayHello(c context.Context, req *proto.HelloRequest) (*proto.HelloReply, error) {
//接收context中的内容
md, ok := metadata.FromIncomingContext(c)
if !ok {
fmt.Println("get metadata err", ok)
}
for key, value := range md {
fmt.Printf("%v: %v\n", key, value)
}
return &proto.HelloReply{
Id: "123456789",
Request: req,
}, nil
}
func (h *HelloSerivce) Ping(context.Context, *proto.IsEmpty) (*proto.Pong, error) {
return nil, nil
}
func main() {
//实例化server
lit, err := net.Listen("tcp", ":50051")
if err != nil {
log.Panicln("监听失败", err)
}
//注册处理逻辑
//NewServer创建一个未注册服务且尚未开始接受请求的 gRPC 服务器。
s := grpc.NewServer()
proto.RegisterGreeterServer(s, &HelloSerivce{})
log.Println(s.Serve(lit))
}

Client:

package main
import (
"context"
"fmt"
"log"
"time"
"StudyGin/jaeger_test/otgrpc"
"StudyGin/jaeger_test/proto"
"github.com/opentracing/opentracing-go"
"github.com/uber/jaeger-client-go"
jaegercfg "github.com/uber/jaeger-client-go/config"
"google.golang.org/grpc"
timepb "google.golang.org/protobuf/types/known/timestamppb"
)
func main() {
//日志追踪初始化配置
cfg := jaegercfg.Configuration{
Sampler: &jaegercfg.SamplerConfig{
Type: jaeger.SamplerTypeConst,
Param: 1,
},
Reporter: &jaegercfg.ReporterConfig{
LogSpans: true,
LocalAgentHostPort: "127.0.0.1:6831",
},
ServiceName: "mxshop",
}
//初始化跟踪连
Tracer, Closer, err := cfg.NewTracer(jaegercfg.Logger(jaeger.StdLogger))
if err != nil {
panic(err)
}
//将tracer设置为全局
opentracing.SetGlobalTracer(Tracer)
defer Closer.Close()
clientConn, err := grpc.Dial("localhost:50051", grpc.WithInsecure(), grpc.WithUnaryInterceptor(otgrpc.OpenTracingClientInterceptor(opentracing.GlobalTracer())))
if err != nil {
log.Panicln("连接失败", err)
}
defer clientConn.Close()
client := proto.NewGreeterClient(clientConn)
res, err := client.SayHello(context.Background(), &proto.HelloRequest{
Name: "kuangyang",
Url: "learinku.com",
Gender: proto.Gender_MALE,
M: map[string]string{
"来自": "无锡",
"现居": "无锡",
},
AddTime: timepb.New(time.Now()),
})
if err != nil {
panic(err)
}
//pong, err := client.Ping(context.Background(), &proto.IsEmpty{})
//if err != nil {
// panic(err)
//}
fmt.Printf("返回结果: %v", res)
}

我们可以到jaeger的ui界面查看本次调用的链路数据




golang
后端
rpc


推荐阅读
author-avatar
上帝的爱神_413_645
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有