1. 程式人生 > >(5)ASP.NET Core3.1 Ocelot服務質量-熔斷

(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": 5000,
        //該值指定當請求超過此值會被自動設定為超時。同樣該值的單位是毫秒。
        "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把兩個專案啟動起來,在瀏覽器上連續重新整理三次上游服務地址http://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回撥字串陣列:

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

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

參考文獻:
Ocelot官網