(5)ASP.NET Core3.1 Ocelot服務品質

1.服務品質(Quality of Service)

對於微服務來說,熔斷就是我們常說的「保險絲」,意思是當服務出現某些狀況時候,通過切斷服務防止應用程式不斷地執行可能會失敗的操作造成系統崩潰,或者大量的超時等待導致系統卡死等情況。而Ocelot也支援熔斷,當客戶端通過上游向下游服務發出請求時候,我們可以基於每個路由上配置熔斷功能。Ocelot使用了Polly的.NET庫中的熔斷功能,安裝命令如下:

Install-Package Ocelot.Provider.Polly

在Ocelot服務品質項目示例中,通過網關層的路由QoSOptions選項可以配置熔斷功能。網關項目中配置一個下游服務加入了熔斷功能,一個則沒有,對應下文APIServices項目兩個Get方法,具體程式碼如下:

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/values",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 9001
        }
      ],
      "UpstreamPathTemplate": "/customers",
      "UpstreamHttpMethod": [ "Get" ],
      "QoSOptions": {
        //該值必須大於0,該值是指當異常發生達到此值會熔斷。
        "ExceptionsAllowedBeforeBreaking": 2,
        //該值指熔斷後會保持多久。該值的單位是毫秒。
     "DurationOfBreak": 3000,
        //該值指定當請求超過此值會被自動設置為超時。同樣該值的單位是毫秒。
        "TimeoutValue": 2000
      }
    },
    {
      "DownstreamPathTemplate": "/api/values/{id}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 9001
        }
      ],
      "UpstreamPathTemplate": "/customers/{id}",
      "UpstreamHttpMethod": [ "Get" ]
    }
  ]
}

下面來介紹下QoSOptions選項幾個參數:
●ExceptionsAllowedBeforeBreaking:該值必須大於0,該值是指當異常發生達到此值會熔斷。
●DurationOfBreak:該值指熔斷後會保持多久。該值的單位是毫秒。
●TimeoutValue:該值指定當請求超過此值會被自動設置為超時。同樣該值的單位是毫秒。
根據官網文檔說明,如果路由配置裡面不加入QoSOptions選項,則不使用熔斷功能,但是Ocelot會將在所有下游請求默認為90秒超時。

2.項目演示

2.1APIGateway項目

Ocelot要使用熔斷功能需要註冊Polly服務,所以需在網關項目的ConfigureServices方法中加入如下程式碼:

public virtual void ConfigureServices(IServiceCollection services)
{
    //註冊Polly服務
    services.AddOcelot().AddPolly();
}

2.2APIServices項目

項目添加兩個Get方法作對比,對應網關項目的路由上下游配置,一個加入計數變數條件判斷,如果計數變數超過等於小於3則等待6秒;一個傳參即可,具體程式碼如下:

[Route("api/[controller]")]
public class ValuesController : Controller
{
    private static int _count = 0;

    // GET api/values
    [HttpGet]
    public IEnumerable<string> Get()
    {
        _count++;
        System.Console.WriteLine($"get...{_count}");
        if (_count <= 3)
        {
            System.Console.WriteLine($"circuit breaker...{_count}");
            Thread.Sleep(6000);
        }
        return new string[] { "value1", "value2" };
    }

    // GET api/values/5
    [HttpGet("{id}")]
    public string Get(int id)
    {
        return "value";
    }
}

2.3項目運行

輸入dotnet run –project 項目路徑\項目文件.csproj把兩個項目啟動起來,在瀏覽器上連續刷新三次上游服務地址//localhost:9000/customers,會看到如下資訊:


結合APIGateway項目網關配置QoSOptions選項和APIServices項目Get方法程式碼可以看到:_count變數是0-3的時候,會等待6秒才會輸出字元串數組返回給客戶端。當_count小於等於2的時候,控制台會輸出Get方法_count變數資訊,但是因為QoSOptions.TimeoutValue設置了2秒超時,所以在等待2秒後就直接切斷服務請求返回503狀態碼給客戶端,不會再進行下一步操作。而當_count等於3的時候,控制台並沒有返回_count變數資訊,這是為什麼呢?因為QoSOptions.ExceptionsAllowedBeforeBreaking選項設置了2次請求異常或者超時處理時直接熔斷,所以當第三次請求時,連下游服務都沒分發就直接返回503狀態碼給客戶端。下面我們再來看看第四次請求:

這時候會看到第四次請求跟第一二次請求是一樣的狀態碼、回調結果,差不多的耗時,這證明QoSOptions配置生效了!而當第五次請求時候,我們就會看到成功獲取Get回調字元串數組:

然後我們在瀏覽器上刷新//localhost:9000/customers/1幾次,會看到如下資訊:

沒添加熔斷配置的服務是沒有限制,可以直接訪問。

參考文獻:
Ocelot官網

Tags: