.NET Core微服務之基於Ocelot+Butterfly實現分布式追蹤


Tip: 此篇已加入.NET Core微服務基礎系列文章索引

一、什么是Tracing?

  微服務的特點決定了功能模塊的部署是分布式的,以往在單應用環境下,所有的業務都在同一個服務器上,如果服務器出現錯誤和異常,我們只要盯住一個點,就可以快速定位和處理問題,但是在微服務的架構下,大部分功能模塊都是單獨部署運行的,彼此通過總線交互,都是無狀態的服務,這種架構下,前后台的業務流會經過很多個微服務的處理和傳遞,我們會面臨以下問題:

  • 分散在各個服務器上的日志怎么處理?
  • 如果業務流出現了錯誤和異常,如何定位是哪個點出的問題?
  • 如何快速定位問題?
  • 如何跟蹤業務流的處理順序和結果?

  以前在單應用下的日志監控很簡單,在微服務架構下卻成為了一個大問題,如果無法跟蹤業務流,無法定位問題,我們將耗費大量的時間來查找和定位問題,在復雜的微服務交互關系中,我們就會非常被動。因此,我們需要對其進行追蹤,而這個時候Google公司廣泛使用了分布式集群,為了應對自身大規模的復雜集群環境,Google公司研發了Dapper分布式跟蹤系統,並發表了論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,給行業內分布式跟蹤的實現提供了非常有價值的參考,該論文也成為了當前分布式跟蹤系統的理論基礎。

>>對於基礎理論,這里涉及到OpenTracing,推薦看看吳晟的翻譯的《OpenTracing文檔中文版》。

二、Butterfly的基本使用

2.1 Butterfly簡介

  Butterfly是一個使用Open Tracing規范來設計追蹤數據的開源追蹤組件,作者Lemon,也是AspectCore的作者。目前Ocelot已集成Butterfly,我們只需要做很少的配置即可對經過網關的所有API服務進行Tracing。不過,貌似Lemon已不打算繼續維護Butterfly而是推薦使用Apache SkyWalking來做生產環境的分布式追蹤,同時他也加入了SkyWalking團隊共同進行SkyWalking在多語言生態的推動。不過,就學習而言,Butterfly是比較適合學習來了解分布式追蹤是個神馬玩意兒的,這里呢我暫時不再去學習ApacheSkyWalking了(因為我的目標是了解整個流程,做POC而不是能上生產環境的產品)。

  這里是SkyWalking-netcore的GitHub地址:https://github.com/OpenSkywalking/skywalking-netcore

2.2 Butterfly的安裝與配置

  

  Step1.下載最新的release,目前是preview-0.0.8

  Step2.解壓並通過命令啟動:dotnet Butterfly.Web.dll --EnableHttpCollector=true

  Step3.通過默認地址和端口進行查看,如下圖所示:(這里沒有任何trace,因為還沒有任何請求)

  

三、結合Ocelot的一個Tracing實例

3.1 Ocelot的配置

  剛剛說到Ocelot已內集成了Butterfly,所以我們只需要做以下兩個配置:

  (1)配置文件配置UseTracing

    "ReRoutes": [
    // API01:CAS.ClientService
    // --> service part
    {
      ......  
      "HttpHandlerOptions": {
        "UseTracing": true // use butterfly to tracing request chain
      },
      ......
    },
    // API02:CAS.ProductService
    // --> service part
    {
      ......
      "HttpHandlerOptions": {
        "UseTracing": true // use butterfly to tracing request chain
      },
      ......
    }

  (2)StartUp類中啟用OpenTracing

    public void ConfigureServices(IServiceCollection services)
    {
        // Ocelot
        services.AddOcelot(Configuration)
            .AddOpenTracing(option => { option.CollectorUrl = Configuration["TracingCenter:Uri"]; option.Service = Configuration["TracingCenter:Name"]; });
        ......
    }

  json配置文件了配置了Butterfly的Url地址及其顯示名:

  "TracingCenter": {
    "Uri": "http://192.168.80.1:9618", // Tracing Center Address
    "Name": "API Gateway" // Display Name
  }

3.2 案例結構與配置

  這里我們模擬一個ASP.NET Core MVC Web應用程序中要請求一個ClientService的某個接口,而這個接口又依賴於ProductService的一個接口的返回結果,因此這個請求的請求順序就如上圖所示(標有序號),流程很簡單,下面我們就來一一為MVC WebApp、ClientService和ProductService進行Butterfly的配置。

  這里我們通過介紹MvcApp的配置(事先創建一個ASP.NET Core MVC應用程序)來說明如何安裝和配置Buttefly,至於ClientService和ProductService和MvcApp的安裝配置步驟一樣,就不再贅述。

  (1)NuGet安裝Butterfly Client

NuGet>Install-Package Butterfly.Client.AspNetCore

  *.這里建議安裝0.0.7版本,0.0.8版本測試時始終無法獲取請求。

  (2)注冊Butterfly

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        // Tracing - Butterfly
        services.AddButterfly(option => { option.CollectorUrl = Configuration["TracingCenter:Uri"]; option.Service = Configuration["TracingCenter:Name"]; }); services.AddSingleton<HttpClient>(p => new HttpClient(p.GetService<HttpTracingHandler>()));
    }

  這里一起注入了加入了HttpTracingHandler的HttpClient,用來在Controller中調用其他服務接口。

  (3)修改Controller中的Action,使其調用ClientService的一個接口:

    public class HomeController : Controller
    {
        private string gatewayUri;

        public HomeController(IConfiguration configuration)
        {
            gatewayUri = $"http://{configuration["Gateway:IP"]}:{configuration["Gateway:Port"]}";
        }

        ......

        public IActionResult About([FromServices]HttpClient httpClient)
        {
            var requestResult = httpClient.GetStreamAsync($"{gatewayUri}/api/clientservice/trace").GetAwaiter().GetResult();

            ViewData["Message"] = $"Your request data result : {requestResult}";

            return View();
        }

        ......
    }

  (4)在ClientService中,調用ProductService的一個接口:

    [Route("api/Trace")]
    public class TraceController : Controller
    {
        private string gatewayUri;

        public TraceController(IConfiguration configuration)
        {
            gatewayUri = $"http://{configuration["Gateway:IP"]}:{configuration["Gateway:Port"]}";
        }

        [HttpGet]
        public string Get([FromServices]HttpClient httpClient)
        {
            var result = httpClient.GetStringAsync($"{gatewayUri}/api/productservice/values").GetAwaiter().GetResult();

            return $"ProductService AccessTime: {DateTime.Now.ToString()}, Result: {result}";
        }
    }

  (5)在ProductService中,提供這樣的一個接口,返回一些測試字符串

    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "ProductService-value1", "ProductService-value2" };
        }

        ......
    }

3.3 簡單測試

  (1)瀏覽器中訪問MvcWebApp的About頁面

  (2)在Butterfly Web頁面查看Trace

  

  上圖我們可以看到總花費時間,經歷了哪些節點等信息。

  

  上圖我們可以看出調用的順序,依次經歷哪些節點,花費時間,占比等等。

  (3)在Butterfly Web頁面查看Dependencies

  

  上圖我們可以直觀地看出這個請求的處理流程(MvcApp->API Gateway->ClientService->API Gateway->ProductService),經過了哪些節點,像API Gateway和ClientService就有一個雙向連接,代表各自請求對方。

四、小結

  本篇首先介紹了一下追蹤(Tracing)的背景以及基本概念,然后介紹了一下一個開源的分布式追蹤組件Butterfly,由於Ocelot已經集成了Butterfly,所以我們可以很方便地在Ocelot中使用Butterfly進行追蹤。最后,通過一個具體的小實例,介紹了如何在ASP.NET Core微服務環境中如何使用Ocelot+Butterfly進行請求的追蹤。不過,Butterfly的作者Lemon已不打算繼續維護Butterfly而是推薦使用Apache SkyWalking來做生產環境的分布式追蹤,同時他也加入了SkyWalking團隊共同進行SkyWalking在多語言生態的推動。所以,學習環境下,可以拿Butterfly了解一下分布式追蹤的意義,但是要上實際環境,可以考慮用以下SkyWalking。后續,有機會的話,我也會用SkyWalking來替代Butterfly做追蹤,到時有機會也分享一下。

示例代碼

  Click Here => 點我下載

參考資料

作者不詳,《微服務架構下,如何實現分布式跟蹤?

吳晟,《OpenTracing文檔中文版

桂素偉,《Ocelot中使用Butterfly實踐

張善友,《Ocelot集成Butterfly實現分布式追蹤

Butterfly Github:https://github.com/liuhaoyang/butterfly => 作者Lemon,也是AspectCore的作者

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM