zipkin 下载
zipkin 下载
前往 zipkin 官网下载最新版的ZipKin Jar包
zipkin 内存存储版 启动
nohup java -jar zipkin-server-1.23.0.jar &
可以 使用命令 lsof -i:9411
在终端 查看是否启动成功
至浏览器 输入链接 打开 zipkin 网页
zipkin 配置 MySQL
- 需要本机启动MySQL 服务 service mysqld start
- 在 MySQL 中建表
CREATE SCHEMA `wjb_monitor` ;
CREATE TABLE IF NOT EXISTS zipkin_spans (
`trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
`trace_id` BIGINT NOT NULL,
`id` BIGINT NOT NULL,
`name` VARCHAR(255) NOT NULL,
`parent_id` BIGINT,
`debug` BIT(1),
`start_ts` BIGINT COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL',
`duration` BIGINT COMMENT 'Span.duration(): micros used for minDuration and maxDuration query'
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
ALTER TABLE zipkin_spans ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `id`) COMMENT 'ignore insert on duplicate';
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`, `id`) COMMENT 'for joining with zipkin_annotations';
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTracesByIds';
ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames';
ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering and range';
CREATE TABLE IF NOT EXISTS zipkin_annotations (
`trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
`trace_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.trace_id',
`span_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.id',
`a_key` VARCHAR(255) NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1',
`a_value` BLOB COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB',
`a_type` INT NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation',
`a_timestamp` BIGINT COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp',
`endpoint_ipv4` INT COMMENT 'Null when Binary/Annotation.endpoint is null',
`endpoint_ipv6` BINARY(16) COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address',
`endpoint_port` SMALLINT COMMENT 'Null when Binary/Annotation.endpoint is null',
`endpoint_service_name` VARCHAR(255) COMMENT 'Null when Binary/Annotation.endpoint is null'
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`, `span_id`) COMMENT 'for joining with zipkin_spans';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTraces/ByIds';
ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames';
ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for getTraces';
ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'for dependencies job';
CREATE TABLE IF NOT EXISTS zipkin_dependencies (
`day` DATE NOT NULL,
`parent` VARCHAR(255) NOT NULL,
`child` VARCHAR(255) NOT NULL,
`call_count` BIGINT
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`, `parent`, `child`);
zipkin MYSQL 存储版 启动
STORAGE_TYPE=mysql MYSQL_HOST=127.0.0.1 MYSQL_TCP_PORT=3306 MYSQL_DB=wjb_monitor MYSQL_USER=root MYSQL_PASS=o nohup java -jar zipkin-server-1.23.0.jar &
可以 使用命令 lsof -i:9411
在终端 查看是否启动成功
至浏览器 输入链接 打开 zipkin 网页
zipkin 开发过程
添加依赖项
<dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-core</artifactId> <version>3.11.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>19.0</version> </dependency> <dependency> <groupId>com.google.auto.value</groupId> <artifactId>auto-value</artifactId> <version>1.1</version> </dependency> <!-- yaml config --> <dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>1.11</version> </dependency> <!-- for kafka collector --> <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>0.10.0.0</version> <scope>provided</scope> </dependency>
在工程 resources/META-INF/dubbo 文件夹下,新建文件
com.alibaba.dubbo.rpc.Filter
主要用于 dubbo在调用中产生拦截 文件内容如下:TraceConsumerFilter=com.monitor.client.trace.filter.TraceConsumerFilter TraceProviderFilter=com.monitor.client.trace.filter.TraceProviderFilter
第二步 文件中所对应的三个核心类 分别是 TraceFilter、TraceConsumerFilter、TraceProviderFilter,其作用是在调用中产生拦截。 在这三个核心类中,都会读取 resources/trace.yml 文件。 文件中 主要配置 此工程在 zipkin 中的服务器信息,名称,作者,以及调用链的URL 根信息。
ZipKin 的数据模型
- Trace:标识整个请求链,即一些列Span的组合。其自身的ID将贯穿整个调用链,其中的每个Span都必须携带这个traceId,因此traceId将在整个调用链中传递;
- Span: 标识一次分布式调用,其自身包含了id,parentId(指向上级Span的id), traceIds,服务名称等重要属性,其应尽量保持精简;
- annotation:包括一个值,时间戳,主机名(留痕迹)。
- traceId:就是一个全局的跟踪ID,是跟踪的入口点,根据需求来决定在哪生成traceId。比如一个http请求,首先入口是web应用,一般看完整的调用链这里自然是traceId生成的起点,结束点在web请求返回点。
- spanId:这是下一层的请求跟踪ID,这个也根据自己的需求,比如认为一次rpc,一次sql执行等都可以是一个span。一个traceId包含一个以上的spanId。
- parentId:上一次请求跟踪ID,用来将前后的请求串联起来。
- cs:客户端发起请求的时间,比如dubbo调用端开始执行远程调用之前。
- cr:客户端收到处理完请求的时间。
- ss:服务端处理完逻辑的时间。
- sr:服务端收到调用端请求的时间。
- 客户端调用时间=cr-cs
- 服务端处理时间=sr-ss
- 工程其余的类目都是围绕着这三个核心类去操作的。 在进行 Http 请求的时候,通过TraceAgent类进行生成一个调用控制器,由于考虑到会扩展到多种日志收集器,所以用代理做封装,其核心功能就是将数据通过http传送到zipkin,由此在每次调用开始时生成一个调用关系模型,存放进 TraceContext 中,在
TraceConsumerFilter
的invke
方法中 判断TraceContext.getTraceId() == null
来判断 是否为 根调用。
zipkin 集成进工程
pom.xml 文件中添加如下依赖:
<dependency> <groupId>wangjubao.monitoring</groupId> <artifactId>monitor-client</artifactId> <version>1.3-SNAPSHOT</version> </dependency>
spring xml 配置文件(dubbo 配置)
添加以下代码:
<import resource="classpath*:spring/spring_monitor_client.xml"/> <dubbo:application name="test_consumer" /> <dubbo:registry address="zookeeper://106.15.46.228:2181" protocol="zookeeper"/>
删除以下代码:(在以上文件中集中配置)
<dubbo:provider timeout="10000" retries="3" …… /> <dubbo:consumer …… /> <dubbo:monitor protocol="registry"/>
在 resources 文件夹下, 新建
trace.yml
文件### 以下为Provider Consumer Web 层 工程都需要配置的基础信息 # 此项目是否需要进行调用链记录 enable: true # 调用链服务器地址(一般与监控地址相同,端口为 9411, 正式工程 配置地址为:121.40.32.163:9411 server: 'localhost:9411' # 此 APP 工程名 - 请保持与 Dubbo 服务名相同,以方便监控 name: 'myapp' # 此APP 负责人 - 请填写这个服务的负责人 owner: 'kevin' ### 以下为 Web 层 工程需要配置的独立基础信息 # 调用链定义需要的跟踪的请求节点 points: - key: user.login #节点名 pattern: ^/api/users/.* #节点路径 desc: 用户登陆 #节点描述 - key: order.create pattern: ^/.* #此 web 工程下所有请求全部跟踪 desc: 用户下单
web 工程中还需在 web.xml 中配置一下如下filter,用于拦截生成调用链
<filter> <filter-name>traceFilter</filter-name> <filter-class>com.monitor.client.trace.filter.TraceFilter</filter-class> </filter> <filter-mapping> <filter-name>traceFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
summary: 配置文件中 关于dubbo 的配置 除了 服务消费者和提供者Bean的配置 以及 工程监控导入配置的代码,仅保留以下两行代码
```xml <!-- Dubbo通用配置以及监控配置 --> <import resource="classpath*:spring/spring_monitor_client.xml"/> <!-- 提供方应用信息,用于计算依赖关系 --> <dubbo:application name="test_provider_pro" /> <dubbo:registry address="zookeeper://106.15.46.228:2181" protocol="zookeeper"/> ```
查看 zipkin
在 浏览器 输入 http://localhost:9411 如果产生调用,即可查看到调用链的信息。
调用链流程解读
- 如上所述,监控的调用链模块分为三个核心类 TraceFilter、TraceConsumerFilter、TraceProviderFilter。
- TractFilter 可以在Web应用层初始化整个调用链,包括traceId,rootSpanId等重要信息,对于ID,我们根据自己的规则去生成。
- 由于需要在整个请求链中共享traceId及父级spanId,因此将其放入ThreadLocal上下文。既然已经初始化了rootSpan,接下来我们还需要将这里的traceId和spanId传递给后端的dubbo服务,这可以通过在dubbo提供的Filter(TraceConsumerFilter、TraceProviderFilter)中的attachment中设置。
- 这样在provider端就能获取到当前traceId和spanId,由于在provider端仍然还有可能调用其他dubbo服务,因此provider端接收到consumer传递的traceId和spanId后,还需要将其设置在ThreadLocal中,以便后续的dubbo服务调用中也需要传递traceId和spanId。
- 这样,当在前端发起请求后,则会在跟踪服务器生成对应的跟踪记录
异常监控接入流程
- pom.xml 中引入 网聚宝 监控客户端,如果引用过了,请注意重新build下。
<dependency> <groupId>wangjubao.monitoring</groupId> <artifactId>monitor-client</artifactId> <version>1.3-SNAPSHOT</version> </dependency>
log4j.xml 中加入如下 配置
<!-- 阿里云监控日志 --> <appender name="loghub" class="com.aliyun.openservices.log.log4j.LoghubAppender"> <!-- 注意:以下 ${} 引用变量的值 请找架构组相关人员提供 --> <param name="projectName" value="${projectName}" /> <param name="logstore" value="${logstore}" /> <param name="endpoint" value="${endpoint}" /> <param name="accessKeyId" value="${accessKeyId}"/> <param name="accessKey" value="${accessKey}"/> <param name="topic" value="${your dubbo application name}"/> <param name="packageTimeoutInMS" value="3000"/> <param name="logsCountPerPackage" value="4096"/> <param name="logsBytesPerPackage" value="5242880"/> <param name="memPoolSizeInByte" value="1048576000"/> <param name="ioThreadsCount" value="1"/> <param name="timeFormat" value="yyyy-MM-dd HH:mm:ss"/> <param name="timeZone" value="GMT+8"/> </appender> <logger name="loghub" additivity="false"> <level value="INFO" /> <appender-ref ref="loghub" /> </logger> <root> <level value="WARN" /> <appender-ref ref="loghub" /> </root>
- 在 服务启动的 main 函数中第一行调用如下方法
ExceptionHandler.startupExcetpionHandler();
发布提交代码监控接入流程
- code.aliyun.com 对应的 Git 项目中,将 网聚宝公司账户 加入此项目(如使用公司账户创建项目的,忽略此条)
- code.aliyun.com 对应的 Git 项目中,打开侧边栏 Settings - WebHooks ,添加以下 URL(IP 地址请架构组相关人员提供),点击
ADD WEB HOOK
。http://<!--IP Address-->/monitor-server-1.0-SNAPSHOT/monitor/devops/postGitWebHook
数据库监控接入流程
- pom.xml 中引入 网聚宝 监控客户端,如果引用过了,请注意重新build下。
<dependency> <groupId>wangjubao.monitoring</groupId> <artifactId>monitor-client</artifactId> <version>1.3-SNAPSHOT</version> </dependency>
mybatis-config.xml 中添加
<configuration> <plugins> ... <plugin interceptor="com.monitor.client.database.SqlCostInterceptor" /> </plugins> </configuration>
log4j.xml 中加入如下 配置 (ps. 如果在异常接入中已添加,请忽略)
<!-- 阿里云监控日志 --> <appender name="loghub" class="com.aliyun.openservices.log.log4j.LoghubAppender"> <!-- 注意:以下 ${} 引用变量的值 请找架构组相关人员提供 --> <param name="projectName" value="${projectName}" /> <param name="logstore" value="${logstore}" /> <param name="endpoint" value="${endpoint}" /> <param name="accessKeyId" value="${accessKeyId}"/> <param name="accessKey" value="${accessKey}"/> <param name="topic" value="${your dubbo application name}"/> <param name="packageTimeoutInMS" value="3000"/> <param name="logsCountPerPackage" value="4096"/> <param name="logsBytesPerPackage" value="5242880"/> <param name="memPoolSizeInByte" value="1048576000"/> <param name="ioThreadsCount" value="1"/> <param name="timeFormat" value="yyyy-MM-dd HH:mm:ss"/> <param name="timeZone" value="GMT+8"/> </appender> <logger name="loghub" additivity="false"> <level value="INFO" /> <appender-ref ref="loghub" /> </logger> <root> <level value="WARN" /> <appender-ref ref="loghub" /> </root>
- [如已经配置发布提交代码监控,请忽略4 、 5 两条配置]code.aliyun.com 对应的 Git 项目中,将 网聚宝公司账户 加入此项目(如使用公司账户创建项目的,忽略此条)
- code.aliyun.com 对应的 Git 项目中,打开侧边栏 Settings - WebHooks ,添加以下 URL(IP 地址请架构组相关人员提供),点击
ADD WEB HOOK
。http://<!--IP Address-->/monitor-server-1.0-SNAPSHOT/monitor/devops/postGitWebHook