Bumblebee之負載、限流和故障處理實踐

smark發表於2019-03-19

Bumblebee作為標準HTTP 1.1應用協議的閘道器,它能作為任何基於HTTP 1.1構建Webapi服務的前置閘道器。以下通過示例講述如何用Bumblebee來製作一個asp.net core webapi的前置閘道器,並演示閘道器的一些基礎功能如:負載,限流和故障遷移等相關基礎功能。

閘道器定義

Bumblebee定義閘道器非常簡便,只需要Nuget引用BeetleX.Bumblebee.然後定義Gateway類執行即可,大概程式碼如下:

            mGateway = new Bumblebee.Gateway();
            mGateway.HttpOptions(o => { o.LogToConsole = true; o.Port = 80; });
            //添中管理的服務,閘道器會對應用服務的可用狀況進行監控
            mGateway.SetServer("http://192.168.2.18:8001");
            mGateway.SetServer("http://192.168.2.18:8002");
            mGateway.SetServer("http://192.168.2.18:8003");

            //default的是'*',匹配優先順序最低
            mGateway.Routes.Default
               .AddServer("http://192.168.2.18:8001", 0, 0)
               .AddServer("http://192.168.2.18:8002", 0, 0)
               .AddServer("http://192.168.2.18:8003", 0, 0);
            //以上是手動程式碼的方式來構建閘道器,實際上可以通過配置'Gateway.json'來描述即可,具本檢視https://github.com/IKende/Bumblebee
            mGateway.Open();

以上通過程式碼定義一個閘道器,閘道器主要有三臺服務,並進行一個平均負載略。如果不想硬程式碼的情況可以通過編寫'Gateway.json'配置檔案來達到同樣的效果:

{
  "Servers": [
    {
      "Uri": "http://192.168.2.18:8001/"
    },
    {
      "Uri": "http://192.168.2.18:8002/"
    },
    {
      "Uri": "http://192.168.2.18:8003/"
    }
  ],
  "Urls": [
    {
      "Url": "*",
      "HashPattern": null,
      "Servers": [
        {
          "Uri": "http://192.168.2.18:8001/"
        },
        {
          "Uri": "http://192.168.2.18:8002/"
        },
        {
          "Uri": "http://192.168.2.18:8003/"
        }
      ]
    }
  ]
}

以上是元件預設的配置檔案,通過程式碼擴充套件的好處是可以根據自己的需要來制定儲存方式。

Web服務

接下需要編寫三個Asp.net core web api專案,分別部署配置到以上三個配置的地址中;為了方便測試服務,對應的方法是返回相應的服務地址IP埠

    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        // GET api/values
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new string[] { $"{this.HttpContext.Connection.LocalIpAddress}${this.HttpContext.Connection.LocalPort}|{DateTime.Now}" };
        }

        // GET api/values/5
        [HttpGet("{id}")]
        public ActionResult<string> Get(int id)
        {
            return $"{this.HttpContext.Connection.LocalIpAddress}${this.HttpContext.Connection.LocalPort}|{DateTime.Now}";
        }

        // POST api/values
        [HttpPost]
        public ActionResult<string> Post([FromBody] string value)
        {
            return $"{this.HttpContext.Connection.LocalIpAddress}${this.HttpContext.Connection.LocalPort}|{DateTime.Now}";
        }

        // PUT api/values/5
        [HttpPut("{id}")]
        public ActionResult<string> Put(int id, [FromBody] string value)
        {
            return $"{this.HttpContext.Connection.LocalIpAddress}${this.HttpContext.Connection.LocalPort}|{DateTime.Now}";
        }

        // DELETE api/values/5
        [HttpDelete("{id}")]
        public ActionResult<string> Delete(int id)
        {
            return $"{this.HttpContext.Connection.LocalIpAddress}${this.HttpContext.Connection.LocalPort}|{DateTime.Now}";
        }
    }

編寫服務執行後會收到閘道器的狀態請求資訊,這個資訊主要是閘道器用於檢測服務的有效性,請求頻率大概在1秒左右。

 

測試

為了方便測試示例閘道器整合了一個測試頁面,通過頁面請求閘道器可以看到響應情況;由於配置是三臺服務平均負載請求,所以測試請求的情況會看到具體請求會被平均化到不同服務上。

 

調整權重

元件在新增服務的時候可以設定對應的重權值,以下把8001的權重設定10,其它兩個設定成5看一下情況

  mGateway.Routes.Default
               .AddServer("http://192.168.2.18:8001", 10, 0)
               .AddServer("http://192.168.2.18:8002", 5, 0)
               .AddServer("http://192.168.2.18:8003", 5, 0);

零權重

元件支援零權重設定,當設定為零的情況下一般情況下是不參與負載的,為什麼說一般情況下呢?其實即使是零的情況當其他服務不可用情況是會把負載落地它身上,以下簡單的演示一下,把8003配置成零權重執行一段時間後把8001和8002關閉,後再執行8001看一下執行結果

   //default的是'*',匹配優先順序最低
            mGateway.Routes.Default
               .AddServer("http://192.168.2.18:8001", 10, 0)
               .AddServer("http://192.168.2.18:8002", 10, 0)
               .AddServer("http://192.168.2.18:8003", 0, 0);

 

RPS限制

為了保障服務執行的穩定性,對請求限制是一種比較普遍的做法,元件支援針對不同URL不同服務進行一個RPS限制,用於確保服務可以可靠地執行。以下把三個服務的RPS都即制在100內

            mGateway.Routes.Default
               .AddServer("http://192.168.2.18:8001", 10, 100)
               .AddServer("http://192.168.2.18:8002", 10, 100)
               .AddServer("http://192.168.2.18:8003", 10, 100);

 

以上用工具壓測了3秒,正常處理的請求是1000多個,其他幾十萬的請求都被閘道器攔載了。所以對於大量併發湧入的時候,rps的限制就能體現其作用。

故障遷移和恢復

這個功能暫由元件內部管理,元件會每秒探測服務的可訪問情況;當有服務狀態不可或恢復後元件都會重新構建負載策略確保服務的可用性。不過當服務不可用的情況存在短暫時間裡訪問到這服務的請求會返回5XX訪問錯誤資訊。

總結

到這裡Bumblebee使用和相關基礎功能就介紹完了,但Bumblebee所提供的功能並不遠止這些,它提供不同的事件介面用於擴充套件服務處理可以制很完善的業務處理功能,後面會一步步深入講解。

示例程式碼:https://github.com/IKende/Bumblebee/tree/master/Samples/AspCoreWebapi

相關文章