負載均衡之Ocelot+Consul(配置文件注冊服務)


繼上篇 Ocellot 做負載均衡之后,本篇將記錄 Ocelot + Consul 試驗如何做服務發現和服務注冊。

服務發現和服務注冊的背景知識,一搜滿街都是。

在此,我還是寫下自己對這個術語的理解吧。上篇雖然對多個服務節點做了負載均衡,但如果其中一個節點掛掉了,我們訪問時會現一次成功一次失敗,這在實際生產環境中是絕對不允許的,也失去了負載均衡原來的意義。

我們必須保證,如果有某些節點服務掛掉了,只要有一個或一個以上的節點服務還健康活着,那整個服務就還能繼續工作。Ocelot網關是不能感知其下節點服務的健康情況的,所以需要借助某種工具,去主動監聽其下節點服務的狀態,這就是服務發現。Ocelot早已兼容Consul這種服務發現工具。

下面,我們先在linux機上安裝一下Consul,具體如下:

$ wget https://releases.hashicorp.com/consul/1.4.4/consul_1.4.4_linux_amd64.zip
$ sudo apt-get install unzip

$ ls

$ unzip consul_1.4.4_linux_amd64.zip
$ sudo mv consul /usr/local/bin/consul

以上命令,在官網下了個包,然后解壓了一下,里面只有一個 consul文件,把文件移到了/usr/local/bin/consul。

然后,就真的沒有然后了,Consul 安裝完畢!

試下 $ consul 

 

看到這個,安裝就是成功的了。

體驗一下: consul agent -dev

看一下成員: consul members

然后在瀏覽器上試訪問一下:192.168.1.23

 

體驗完了,就把它移除吧,dev是拿來試的

$ consul leave

 

下面我們對代碼配置,做一點小修改。修改之前,簡單說一下代碼結構,一個網關,兩個API

所有項目的appsetting.json都設置一下,各自讀自定義IP和Port,

public static IWebHost BuildWebHost(string[] args)
        {

            return WebHost.CreateDefaultBuilder(args)
                            .UseStartup<Startup>()
                            .UseUrls(new ConfigurationBuilder().SetBasePath(System.IO.Directory.GetCurrentDirectory())
                                .AddJsonFile("appsettings.json")
                                .Build()["ApplicationUrl"]).Build();
        }
{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ApplicationUrl": "http://192.168.1.232:5011"
}

修改一下 lanchSettings.json, 取消通過瀏覽器啟動

{
  "profiles": {
    "Dashboard": {
      "commandName": "Project",
      "launchBrowser": false,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "http://localhost:5012/"
    }
  }
}

 

 解決方案啟動項目設置如下:

 

apigateway項目的ocelot.json的配置:定義了下游兩個服務節點,開啟了服務發現,配置了consul的連接IP和POrt

 {
      "UseServiceDiscovery": true, // do not use Consul service discovery
      "DownstreamPathTemplate": "/master/{url}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "192.168.1.232",
          "Port": "5011"
        },
        {
          "Host": "192.168.1.232",
          "Port": "5012"
        }
      ],
      "ServiceName": "MasterService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "UpstreamPathTemplate": "/master/{url}",
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "RateLimitOptions": {
        "ClientWhitelist": [ "admin" ], // 白名單
        "EnableRateLimiting": true, // 是否啟用限流
        "Period": "1m", // 統計時間段:1s, 5m, 1h, 1d
        "PeriodTimespan": 15, // 多少秒之后客戶端可以重試
        "Limit": 10 // 在統計時間段內允許的最大請求數量
      },
      "QoSOptions": {
        "ExceptionsAllowedBeforeBreaking": 2, // 允許多少個異常請求
        "DurationOfBreak": 5000, // 熔斷的時間,單位為秒
        "TimeoutValue": 3000 // 如果下游請求的處理時間超過多少則視如該請求超時
      },
      "ReRoutesCaseSensitive": false // non case sensitive
    }
"GlobalConfiguration": {
    //"BaseUrl": "https://api.mybusiness.com"
    "ServiceDiscoveryProvider": {
      "Host": "192.168.1.23", // Consul Service IP
      "Port": 8500 // Consul Service Port
    },

 

分別對兩個api加一個健康檢查入口:

        [HttpGet("/master/health")]
        public IActionResult Heathle()
        {
            return Ok();
        }

 

至此,網關和2個API的准備工作完畢。跑起來!

 

 

下面,通過文件方式,向consul注冊服務,在linux上創建一個service.json, 隨便找個地方放一下

{
  "encrypt": "Wd7HAMtcgg5RQ2hZhHE9xw==",
  "services": [
    {
      "id": "api1",
      "name": "MasterService",
      "tags": [ "ApiService" ],
      "address": "192.168.1.232",
      "port": 5011,
      "checks": [
        {
          "id": "ApiServiceA_Check",
          "name": "ApiServiceA_Check",
          "http": "http://192.168.1.232:5011/health",
          "interval": "10s",
          "tls_skip_verify": false,
          "method": "GET",
          "timeout": "1s"
        }
      ]
    },
    {
      "id": "api2",
      "name": "MasterService",
      "tags": [ "ApiService" ],
      "address": "192.168.1.232",
      "port": 5012,
      "checks": [
        {
          "id": "ApiServiceB_Check",
          "name": "ApiServiceB_Check",
          "http": "http://192.168.1.232:5012/health",
          "interval": "10s",
          "tls_skip_verify": false,
          "method": "GET",
          "timeout": "1s"
        }
      ]
    }
  ]
}

運行下面的命令:

consul agent -server -ui -bootstrap-expect=3 -data-dir=/tmp/consul -node=consul-1 -client=0.0.0.0 -bind=0.0.0.0 -datacenter=dc1 -config-dir=/consul/testservices &

 

參數說明:

-server:服務器模式 

-ui:能webui展示 

-bootstrap-expect:server為1時即選擇server集群leader 

-data-dir:consul狀態存儲文件地址 

-config-dir: 剛才放service.json的位置

-node:指定結點名 

-advertise:本地ip地址 

-client:指定可訪問這個服務結點的ip 

& : run as background server

 

再訪問一下 8500

可以看到,兩個節點服務在健康地存在。

訪問一下服務,可以看到節點在來會切變

 

 

下面是實驗最關鍵的一步,讓其中一個節點掛掉,看看服務還能不能繼續,我把 api1,關掉,后面再訪問,一直都是

 

試驗完畢。

 

說明:

1.一開始是也是跟着https://www.cnblogs.com/edisonchou/p/9124985.html來學習的,但因為我沒有那么多虛擬機,就沒辦法按他那方式來做,但他那種才是 貼近生產環境的,具有更高的參考價值。

2.我是奔着試驗的目的,所以參考https://www.cnblogs.com/alan-lin/p/9126155.html來做,基本都是一樣的,惟一不同只是consul的安裝環境而已。

 


免責聲明!

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



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