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;
     }
     
}
相關文章
相關標籤/搜索