Zipkin实现分布式调用链监控实践

本人所在的产品线是公司统一的构建管理平台,该平台采用了微服务的构造,跟微服务自身的通病一样,服务数量多了之后,存在这样一些问题:

  1. 接口超时或者调用失败后,无法知道具体是那个下游接口超时
  2. 接口响应慢后,怎么去了解是那个服务的那个方法调用耗时较长
  3. 对前端暴露的接口,响应时间对用户的体验比较敏感,怎么监控到系统中存在的慢接口,进而优化

微服务发展到今天,业界对这类问题已经有很多通用的解决方案,最早的比较Google公司发表的Dapper应该算得上是始祖了吧。 我们也不想重复造轮子,比较了一些方案,综合对埋点语言的支持(Golang + Java),Zipkin进行最终的方案。

安装Zipkin Server

Zipkin Server主要包含三个Components:

  • Zipkin UI
    在这里插入图片描述

  • Zipkin Server: 应用的埋点配置需要将Span, trace的数据发到这里

  • Span Storage: Zipkin Server默认后端使用内存存储, 数据大的话似乎只可以存储几个小时的数据,而且搜索的性能也会有问题,Zipkin支持较多其它的Storage, 比如Mysql, ElasticSearch。

为了简化这些组件的安装,直接采用了官方提供的Docker Image,参数通过环境变量来指定。

  1. 启动ElasticSearch6, 官方建议先调高系统的虚拟内存,不然会启动失败

    docker run -d -p 9200:9200 zipkin-elasticsearch6:latest
    
  2. 启动Zipkin Server (含UI)

    docker run -d -p 9411:9411 -e STORAGE_TYPE=elasticsearch -e ES_HOSTS=192.168.10.10:9200 zipkin:latest
    

一切就绪后,就可以通过http://< ip-address >:9411/zipkin/访问了。

应用埋点

埋点就是通过SDK将业务的接口数据生成trace信息,再由SDK通过http/消息将trace发送到后端的Zipkin服务。

前面提到选型时主要考虑了语言的兼容性,我们分别看一下Java与Go的埋点,以及其中一些比较tricky的配置。

JAVA 应用埋点

Zipkin官方对Java应用的埋点推荐提供的是Brave,它可以兼容Zipkin后端trace数据的格式,由于项目本身是Springboot的框架搭建的,因些我们采用的是对Brave封装了多一层的Spring Sleuth

在工程中添加下面的依赖:

compile('org.springframework.cloud:spring-cloud-starter-zipkin:1.3.3.RELEASE')
compile('org.springframework.boot:spring-boot-starter-aop:1.5.6.RELEASE')

埋点配置

埋点的配置主要包含下面常用的配置项 (注意你使用的版本,可能配置项名称会有些差异):

配置项 配置项解释
application.name 应用的名称,在Zipkin UI过滤时对应为 serviceName
sleuth.enabled 是否启动sleuth,只有启用后才会收集trace
zipkin.baseUrl Zipkin Server对应的链接,需要将trace的数据通过http接口发送给它
sleuth.sampler.percentage 设置Span的采样率,默认似乎是0,初次使用会比较坑,在UI上看不到收集的Span数据
sleuth.web.skip-pattern 排除掉一些不用监控的服务入口,比如 /health_check

下面是一个具体的配置例子:

spring:
  profiles: staging
  application:
    name: neith-gw
  zipkin:
    baseUrl: ${
   ZIPKIN_SERVER:http://192.168.10.10:9411}
  sleuth:
    sampler:
      percentage: ${
   SLEUTH_SAMPLE_RATE:1.0}
    web:
      client:
        enabled: true
      skip-pattern: /prometheus|/_health_check|/ws/.*|/swagger.*|.*\\.ttf|/v2/api-docs|.*\\.png|.*\.css|.*\.js|.*\.html|/favicon.ico
    enabled: ${
   SLEUTH_ENABLE:true}

假如配置没问题,你应该可以看到下面的启动日志:

16:24:48.713 [main]  INFO  o.s.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.cloud.sleuth.annotation.SleuthAnnotationAutoConfiguration' of type [org.springframework.cloud.sleuth.annotation.SleuthAnnotationAutoConfiguration$$EnhancerBySpringCGLIB$$5766f243] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

Http客户端埋点

由于Sleuth的埋点是通过AOP代理的,而Spring的AOP默认又是基于Java Bean的proxy对象,即在调用target bean对应的方法前,先调用proxy对象的方法,并在proxy方法实现埋点的功能。

假如你的项目跟我一样没有使用Spring的RestTemplate类(并且必须是Bean,不能通过New生成实例),而是使用了第三方的http client包,为了埋点能工作以及减少埋点对代码的侵入,需要一些小技巧,在我的项目是这样做的:

  • 首先需要创建一个新的Bean实现http的发送接口,例如

    @Component
    public class HttpSender {
         
    
        public HttpResponse send(HttpRequest request) {
         
            return request.send();
        }
    }
    
  • 然后将原来的使用三方http client接口的调用替换为新的接口

    	...
        @Autowired
        private HttpSender httpSender;
    
        @Override
        public GitlabCommit findCommitByRef(String gitRepo, String refName) {
         
            HttpResponse response = httpSender.send(HttpRequest.get(GITLAB_COMMIT_URL)
                    .query("branch_name", refName)
                    .query("token", token)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值