‘壹’ idea怎么查看jar里的类调用链
你要有这个jar对应的sources.jar才行,我这里以google的guava.jar为例,在maven仓库中,有:
对于没有相应的sources.jar的jar包,则看不到,jar包对应的sources.jar一般大公司的都会一起发布在网上。
‘贰’ tt函数调用链怎么用
载入时动态链接(load-time dynamic linking),模块非常明确调用某个导出函数,使得他们就像本地函数一样。这需要链接时链接那些函数所在DLL的导入库,导入库向系统提供了载入DLL时所需的信息及DLL函数定位。
运行时动态链接(run-time dynamic linking),运行时可以通过LoadLibrary或LoadLibraryEx函数载入DLL。DLL载入后,模块可以通过调用GetProcAddress获取DLL函数的出口地址,然后就可以通过返回的函数指针调用DLL函数了。如此即可避免导入库文件了。
调用链有头有尾执行从前往后,可以用一条线来表示,为简化用一条直线表示。调用链的头和尾是相对的,取决我们的观察需要。一条链可以一分为二分别进行分析。
‘叁’ 深入探究ZIPKIN调用链跟踪——拓扑Dependencies篇
Zipkin的拓扑服务zipkin-dependencies是作为zipkin的一个独立的离线服务,也就是说,只启动zipkin服务,是没法看到拓扑的,还需要自己离线启动zipkin-dependencues服务。
其中ES配置参数如下:
Zipkin出了支持elasticsearch存储,还有mysql,cassard,详细配置信息请看 源码Readme
1、图中线条说明
服务之间的线条,遵循以下原则:
2、主调被调次数说明
点开每一个服务,可以看到主调被调,比如我在拓扑图中点击
某个服务,可以与此服务有直接调用关系的服务有哪些,效果如下:
其中Uses by表示此服务作为被调服务,被哪些服务调用了;Uses表示此服务调用了哪些其他服务。
在上面的图中点击某个主调或被调服务,即可看到具体的调用次数,以及失败次数,效果如下:
通过拓扑图,宏观上,我们可以快速了解服务之间的调用关系,同时也可以知道哪些服务间调用有问题,且可以知道出现问题的一个量级是多少(失败数,调用总数)。
Zipkin拓扑denpendencies是基于上报的链路span数据再次构建出的描述链路拓扑的一种新的数据结构。
构建链路的第一步就是读取Span数据。Zipkin外部数据源支持三种,分别是Mysql,Cassandra,Elasticsearch,因此构建拓扑时,将从这三种数据源中读取Span数据。
读取Span数据源后,需要对其处理,计算出链路的拓扑。因为Span的数据量很大,普通程序计算处理无法完成任务,因此需要用到大数据框架。Zipkin官方选用的是Spark框架。Spark对Span数据进行处理,最后生成拓扑数据DenpendencyLink,然后持久化到存储中。
前端请求拓扑(DependencyLink)时,即按照查询条件,查询已经持久化后的DependencyLink,然后经过UI渲染,进行页面展示。
启动Zipkin-dependencies服务时,会传入几个参数,分别是时间day和存储类型storageType。Zipkin-dependencies服务是以天为单位进行建立拓扑,因此day将决定建立那一天的拓扑;而storageType将决定从什么储存中读取数据。
1、获取日期:
2、获取存储类型:
3、根据不同的存储启动不同的jOb:
不同的存储会定义不同Job类,因此有CassandraDependenciesJob,MySQLDependenciesJob,MySQLDependenciesJob,ElasticsearchDependenciesJob。 不同的Job主要区别在于读取Span的方式不同,而Spark对Span进行处理计算的方式基本都是相同的。 本文主要分析ElasticsearchJOb。
Job中主要逻辑都在run方法中,ElastichserchJob的Run方法定义如下:
主要步骤如下:
1、首先通过Spark的配置属性Conf,创建一个JavaSparkContext对象sc:
2、然后读取elasticsearch span数据源:
3、读取数据源后,就可以对Span进行处理了,首先按照TraceId 进行Group分组:
其中JSON_TRACE_ID Function定义如下:
4、Span按照TraceId Group 分组后,接着对Span进行处理, 创建出DenpendencyLink。
5、上面方法最终返回的是个Map类型,将其转化为pari类型,再对其进行一个receByKey操作:
6、Spark对Span的计算操作到这儿基本就完成了,最后将DependencyLink转化为Jso形式:
7、对于计算好的拓扑Links,将其持久化到Elasticsearch中:
整个过程到此完毕,其中最复杂也是最核心的逻辑就是计算出链路拓扑Denpendencylink,此步骤在Function (logInitializer, decoder)中。接下来详细分析完成的工作。
首先介绍一下DenpendencyLink数据结构。DenpendencyLink就是最终与页面交互的拓扑结构数据单元,字端有:
DenpendencyLink类定义如下:
类的定义如下:
其中call方法中,首先完成对同一TraceId的Span解码:
然后,通过DependencyLinker类构造出DependendyLink,首先构造一个SpanNode Tree:
然后利用深度优先遍历方法遍历整个,统计出CallCounts和errorCounts:
其中callCounts和errorCounts定义如下:
最后,再通过callCounts和errorCounts生成List<DependencyLink>:
这样,最终构建出了DependencyLink。
本文为我的调用链系列文章之一,已有文章如下:
祝大家工作顺利,天天开心!