阿里高階架構師教你使用Spring Cloud Sleuth跟蹤微服務

weixin_34292287發表於2018-09-06

隨著微服務數量不斷增長,需要跟蹤一個請求從一個微服務到下一個微服務的傳播過程,Spring Cloud Sleuth 正是解決這個問題,它在日誌中引入唯一ID,以保證微服務呼叫之間的一致性,這樣你就能跟蹤某個請求是如何從一個微服務傳遞到下一個。

Spring Cloud Sleuth在日誌中增加兩種ID 型別, 一個是trace ID,另外一個是span ID,span ID代表工作基本單元,比如傳送一個HTTP 請求;treace ID包含一系列span ID,形成一個樹狀結構。

首先,從 start.spring.io建立一個新的Spring Boot應用,依賴於Sleuth(spring-cloud-starter-slueth),產生專案並下載程式碼,給你的應用取名也有助於Sleuth的跟蹤。

在src/main/resources建立一個檔案稱為bootstrap.yml,在這個檔案里加入屬性spring.application.name為你取的名稱,名稱將作為SLeuth跟蹤部分的一部分。

現在加入一些日誌到應用中,開啟你的應用檔案,main方法所在的那個類,建立一個方法為home,返回String:

public String home() {  return "Hello World"; }

讓我們使用該方法作為你的web應用的直接呼叫,增加@RestController在類級別,增加@RequestMapping("/")到home方法:

@SpringBootApplication @RestController public class SleuthSampleApplication {  public static void main(String[] args) {   SpringApplication.run(SleuthSampleApplication.class, args);  }   @RequestMapping("/")  public String home() {   LOG.log(Level.INFO, "you called home");   return "Hello World";  } }

如果你啟動這個應用,瀏覽器訪問http://localhost:8080,你會看到hello world,現在有了這個案例,讓我們使用Sleuth加入日誌到這個應用:

在應用類增加下面日誌變數:

private static final Logger LOG = Logger.getLogger(SleuthSampleApplication.class.getName());

注意這裡的類名需要是所在類的名稱,在home方法,增加下面日誌語句:

@RequestMapping("/") public String home() {  LOG.log(Level.INFO, "you called home");  return "Hello World"; }

當你再訪問這個應用時,在console後臺會看到日誌輸出:

2016-06-15 16:55:56.334 INFO [slueth-sample,44462edc42f2ae73,44462edc42f2ae73,false] 13978 --- [nio-8080-exec-1] com.example.SleuthSampleApplication : calling home

Sleuth加入的是[slueth-sample,44462edc42f2ae73,44462edc42f2ae73,false],這是什麼意思?第一個部分是應用名稱,也就是前面你在bootstrap.yml中設定spring.application.name的值,第二個值是trace ID,第三個是span ID,最後值顯示span是否應該匯出到Zipkin。

除了向日志語句新增額外的跟蹤資訊外,Spring Cloud Sleuth在呼叫其他微服務時還提供了一些重要的好處。 記住,這裡的真正的問題不是在單個微服務中識別日誌,而是在多個微服務之間跟蹤一個請求鏈。 微服務通常使用REST API與非同步地通過訊息中心互相互動。 Sleuth可以在任一情況下提供跟蹤資訊,但在本示例中,下面我們將瞭解REST API呼叫的工作原理。

讓我們使用RestTemplate瞭解應用呼叫是如何工作的。修改我們的應用類:

private static final Logger LOG = Logger.getLogger(SleuthSampleApplication.class.getName());  @Autowired private RestTemplate restTemplate; public static void main(String[] args) {  SpringApplication.run(SleuthSampleApplication.class, args); }  @Bean public RestTemplate getRestTemplate() {  return new RestTemplate(); }  @RequestMapping("/") public String home() {  LOG.log(Level.INFO, "you called home");  return "Hello World"; }  @RequestMapping("/callhome") public String callHome() {  LOG.log(Level.INFO, "calling home");  return restTemplate.getForObject("http://localhost:8080", String.class); }

我們增加了新的RestTemplate這個bean,這對於Sleuth在請求頭部加入trace ID和span ID有作用,這個頭部能夠被Sleuth用來跟蹤微服務之間請求鏈,通過這個bean,Sleuth能夠使用依賴注入獲得這個物件並加入頭部資訊。

我們也加入新的方法和端點,稱為callhome,如果你訪問http://localhost:8080/callhome,你會看到日誌輸出如下:

2016-06-17 16:12:36.902 INFO [slueth-sample,432943172b958030,432943172b958030,false] 12157 --- [nio-8080-exec-2] com.example.SleuthSampleApplication : calling home 2016-06-17 16:12:36.940 INFO [slueth-sample,432943172b958030,b4d88156bc6a49ec,false] 12157 --- [nio-8080-exec-3] com.example.SleuthSampleApplication : you called home

上面日誌trace ID是相同,但是span ID不同,trace ID是讓你跟蹤一個跨服務呼叫傳遞的請求,而span ID是不同,因為有兩個工作單元發生,每個請求各一個。

如果你開啟瀏覽器除錯工具,會看到/callhome的請求頭部,在響應中看到兩個頭部有:

X-B3-SpanId: fbf39ca6e571f294 X-B3-TraceId: fbf39ca6e571f294

可見,頭部能夠讓Sleuth跟蹤微服務之間的請求。

大家可以點選加入群:【Java高階架構進階群】:854180697 裡面有Java高階大牛直播講解知識點 走的就是高階路線,(如果你想跳槽換工作 但是技術又不夠 或者工作上遇到了瓶頸 ,我這裡有一個JAVA的免費直播課程 ,講的是高階的知識點基礎不好的誤入喲,只要你有1-5年的開發經驗可以加群找我要課堂連結 注意:是免費的 沒有開發經驗誤入哦)

寫在最後:歡迎留言討論,加關注,持續更新!!!

相關文章