Java微服务-第三节 链路追踪组件Sleuth&Zipkin、分布式配置中心Config、消息总线Bus

链路追踪组件Sleuth&Zipkin

概念

  1. 为什么需要链路追踪
    1. 微服务架构是一个分布式架构,它按业务划分服务单元,一个分布式系统往往有很多个服务单元。由于服务单元数量众多,业务的复杂性,如果出现了错误和异常,很难去定位。主要体现在,一个请求可能需要调用很多个服务,而内部服务的调用复杂性,决定了问题难以定位。所以微服务架构中,必须实现分布式链路追踪,去跟进一个请求到底有哪些服务参与,参与的顺序又是怎样的,从而达到每个请求的步骤清晰可见,出了问题,很快定位。
    2. 在微服务系统中,一个来自用户的请求,请求先达到前端A(如前端界面),然后通过远程调用,达到系统的中间件B、C(如负载均衡、网关等),最后达到后端服务D、E,后端经过一系列的业务逻辑计算最后将数据返回给用户。对于这样一个请求,经历了这么多个服务,怎么样将它的请求过程的数据记录下来呢?这就需要用到服务链路追踪。
  2. 什么叫埋点
    1. 所谓埋点就是在应用中特定的流程收集一些信息,用来跟踪应用使用的状况,后续用来进一步优化产品或是提供运营的数据支撑,包括访问数(Visits),访客数(Visitor),停留时长(Time On Site),页面浏览数(Page Views)和跳出率(Bounce Rate)。这样的信息收集可以大致分为两种:页面统计(track this virtual page view),统计操作行为(track this button by an event)。

集成链路追踪组件Sleuth

  1. 在product-server和order-server中添加sleuth依赖

     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-sleuth</artifactId>
     </dependency>
    
  2. 在需要写日志的类上贴@Slf4j,然后再order-server,product-server中打印日志。

     log.info("调用商品服务feign接口");
     //这样打印出的日志就会新增访问节点的唯一标识,可以确定是访问的哪个节点
    
  3. 日志参数讲解,日志格式:[order-server,c323c72e7009c077,fba72d9c65745e60,false]

    1. 第一个值,yml配置文件中的spring.application.name的值
    2. 第二个值,c323c72e7009c077 ,sleuth生成的一个ID,叫Trace ID,用来标识一条请求链路,一条请求链路中包含一个Trace ID,多个Span ID
    3. 第三个值,fba72d9c65745e60,spanID 基本的工作单元,获取元数据,如发送一个http
    4. 第四个值:true,是否要将该信息输出到zipkin服务中来收集和展示。

Zipkin

  1. zipkin是Twitter基于google的分布式监控系统Dapper(论文)的开发源实现,zipkin用于跟踪分布式服务之间的应用数据链路,分析处理延时,帮助我们改进系统的性能和定位故障。官网:https://zipkin.io/
  2. 同类产品
    1. CAT:由大众点评开源,基于Java开发的实时应用监控平台,包括实时应用监控,业务监控 。 耦合性高一定 需要自定义埋点信息
    2. Pinpoint:由韩国团队naver团队开源,针对大规模分布式系统用链路监控,使用Java写的工具。
    3. SkyWalking:2015年由个人吴晟(华为开发者)开源 , 2017年加入Apache孵化器。 针对分布式系统的应用性能监控系统,特别针对微服务、cloud native和容器化(Docker, Kubernetes, Mesos)架构, 其核心是个分布式追踪系统
  3. 集成步骤
    1. 微服务项目中添加zipkin依赖(zipkin依赖中已经包含sleuth,所以可以把之前的sleuth依赖删除)

       <dependency>
       	<groupId>org.springframework.cloud</groupId>
       	<artifactId>spring-cloud-starter-zipkin</artifactId>
       </dependency>
      
    2. 从官网下载jar包,然后启动zipkin服务,我们直接使用的是jar的方式.
    3. 需要在product-server和order-server中的配置文件中添加zipkin地址.

       spring:
         zipkin:
           base-url: http://localhost:9411
         sleuth:
           sampler:
             probability: 1
      

分布式配置中心Config

简介:

  1. 配置中心的作用和好处
    1. 统一管理配置, 快速切换各个环境的配置
    2. 在微服务体系中,服务的数量以及配置信息的日益增多,比如各种服务器参数配置、各种数据库访问参数配置、各种环境下配置信息的不同、配置信息修改之后实时生效等等,传统的配置文件方式或者将配置信息存放于数据库中的方式已无法满足开发人员对配置管理的要求,如:
      1. 安全性:配置跟随源代码保存在代码库中,容易造成配置泄漏
      2. 时效性:修改配置,需要重启服务才能生效
      3. 局限性:无法支持动态调整:例如日志开关、功能开关
  2. 相关产品:百度的disconf、阿里的diamand、携程Apollo

搭建config-server项目

  1. 使用Spring Initializr创建SpringBoot项目,然后Dependencies选择Spring Cloud Discovery->Eureka Discovery Client, Spring Cloud Config-> Config Server
  2. 在启动类中贴上@EnableConfigServer注解
  3. 添加application.yml并设置相关的配置

搭建git+config的分布式配置中心

  1. 创建git仓库cloud-config,访问地址为:https://gitee.com/zhonghua123/cloud-config
  2. 依次创建product-server.yml、order-server.yml
  3. 将product-server、order-server中的application.yml配置信息分别复制进去,只保留eureka的注册配置,其余删除

     //只保留这个配置
     spring:
       application:
         name: order-server
     eureka:
       client:
         serviceUrl:
           defaultZone: http://localhost:8761/eureka/
    
  4. 添加application.yml并设置相关的配置

     server:
       port: 9100
     spring:
       application:
         name: config-server
       #到git仓库获取配置信息
       cloud:
         config:
           server:
             git:
               uri: https://gitee.com/zhonghua123/cloud-config
               username: 1540876109@qq.com
               password: 123456
     eureka:
       client:
         serviceUrl:
           defaultZone: http://localhost:8761/eureka/
    
  5. 启动config-server项目,可以通过http://localhost:9100/order-server.yml直接访问查看配置信息

     访问方式
     /{name}-{profiles}.properties
     /{name}-{profiles}.yml
     /{name}-{profiles}.json
     /{label}/{name}-{profiles}.yml
            
     name 服务名称
     profile 环境名称,开发、测试、生产
     lable 仓库分支、默认master分支
    

分布式配置中心客户端

  1. 在order-server、product-server中添加config-client的依赖

     <dependency>
     	<groupId>org.springframework.cloud</groupId>
     	<artifactId>spring-cloud-config-client</artifactId>
     </dependency>
    
  2. 修改对应服务的配置文件,把order-server、product-server的application.yml 改为 bootstrap.yml,新增配置中心的发现配置

     spring:
       application:
         name: order-server
       #新增配置中心发现服务配置
       cloud:
         config:
           discovery:
             service-id: config-server #到那个服务去拉
             enabled: true
           label: master #拉取哪分支
           name: order-server #拉取哪个配置文件,多个配置文件用逗号隔开。
     eureka:
       client:
         serviceUrl:
           defaultZone: http://localhost:8761/eureka/
    
  3. 把其他配置都放入到git服务器期中管理
  4. 注意 :要先启动eureka-server、config-server,再启动order-server、product-server

消息总线Bus

概念

  1. 使用场景:git仓库中的配置文件更新了,其他系统怎么能够实时更新拉取呢?
  2. 消息总线的原理:
    1. 当git文件更改的时候,通过pc端用post 向端口为8090的config-client发送请求/bus/refresh/;
    2. 此时8090端口会发送一个消息,由消息总线向其他服务传递,从而使整个微服务集群都达到更新配置文件。
    3. config-client使用消息中间件(MQ、KAFKA)的广播方式,通知各个服务更新配置信息。官方默认支持:kafka、rabbitmq这两个消息中间件;不支持rocketmq,开源项目可以支持RocketMQ的bus总线

项目集成消息总线Bus(已废弃)

  1. 下载spring-cloud-stream-bus-rocketmq项目到本地,并且安装到本地仓库 https://github.com/zhipingzhang/spring-cloud-stream-bus-rocketmq
    1. 下载下来是spring-cloud-stream-bus-rocketmq-master.zip,然后解压
    2. idea->file->open->找到spring-cloud-stream-bus-rocketmq-master文件夹下的pom.xml打开项目
    3. 删除pom文件中maven-compiler-plugin的jdk依赖10

       //删除
        <configuration>
           <source>10</source>
           <target>10</target>
       </configuration>
      
    4. 点击右侧的maven->spring-cloud-bus-rocketmq-parent->Lifecycle->install,执行完之后会将该库安装到idea配置的本地仓库。
  2. 在order-server和product-server项目中添加actuactor和spring-cloud-starter-bus-rocketmq依赖. 默认使用的Topic是springCloudBus 可以通过spring.cloud.bus.destination 来指定

     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-actuator</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-bus-rocketmq</artifactId>
         <version>2.0.2.RELEASE</version>
     </dependency>
    
  3. 在order-server.yml和product-server.yml配置文件中增加RocketMQ的配置

     spring:
       application:
         name: order-server
       cloud:
         # 相关配置在这
         stream:
           rocket:
             binder:
               name-server: 192.168.48.102:9876 #mq的地址,要先部署启动好mq服务
             bindings:
               springCloudBusInput:
                 consumer:
                   broadcasting: true #广播模式
           bindings:
             springCloudBusInput:
               group: test-group #消费组名称
     #暴露全部的监控信息
     management:
     	endpoints:
     		web:
     			exposure:
     				include: "*"
    
  4. 需要刷新配置的地方,在类上面增加注解@RefreshScope(在order-server的HelloController新增测试代码)

     @RestController
     @RefreshScope //标记的类是一个延迟加载对象, 在访问的时候创建, 并且刷新env环境的时候会清除该对象
     public class HelloController {
        
         @Value("${limitNum}")  //
         private String limitNum;
        
         @RequestMapping("hello")
         public String hello(){
             System.out.println("用户的限购数量:"+limitNum);
             return limitNum;
         }
        
     }
    
  5. 依次启动eureka-server、config-server、order-server,然后修改远程git仓库中order-server.yml的limitNum属性值为3
  6. 访问验证post方式: http://localhost:8090/actuator/bus-refresh
    1. 必须发送这个请求,才会触发更新。
  7. 访问http://localhost:8090/hello,打印结果为:用户的限购数量:3 ,成功修改

SpringBoot的监控管理(重要:可以用来排查问题)

  1. SpringBoot默认情况是关闭监控管理, 需要通过配置开启监控

     management:
     	endpoints:
     		web:
     			exposure:
     				include: "*"
    
  2. 访问监控页面

     http://localhost:9100/actuator
     http://localhost:9100/actuator/env springboot环境配置
     http://localhost:9100/actuator/beans  获取对应的Bean信息
    
  3. 可以通过post请求访问更新最新的环境配置, 并且会清除缓存中的Bean对象(使用@RefreshScope标记的类), http://localhost:8090/actuator/refresh
  4. 可以通过在类上标记注解@RefreshScope 来声明该Bean对象是一个延迟加载的实例Bean对象
  5. 在bus消息总线环境可以通过 http://localhost:8090/actuator/bus-refresh 进行消息总线的通知更新
Table of Contents