-
- 一、设计依据
-
二、设计思路
- 1、核心数据模型字段
- 2、参数透传说明
- 3、日志格式(举例子)
- 4、链路性能指标(处理时间)
-
三、先决条件
- 1、Web Servlet Filter 调用链开始
- 2、Dubbo作为RPC 调用链跟踪
- 3、DB调用跟踪
- 4、Cache调用跟踪
- 5、MQ调用跟踪
-
四、系统对接步骤
- 1、引入相关JAR包
- 2、定义logger
- 3、引入拦截调用链
-
五、遗留问题
分布式跟踪系统设计
想知道系统哪个地方处理慢么?想优化系统,但不知哪块慢?每个调用耗时多少?xxx,还有N多疑问。好吧,我们先从最简单的跟踪做起。
一、设计依据
谷歌,DAPPER论文。中文翻译链接http://bigbully.github.io/Dapper-translation/ 下面是开头部分。
(当代的互联网的服务,通常都是用复杂的、大规模分布式集群来实现的。互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。因此,就需要一些可以帮助理解系统行为、用于分析性能问题的工具。
Dapper--Google生产环境下的分布式跟踪系统,应运而生。那么我们就来介绍一个大规模集群的跟踪系统,它是如何满足一个低损耗、应用透明的、大范围部署这三个需求的。当然Dapper设计之初,参考了一些其他分布式系统的理念,尤其是Magpie和X-Trace,但是我们之所以能成功应用在生产环境上,还需要一些画龙点睛之笔,例如采样率的使用以及把代码植入限制在一小部分公共库的改造上。)
二、设计思路
系统是演进的。先满足最小化跟踪。先满足核心调用链跟踪。并只做一件事,如实记录发生时间。
1、核心数据模型字段
tracerNo:全栈跟踪唯一ID(UUID)
serialNo:当前节点跟踪序号(比如上述图的0.1.1等)
上述两个参数为透传系统参数,后续嵌入跟踪系统,需要设置此参数以便处理。
2、参数透传说明
透传需要传递最后一个节点的上述两个字段参数,保证后续serialNo的正确性,连续性。
3、日志格式(举例子)
iboxpay_tracer_log|ad7d8e36-f032-4e63-9eb7-b49ef39a2c29|0|WEB|cash_box|http://172.30.0.81:8080/TestRedis/session|1449621713215|1449621716120|
iboxpay_tracer_log|ad7d8e36-f032-4e63-9eb7-b49ef39a2c29|0.1|DUBBO_C|test-redis|null|1449621715234|1449621716119|
iboxpay_tracer_log|ad7d8e36-f032-4e63-9eb7-b49ef39a2c29|0.1|DUBBO_S|test_Tracer|null|1449650158205|1449650158206|
即按下述格式:iboxpay_tracer_log|tracerNo|serialNo|tracerType|name|url|startTime|endTime|params
解释如下:iboxpay_tracer_log|唯一跟踪ID|当前节点序号|跟踪类型|名称|URL|开始时间|结束时间|相关附带参数
其中iboxpay_tracer_log 为大数据平台标识头。params 为添加进去的附带参数。
4、链路性能指标(处理时间)
整条调用链跟踪下来,计算总耗时:
1、300毫秒以下正常
2、300—500毫秒(语句调优)
3、500—1000毫秒(模块重构)
4、1000—3000毫秒(系统重构)
5、3000毫秒以上(考虑重写)
三、先决条件
JAVA语言系统。后续扩展其他语言系统。
1、Web Servlet Filter 调用链开始
基础库已实现。
2、Dubbo作为RPC 调用链跟踪
基础库已实现。
3、DB调用跟踪
(主流两种ORM框架实现,Hibernate,Mybatis;其他暂未)
4、Cache调用跟踪
(待实现)
5、MQ调用跟踪
(待实现)
四、系统对接步骤
1、引入相关JAR包
a>大数据平台日志接入JAR包。详见(大数据平台日志接入指南)
1
2
3
4
5
6
7
8
9
10
|
<
dependency
>
<
groupId
>com.iboxpay</
groupId
>
<
artifactId
>logback-flume-appender</
artifactId
>
<
version
>1.0.0</
version
>
</
dependency
>
<
dependency
>
<
groupId
>org.apache.flume</
groupId
>
<
artifactId
>flume-ng-sdk</
artifactId
>
<
version
>1.6.0</
version
>
</
dependency
>
|
b>基础库相关JAR包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<
dependency
>
<
groupId
>com.iboxpay.base</
groupId
>
<
artifactId
>iboxpay-base-common</
artifactId
>
<
version
>0.0.1-SNAPSHOT</
version
>
</
dependency
>
<
dependency
>
<
groupId
>com.iboxpay.base</
groupId
>
<
artifactId
>iboxpay-base-dao</
artifactId
>
<
version
>0.0.1-SNAPSHOT</
version
>
</
dependency
>
<
dependency
>
<
groupId
>com.iboxpay.base</
groupId
>
<
artifactId
>iboxpay-base-web</
artifactId
>
<
version
>0.0.1-SNAPSHOT</
version
>
</
dependency
>
|
其中,iboxpay-base-common 为必须依赖包,其他两个根据跟踪类型,选择性加入。
2、定义logger
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<
appender
name
=
"log_to_flume_tracer"
class
=
"com.gilt.logback.flume.FlumeLogstashV1Appender"
>
<
flumeAgents
>
172.16.4.145:5070
</
flumeAgents
>
<
flumeProperties
>
connect-timeout=4000;
request-timeout=8000
</
flumeProperties
>
<
reporterMaxThreadPoolSize
>6</
reporterMaxThreadPoolSize
>
<
reporterMaxQueueSize
>100</
reporterMaxQueueSize
>
<
batchSize
>100</
batchSize
>
<
reportingWindow
>10</
reportingWindow
>
<
additionalAvroHeaders
>
logType=log-type
</
additionalAvroHeaders
>
<
application
>smapleapp</
application
>
<
layout
class
=
"ch.qos.logback.classic.PatternLayout"
>
<
pattern
>%msg%n</
pattern
>
</
layout
>
</
appender
>
<
logger
name
=
"com.iboxpay.base.tracer.Node"
level
=
"INFO"
additivity
=
"false"
>
<
appender-ref
ref
=
"log-to-flume-tracer"
/>
</
logger
>
|
3、引入拦截调用链
1、引入filter,web.xml文件中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<
filter
>
<
filter-name
>tracerFilter</
filter-name
>
<
filter-class
>com.iboxpay.base.web.filter.TracerFilter</
filter-class
>
<
init-param
>
<
param-name
>appName</
param-name
>
<
param-value
>cash_box</
param-value
>
</
init-param
>
<
init-param
>
<
param-name
>staticResourceSuffix</
param-name
>
<
param-value
>js,css,png,jpg,jpeg,gif</
param-value
>
</
init-param
>
</
filter
>
<
filter-mapping
>
<
filter-name
>tracerFilter</
filter-name
>
<
url-pattern
>/*</
url-pattern
>
</
filter-mapping
>
|
2、引入dubbo,filter;一般在application-dubbo-client.xml或是application-dubbo-server.xml;找到定义的地方即可。
1
2
3
4
|
<
dubbo:consumer
filter
=
"tracerClientFilter"
/>
<
dubbo:provider
filter
=
"tracerServerFilter"
/>
|
3、引入ORM,Interceptor
a>Hibernate引入下述配置(一般在hibernate-config.xml)
1
2
3
4
5
6
7
8
|
<
bean
id
=
"tracerInterceptor"
class
=
"com.iboxpay.base.dao.hibernate.interceptor.TracerInterceptor"
/>
<
bean
id
=
"sessionFactory"
class
=
"org.springframework.orm.hibernate4.LocalSessionFactoryBean"
>
<
property
name
=
"dataSource"
>
<
ref
local
=
"dataSource_jdbc"
/>
</
property
>
<
property
name
=
"entityInterceptor"
ref
=
"tracerInterceptor"
/>
..............
</
bean
>
|
b>Mybatis引入下述配置(一般在mybatis-config.xml)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<
configuration
>
<
settings
>
<
setting
name
=
"lazyLoadingEnabled"
value
=
"false"
/>
<
setting
name
=
"jdbcTypeForNull"
value
=
"NULL"
/>
<
setting
name
=
"defaultStatementTimeout"
value
=
"30"
/>
</
settings
>
<
plugins
>
<
plugin
interceptor
=
"com.iboxpay.base.dao.mybatis.interceptor.TracerInterceptor"
>
</
plugin
>
</
plugins
>
</
configuration
>
|
五、遗留问题
1、异步传递
异步请求转发调用跟踪;
2、并发访问
并发访问跟踪节点对象等;
3、其他