单进程的链路跟踪即进程内方法之间的调用链关系。这种场景的跟踪没有涉及到分布式跟踪,比较简单,以该示例作为我们入门的一个例子吧。示例代码地址:https://github.com/GOgf/gf/tree/master/example/trace/inprocess
创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站制作、成都网站建设、外贸营销网站建设、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的瑞丽网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
root span
即链路中第一个span
对象。在这里的单进程场景中,往往需要手动创建一个。随后在方法内部创建的span
都会作为它的子级span
。
在分布式架构的服务间通信场景中,往往不需要开发者手动创建root span
,而是由客户端/服务端请求的拦截器来自动创建。
创建tracer
,生成root span
:
func main() {
var ctx = gctx.New()
tp, err := jaeger.Init(ServiceName, JaegerUdpEndpoint)
if err != nil {
g.Log().Fatal(ctx, err)
}
defer tp.Shutdown(ctx)
ctx, span := gtrace.NewSpan(ctx, "main")
defer span.End()
// Trace 1.
user1 := GetUser(ctx, 1)
g.Dump(user1)
// Trace 2.
user100 := GetUser(ctx, 100)
g.Dump(user100)
}
上述代码创建了一个root span
,并将该span
通过context
传递给GetUser
方法,以便在GetUser
方法中将追踪链继续延续下去。
// GetUser retrieves and returns hard coded user data for demonstration.
func GetUser(ctx context.Context, id int) g.Map {
ctx, span := gtrace.NewSpan(ctx, "GetUser")
defer span.End()
m := g.Map{}
gutil.MapMerge(
m,
GetInfo(ctx, id),
GetDetail(ctx, id),
GetScores(ctx, id),
)
return m
}
// GetInfo retrieves and returns hard coded user info for demonstration.
func GetInfo(ctx context.Context, id int) g.Map {
ctx, span := gtrace.NewSpan(ctx, "GetInfo")
defer span.End()
if id == 100 {
return g.Map{
"id": 100,
"name": "john",
"gender": 1,
}
}
return nil
}
// GetDetail retrieves and returns hard coded user detail for demonstration.
func GetDetail(ctx context.Context, id int) g.Map {
ctx, span := gtrace.NewSpan(ctx, "GetDetail")
defer span.End()
if id == 100 {
return g.Map{
"site": "https://GoFrame.org",
"email": "john@goframe.org",
}
}
return nil
}
// GetScores retrieves and returns hard coded user scores for demonstration.
func GetScores(ctx context.Context, id int) g.Map {
ctx, span := gtrace.NewSpan(ctx, "GetScores")
defer span.End()
if id == 100 {
return g.Map{
"math": 100,
"english": 60,
"chinese": 50,
}
}
return nil
}
该示例代码展示了多层级方法间的链路信息传递,即是把ctx
上下文变量作为第一个方法参数传递即可。在方法内部,我们通过的固定语法来创建/开始一个Span
:
ctx, span := gtrace.NewSpan(ctx, "xxx")
defer span.End()
并通过defer
的方式调用span.End
来结束一个Span
,这样可以很好地记录Span
生命周期(开始和结束)信息,这些信息都将会展示到链路跟踪系统中。其中gtrace.NewSpan
方法的第二个参数spanName
我们直接给定方法的名称即可,这样在链路展示中比较有识别性。
执行完上面的程序后,终端输出:
打开Jaeger UI
: http://localhost:16686/search,可以看到链路追踪的结果:
点击详情可以查看具体信息,包括span
的调用顺序、调用关系,执行时间轴,以及记录一些Attributes
和Events
信息,极大的方便我们定位系统中的异常和发现性能瓶颈:
其中的tracing-inprocess
是我们tracer
的名称,该名称往往是服务名称,由于我们这里只有一个进程和一个tracer
,因此这里只看得到一个服务名称。其中的main
为我们创建的root span
名称,其他的span
为基于该root span
创建的子级span
。由于我们在程序中调用了两次GetUser
方法,因此这里也展示了两次GetUser
方法的调用。每一次GetUser
调用的内部又分别去调用了GetIndo
、GetDetail
、GetScores
三个方法,方法间的调用层级关系展示得非常清晰明了,并且每个方法的调用时长都可以看得到。
关于其中每个span
记录的Tags
和Process
信息其实对应了OpenTelemetry
中的Attributes
和Events
信息,这些信息我们放到后续章节去详细介绍。
本文标题:创新互联GoFrame教程:GoFrame链路跟踪-基本示例
标题URL:http://www.mswzjz.com/qtweb/news46/207346.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联