SpringCloud系列教材 (九)- 服务链路追踪

SpringCloud系列教材 (九)- 服务链路追踪


 
步骤1:什么是服务链路
步骤2:先运行,看到效果,再学习
步骤3:模仿和排错
步骤4:改造
步骤5:pom.xml
步骤6:配置信息
步骤7:sampler
步骤 1 : 什么是服务链路
在前面的例子里,咱们有两个微服务,分别是数据服务和视图服务,随着业务的增长,就会有愈来愈多的微服务存在,他们之间也会有更加复杂的调用关系。
这个调用关系,仅仅经过观察代码,会愈来愈难以识别,因此就须要经过 zipkin 服务链路追踪服务器 这个东西来用图片进行识别了。
步骤 2 : 先运行,看到效果,再学习
老规矩,先下载 下载区(点击进入)的可运行项目,配置运行起来,确承认用以后,再学习作了哪些步骤以达到这样的效果。 

1. 须要启动链路追踪服务器,这个启动办法是下载右上角的 zipkin-server-2.10.1-exec.jar, 而后用以下命令启动:
java -jar zipkin-server- 2.10 . 1 -exec.jar

2. 挨个启动 eureka-server, 改造后的 product-data-service 和 product-view-service-feign 。 ( product-view-service-ribbon 后续再也不使用,因此既没有被改造,也不用再启动了)
3. 访问一次 http://127.0.0.1:8012/products 经过 视图微服务去访问数据微服务,这样链路追踪服务器才知道有这事儿发生~
4. 而后打开链路追踪服务器 http://localhost:9411/zipkin/dependency/ 就能够看到如图所示的 视图微服务调用数据微服务 的图形了。
先运行,看到效果,再学习
步骤 3 : 模仿和排错
在确保可运行项目可以正确无误地运行以后,再严格照着教程的步骤,对代码模仿一遍。 
模仿过程不免代码有出入,致使没法获得指望的运行结果,此时此刻经过比较正确答案 ( 可运行项目 ) 和本身的代码,来定位问题所在。 
采用这种方式,学习有效果,排错有效率,能够较为明显地提高学习速度,跨过学习路上的各个槛。 

推荐使用diffmerge软件,进行文件夹比较。把你本身作的项目文件夹,和个人可运行项目文件夹进行比较。 
这个软件很牛逼的,能够知道文件夹里哪两个文件不对,而且很明显地标记出来 
这里提供了绿色安装和使用教程: diffmerge 下载和使用教程
步骤 4 : 改造
eureka-server 不须要作改造。
product-data-service和product-view-service 须要进行改造以使其能够被追踪到。
步骤 5 : pom.xml
两个 pom.xml 里都增长 zipkin 的jar包。
<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>    
< project  xmlns = "http://maven.apache.org/POM/4.0.0"  xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
   < modelVersion >4.0.0</ modelVersion >
   < parent >
     < groupId >cn.how2j.springcloud</ groupId >
     < artifactId >springcloud</ artifactId >
     < version >0.0.1-SNAPSHOT</ version >
   </ parent >
   < artifactId >product-data-service</ artifactId >
   
     < dependencies >
         < dependency >
             < groupId >org.springframework.cloud</ groupId >
             < artifactId >spring-cloud-starter-netflix-eureka-client</ artifactId >
         </ dependency >
         < dependency >
             < groupId >org.springframework.boot</ groupId >
             < artifactId >spring-boot-starter-web</ artifactId >
         </ dependency >
         < dependency >
             < groupId >org.springframework.cloud</ groupId >
             < artifactId >spring-cloud-starter-zipkin</ artifactId >
         </ dependency >      
                         
     </ dependencies >
       
</ project >
< project  xmlns = "http://maven.apache.org/POM/4.0.0"  xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
   < modelVersion >4.0.0</ modelVersion >
   < parent >
     < groupId >cn.how2j.springcloud</ groupId >
     < artifactId >springcloud</ artifactId >
     < version >0.0.1-SNAPSHOT</ version >
   </ parent >
   < artifactId >product-view-service-feign</ artifactId >
   
     < dependencies >
         < dependency >
             < groupId >org.springframework.cloud</ groupId >
             < artifactId >spring-cloud-starter-netflix-eureka-client</ artifactId >
         </ dependency >
         < dependency >
             < groupId >org.springframework.cloud</ groupId >
             < artifactId >spring-cloud-starter-openfeign</ artifactId >
         </ dependency >
                 
         < dependency >
             < groupId >org.springframework.boot</ groupId >
             < artifactId >spring-boot-starter-web</ artifactId >
         </ dependency >
 
       < dependency >
         < groupId >org.springframework.boot</ groupId >
         < artifactId >spring-boot-starter-thymeleaf</ artifactId >
       </ dependency >
 
     < dependency >
         < groupId >org.springframework.cloud</ groupId >
         < artifactId >spring-cloud-starter-zipkin</ artifactId >
     </ dependency >      
                 
     </ dependencies
   
</ project >
步骤 6 : 配置信息
两个的配置文件都加上
spring:
   zipkin:
     base-url: http: //localhost:9411
#   server:
#   port: 由于会启动多个 product-data-service, 因此端口号由用户自动设置,推荐 8001,8002,8003
 
spring:
   application:
     name: product-data-service
   zipkin:
     base-url: http://localhost:9411       
eureka:
   client:
     serviceUrl:
       defaultZone: http://localhost:8761/eureka/
eureka:
   client:
     serviceUrl:
       defaultZone: http://localhost:8761/eureka/
spring:
   application:
     name: product-view-service-feign
   zipkin:
     base-url: http://localhost:9411   
   thymeleaf:
     cache: false
     prefix: classpath:/templates/
     suffix: .html
     encoding: UTF-8
     content-type: text/html
     mode: HTML5   
步骤 7 : sampler
在启动类里配置 Sampler 抽样策略: ALWAYS_SAMPLE 表示持续抽样
@Bean
public  Sampler defaultSampler() {
     return  Sampler.ALWAYS_SAMPLE;
package  cn.how2j.springcloud;
 
import  java.util.Scanner;
import  java.util.concurrent.ExecutionException;
import  java.util.concurrent.Future;
import  java.util.concurrent.TimeUnit;
import  java.util.concurrent.TimeoutException;
import  org.springframework.boot.autoconfigure.SpringBootApplication;
import  org.springframework.boot.builder.SpringApplicationBuilder;
import  org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import  org.springframework.context.annotation.Bean;
 
import  brave.sampler.Sampler;
import  cn.hutool.core.convert.Convert;
import  cn.hutool.core.thread.ThreadUtil;
import  cn.hutool.core.util.NetUtil;
import  cn.hutool.core.util.NumberUtil;
 
@SpringBootApplication
@EnableEurekaClient
public  class  ProductDataServiceApplication {
     public  static  void  main(String[] args) {
         int  port =  0 ;
         int  defaultPort =  8001 ;
         Future<Integer> future = ThreadUtil.execAsync(() ->{
                 int  p =  0 ;
                 System.out.println( "请于5秒钟内输入端口号, 推荐  8001 、 8002  或者  8003,超过5秒将默认使用 "  + defaultPort);
                 Scanner scanner =  new  Scanner(System.in);
                 while ( true ) {
                     String strPort = scanner.nextLine();
                     if (!NumberUtil.isInteger(strPort)) {
                         System.err.println( "只能是数字" );
                         continue ;
                     }
                     else  {
                         p = Convert.toInt(strPort);
                         scanner.close();
                         break ;
                     }
                 }
                 return  p;
         });
         try {
             port=future.get( 5 ,TimeUnit.SECONDS);
         }
         catch  (InterruptedException | ExecutionException | TimeoutException e){
             port = defaultPort;
         }
         
         if (!NetUtil.isUsableLocalPort(port)) {
             System.err.printf( "端口%d被占用了,没法启动%n" , port );
             System.exit( 1 );
         }
         
         new  SpringApplicationBuilder(ProductDataServiceApplication. class ).properties( "server.port="  + port).run(args);
     }
     @Bean
     public  Sampler defaultSampler() {
         return  Sampler.ALWAYS_SAMPLE;
     }   
}
package  cn.how2j.springcloud;
 
import  java.util.Scanner;
import  java.util.concurrent.ExecutionException;
import  java.util.concurrent.Future;
import  java.util.concurrent.TimeUnit;
import  java.util.concurrent.TimeoutException;
 
import  org.springframework.boot.autoconfigure.SpringBootApplication;
import  org.springframework.boot.builder.SpringApplicationBuilder;
import  org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import  org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import  org.springframework.cloud.openfeign.EnableFeignClients;
import  org.springframework.context.annotation.Bean;
 
import  brave.sampler.Sampler;
import  cn.hutool.core.convert.Convert;
import  cn.hutool.core.thread.ThreadUtil;
import  cn.hutool.core.util.NetUtil;
import  cn.hutool.core.util.NumberUtil;
 
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public  class  ProductViewServiceFeignApplication {
 
     public  static  void  main(String[] args) {
         int  port =  0 ;
         int  defaultPort =  8012 ;
         Future<Integer> future = ThreadUtil.execAsync(() ->{
                 int  p =  0 ;
                 System.out.println( "请于5秒钟内输入端口号, 推荐  8012 、 8013  或者  8014,超过5秒将默认使用" +defaultPort);
                 Scanner scanner =  new  Scanner(System.in);
                 while ( true ) {
                     String strPort = scanner.nextLine();
                     if (!NumberUtil.isInteger(strPort)) {
                         System.err.println( "只能是数字" );
                         continue ;
                     }
                     else  {
                         p = Convert.toInt(strPort);
                         scanner.close();
                         break ;
                     }
                 }
                 return  p;
         });
         try {
             port=future.get( 5 ,TimeUnit.SECONDS);
         }
         catch  (InterruptedException | ExecutionException | TimeoutException e){
             port = defaultPort;
         }
         if (!NetUtil.isUsableLocalPort(port)) {
             System.err.printf( "端口%d被占用了,没法启动%n" , port );
             System.exit( 1 );
         }
         new  SpringApplicationBuilder(ProductViewServiceFeignApplication. class ).properties( "server.port="  + port).run(args);
 
     }
     @Bean
     public  Sampler defaultSampler() {
         return  Sampler.ALWAYS_SAMPLE;
     }
     
}
相关文章
相关标签/搜索