技术分享 | jaeger链路日志实现

源宝导读:随着企业应用越来越复杂,内部的调用链条越来越长,性能问题也变得越来越难以定位和排查,为了应对此问题,我们在移动平台中引入了“jaeger调用链追踪工具”,帮助我们高效定位云端服务的性能问题。本文将分享我们相关的技术实践。

一、背景

    大家好,很幸运代表团队和大家分享一下,天际-移动平台团队在实现分布式链路日志追踪过程的心路历程。移动应用的后台服务,其内部调用链路往往很复杂,一旦发现性能问题,很难快速精准的定位,严重影响研发小伙伴们的幸福感。具体问题表现在这几个方面:

  • 容器内日志简单,某些前后端数据不一致导致的的问题无法定位。

  • PaaS小程序微服务化,服务之间调用虽然有严格规定,但是出现问题时还是无法快速定位问题的出处。

  • 测试人员登记bug需要粘贴详细的请求、响应,开发通过创造数据,模拟这个请求来慢慢排查问题所在。

二、技术选型

移动平台中关于PaaS小程序后端的现有架构:

    从上图中可知,我们当前同时支持了PHP、Go、Nodejs三种编程语言构建的应用,如果要做日志的链路追踪,起码需要兼容多编程语言。

    通过分析,我们总结出“日志追踪工具”应满足的条件:

  • 支持多语言。保证PHP、Go、Nodejs都可以接入日志,才能形成完整链路。

  • 一定是无侵入式的。这样在多个服务中埋点比较方便,日志服务升级维护成本也不会高。

  • 对于特定标签的日志可以通过微信、邮箱甚至短信的方式通知到开发或者运维同学。

  • 能够对API接口的性能统计分析。

  • 由于我们使用的阿里云日志,日志服务最好可以将阿里云日志作为数据存储。

三、jaeger工具介绍

3.1、简介

    Jaeger是由Uber开源的分布式追踪系统,一套完整的Jager追踪系统包括Jaeger-client、Jaeger-agent、Jaeger-collector、Database和Jaeger-query UI等基本组件。

3.2、Jaeger的优势

  • 采用Open Tracing标准,支持跨语言。

  • 分布式上下文传播。

  • 分布式是链路追踪。

  • 服务依赖性分析。

  • 性能延迟监控。

3.3、jaeger的技术原理

架构图:

  • jaeger-client:jaeger 的客户端,实现了opentracing协议。

  • jaeger-agent:jaeger-client 的一个代理程序,client将收集到的调用链数据发给agent,然后由agent发给collector。

  • jaeger-collector:负责接收jaeger client或者jaeger agent上报上来的调用链数据,然后做一些校验,比如时间范围是否合法等,最终会经过内部的处理存储到后端存储。后端存储是一个可插拔的组件,Jaeger on Aliyun Log Service 增加了对阿里云日志服务的支持。

  • jaeger-query:专门负责调用链查询的一个服务,有自己独立的UI。

  • spark-job:基于spark的运算任务,可以计算服务的依赖关系,调用次数等。

    说明:其中jaeger-collector和jaeger-query是必须的,其余的都是可选的,我们采用agent上报的方式,让客户端上报日志到agent,以减少部分性能消耗。jaeger-collector支持Aliyun Log Service,也是很好的满足我们要求。

    aliyun-log-jaeger-collector配置表:

3.4、日志

单条链路:

    可以清晰的看到一个请求的发起时间,所经过的服务数量、所调用服务的依赖关系、消耗的时长等信息。

3.5、技术名词解释

  • service:微服务的名称或者标识。

  • operation:一个span的名称,简单易读。

  • span:系统中具有开始时间和执行时长的逻辑运行单元 。具体可以理解为一次方法调用, 一个程序块的调用或者一次RPC/数据库访问。

  • tags:“键值对”形式的tags,一个span可以有多tags,tags是对span的简单注解,不会被子级span继承。tags value 的标准含义看参考https://opentracing.io/ specification/conventions

  • logs:一个span可以有多logs,每一个logs都可以自定名称以及任意大小的存储结构。

  • spanContext:跨进程边界,传递到下级span的状态,每个span都有访问spanContext的方法。当在创建span时,向传输协议Inject(注入)从上级span传输协议中Extract(提取)的spanContext既可。

  • Inject and Extract:spanContext可以通过Injected操作向Carrier增加,或者通过ExtractedCarrier中获取,跨进程通讯数据。通过这种方式,SpanContexts可以跨越进程边界,并提供足够的信息来建立跨进程的span间关系(因此可以实现跨进程连续追踪)。

四、落地应用

4.1、  核心设计思路:

  • 采用jaeger-client上报数据到jaeger-agent,再由jaeger-agent集中处理传输到jaeger-collector,之后jaeger-collector会将合法的数据存储到阿里日志。

  • 之后在我们需要时,可以通过jaeger-query + jaeger-ui来查询日志。

  • 我们采用jaeger的默认方式,将spanContext中跨进程数据(当前只有uber-trace-id)注入到header中,当下游服务在请求header中提取到对应的跨进程数据就会形成一个依赖和链路关系,如果没有就生成一个新的供下游服务发现和关联。

4.2、traceId传递方式

//  上游服务将traceId注入到header中$header = TraceJaeger::inject($header);
// 下游服务解析获取traceId,完成一个请求的传递
$target = [];
foreach (request()->headers->all() as $key => $value) {$target[$key] = Arr::first($value);
}
$spanContext = $this->tracer->extract(TEXT_MAP, $target);

4.3、应用结果

串行

traceId:1660cc5871c2df9e1660cc5871c34a59

并行

traceId:1660d1de34f6c7691660d1de34f5a93b

    以上都是我们实际的调用场景,应用创建的改造前(串行),改造后(并行)。可以很清晰的看到服务之间的调用和所花费的时间。

    我们打开可以看到app-service这个服务被调用的详细信息。包括请求方式、请求数据、响应数据等。

4.4、兼容Go语言

1、go服务gin中间件使用开源框架,代码仓库:https://github.com/yuchanns/bullets

go get -u github.com/yuchanns/bullets

2、中间件使用:

package main
import ("context""github.com/gin-gonic/gin""github.com/yuchanns/bullets/common""github.com/yuchanns/bullets/common/middlewares""os"
)
func main() {g := gin.Default()//服务名serviceName := "openapi-service"//上报agent地址agentAddr := os.Getenv("OPENTRACING_AGENT")//操作前缀operationPrefix := []byte("api-request-")opentracerCloseFunc, opentracerMiddleware, err := middlewares.BuildOpenTracerInterceptor(serviceName, agentAddr, operationPrefix)if err != nil {common.Logger.Error(context.Background(), err)} else {defer opentracerCloseFunc()g.Use(opentracerMiddleware)}
}

3、自定义打tag:

import ("github.com/gin-gonic/gin""github.com/opentracing/opentracing-go""github.com/opentracing/opentracing-go/log""github.com/pkg/errors"
)
func CustomTag(ctx *gin.Context) {if cspan, ok := ctx.Get("tracing-context"); ok {if span, ok := cspan.(opentracing.Span); ok {span.SetTag("error", true)span.LogFields(log.Error(errors.New("err")))span.LogFields(log.String("exampleKey", "stringValue"))}}
}

4.5、兼容PHP语言

1、安装composer包

composer require tracelog/jaeger

2、根目录执行

php artisan vendor:publish

3、选择发布配置⽂件

Tracelog\jaeger\config\jaeger.php文件拷贝到工程项目的config⽬录

4、修改配置⽂件

return['enabled' => env('JAEGER_ENABLED', true), //是否开启'service_name' => env('JAEGER_SERVICE_NAME', env('APP_NAME', 'Laravel')), //服务名称'agent' => [ 'host' => env('OPENTRACING_AGENT','0.0.0.0:6831'), //日志服务代理 地址],'watchers' => [Tracelog\jaeger\watchers\RequestWatcher::class, //请求日志监听Tracelog\jaeger\watchers\FrameworkWatcher::class //项目日志推送]
]

使⽤ jukylin/jaeger-php 直接记录。

参考:https://github.com/jukylin/jaeger-php/blob/master/example/HTTP.php

4.6、集成到Laravel Log

    使⽤框架中Log⻔⾯时,也可以将日志记录到代理。针对当前框架情况修改(添加)/app/Common/StreamHandler ---> Handle

if (config('jaeger.enabled')){$span = TraceJaeger::client()->startSpan($record['message'],['child_of' => TraceJaeger::getRootSpan()]);$span->setTag('log.level', $record['level_name']);$span->log($record['context']);$span->finish();TraceJaeger::client()->flush();
}

说明:对Nodejs的兼容,我们目前正在实现中。

五、总结

    自从链路日志工具上线后,我们排查问题的效率有了很大提升。我们可以直接通过日志定位出有问题的后端服务,通过请求和响应数据快速判断问题原因,极大的提高了工作效率和排查问题的幸福感!

------ END ------

作者简介

智同学: 研发工程师,目前负责天际-移动平台的研发工作。

也许您还想看

记AWSS3在iOS端的一次改造事件

明源云创CI/CD技术演进

微前端架构在容器平台的应用

AI云店小程序演变之路

天眼探针基于rrweb实现前端异常视频录制与回放功能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/303398.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IT资料,重磅来袭!

现在IT行业越来越火爆,技术的更新也越来越快,不好好充实自己的话,就会被淘汰。小编这几年一直有意识地收集IT行业相关的资料,现在已经拥有8G左右的资料,如区块链、Python、大数据、人工智能深度学习等方面的资料&#…

荐书 | 10本书给你计算机大师思维

《黑客与画家》作者:保罗格雷厄姆 / 译者:阮一峰美国互联网界如日中天的教父、哈佛大学离经叛道的博士保罗格雷厄姆著作!一本书,你不曾想到的视角,彻底颠覆你对世界的认识!美国亚马逊、纽约时报超级畅销书&…

php按时间分组的sql语句,(SQL语句)按指定时间段分组统计

---------------------------------------Author : liangCK 梁爱兰--Comment: 小梁 爱 兰儿--Date : 2010-01-02 16:47:10---------------------------------------> 生成测试数据: #tbCREATETABLE#tb(列名1varchar(12),时间datetime)INSERTINTO#tbSELECT03174190188,2009…

NET问答: 说说你对 LookupTKey, TElement 的看法 ?

咨询区 dan-gph&#xff1a;MSND 上对 Lookup 做了如下的解释。Lookup<TKey, TElement> 类似于 Dictionary<TKey,TValue>, 不同点在于 Dictionary<TKey, TValue> 中的key对应的是单个value&#xff0c;而 Lookup<TKey, TElement> 中的 key 对应的是一个…

最多金的编程语言Top10:Python第3,R第10,你猜第1是谁?

导读&#xff1a;如果你还在纠结选哪门编程语言来开启你的码农生涯&#xff0c;这将是你的最佳指南。本文绝非标题党&#xff0c;而是基于大量数据和为期两周的深入探究&#xff0c;在18年初&#xff0c;对IT行业的现状、趋势以及预测进行客观观察&#xff0c;让大家对编程语言…

[转贴]制作windows 2003自动安装盘-集成补丁/Raid及硬件驱动

从事网游行业的工作人员&#xff0c;如果一款游戏上线&#xff0c;必须上大量服务器。用品牌机引导盘装系统&#xff0c;再打个补丁&#xff0c;速度真让人不敢恭维。为了提高效率&#xff0c;就尝试制作一张集成系统补丁/RAID及硬件驱动自动安windows 2003系统盘。下面以品牌机…

4月 .NET 线上 Meetup,快来报名

点击蓝字关注我们.NET 6 preview 2 在3月11日已经发布&#xff0c;.NET 6 将是 .NET Core 3.1 之后的第一个 LTS 版本&#xff0c;也是微软开启全平台统一一个 .NET 计划以来的第一个 LTS 版本&#xff0c;意义不可谓不大&#xff0c;那么 .NET 5/6 又会带来哪些新特性呢&#…

NP完全性理论与近似算法

一、图灵机根据有限状态控制器的当前状态及每个读写头读到的带符号&#xff0c;图灵机的一个计算步可实现下面3个操作之一或全部。改变有限状态控制器中的状态。清除当前读写头下的方格中原有带符号并写上新的带符号。独立地将任何一个或所有读写头&#xff0c;向左移动一个方格…

阿里25k 百度25k,招WPF!

.NET5打通7大开发方向&#xff0c;CLR超高性能&#xff0c;.NET6支持Blazor嵌入WPF&#xff0c;还有MAUI跨平台UI解决方案&#xff0c;都是.NET的利好&#xff0c;也是WPF的利好。牛年跳槽季&#xff0c;.NET在客户端方向一骑绝尘&#xff0c;阿里影视、百度地图&#xff0c;以…

掌握神经网络模型的快捷方式

TensorFlow是Google基于DistBelief进行研发的第二代人工智能学习系统&#xff0c;其命名来源于本身的运行原理。Tensor&#xff08;张量&#xff09;意味着N维数组&#xff0c;Flow&#xff08;流&#xff09;意味着基于数据流图的计算&#xff0c;TensorFlow实际上就是张量从流…

.Net项目模板(Project Template)

你有没有这样的感觉&#xff0c;开启一个新项目时&#xff0c;总是做一堆体力活——项目的结构层次&#xff0c;常用日志库&#xff0c;OpenAPI库&#xff0c;ORM库&#xff0c;的引入&#xff0c;权限认证方式选择添加&#xff0c;配置文件重新归置存放等等。公共框架的部分总…

谈通过测试与失败测试

在软件测试技术中&#xff0c;现有的测试方法、测试技术中均未提及到通过测试与失败测试。 而在实际项目测试过程中&#xff0c;很多项目组却再应用该方法。虽然该方法被采用&#xff0c;但是很多人对通过测试与失败测试理解并不透侧&#xff0c;在实际使用过程中并未按统一的标…

100个微信小程序的源码公开分享

现在微信小程序越来越火&#xff0c;小编一直有意识地收集微信小程序源码&#xff0c;至今已经拥有100个小程序的源码&#xff0c;有gank、LOL战绩查询、百度小说、豆瓣电影、手势解锁等。现在&#xff0c;小编准备将这些资料免费分享给大家&#xff01;gankLOL战绩查询百度小说…

家里在一二线城市有很多套房是什么体验?答案太颠覆!

作者&#xff1a;匿名来源&#xff1a;知乎&#xff08;图片&#xff1a;网络&#xff09;“家里在一二线城市有很多套房是怎么的一种体验&#xff1f;”这是知乎上一个浏览超600万的话题。其中一个答案非常颠覆&#xff0c;获得高赞。作者的观点是否正确见仁见智&#xff0c;但…

希尔排序听起来有点难,其实很简单

前言直接插入排序当待排序数据的顺序和期望排序结果相反时&#xff0c;排序效率是最差的&#xff1b;上次聊到的折半插入排序只是减少有序列表的比较次数&#xff0c;而对于整体数据遍历次数还是没有得到优化&#xff1b;接下来要说的希尔排序就是针对整体数据进行优化&#xf…

等我敲完这行代码,就和你离婚!

工作是高端大气上档次&#xff0c;工资是低调奢华接地气&#xff01;我们叫做“程序猿”&#xff0c;也叫“攻城狮”&#xff01;但是往往城还没攻下来&#xff0c;我们的头发就先掉下来&#xff01;我们最喜欢听的一句话就是☟段子一“等我敲完这行代码&#xff0c;就和你离婚…

深夜,学妹遇到了数据分析师生涯的第一个疑问

大家好&#xff0c;我是大鹏&#xff0c;目前是一名数据分析师。自从上次学妹深夜给我发微信&#xff0c;询问数据分析师招聘要求和需要掌握的技能&#xff0c;已经过去2个月了。直到昨天&#xff0c;我再次收到了学妹的召唤&#xff1a;当天深夜 学妹深夜求助&#xff0c;定是…

你知道WPF与WinForms的区别吗?

介绍WPF的缩写指微软的Windows Presentation Foundation&#xff0c;而WinForms是Windows Forms Applications的简单组合。这两个都是微软的Windows应用程序图形用户界面&#xff0c;开发人员可以使用它们来开发Windows桌面应用程序。本文重点介绍两种开发Windows桌面应用程序的…

一起谈.NET技术,发布NGuestBook(一个基于.NET平台的分层架构留言本小系统)

发布NGuestBook的动机说明 大约在半年前&#xff0c;我在博客上发表了一个系列文章&#xff1a;《基于.NET平台的分层架构实战》。当时在讲解过程中用到了一个叫NGuestBook的案例&#xff0c;在那以后&#xff0c;有很多朋友留言或发E-mail希望能得到NGuestBook的完整源代…

当Java、C++、Python等编程语言都变成妹子。。。

试想一下&#xff0c;当Java、C、Python、Ruby、PHP、C#、JS等编程语言变成了动漫人物会是怎样的一幅场景呢&#xff1f;下面就一起看看在日本作家渡辺将人的笔下&#xff0c;各种编程语言都是哪类“美女”的吧&#xff01;Java犹如宫泽贤治的《不畏风雨》中出现的、性格木讷的…