天天看點

Ocelot + Consul 搭建關鍵點 主要要關注是以下的坑

Ocelot 的【限流】【熔斷】  【負載均衡】等基礎功能已經實作,比較難實作的是Ocelot內建Consul這個服務發現以及服務治理,原來裡面有幾個比較隐秘的坑,廢話不多說,上代碼,中間有可能需要引用對應的dll

using Ocelot.Cache.CacheManager;

using Ocelot.DependencyInjection;

using Ocelot.Middleware;

using Ocelot.Provider.Consul;

using Ocelot.Provider.Polly;

 Ocelot搭建

 首先在Program.cs引用Ocelot 

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration(conf => conf.AddJsonFile("ocelot.json", false, true))
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
           

然後在Startup.cs注入Ocelot 

public void ConfigureServices(IServiceCollection services)
        {
            //services.AddControllers();
            services.AddOcelot(Configuration).AddPolly().AddConsul().AddCacheManager(u=>u.WithDictionaryHandle()); //AddPolly 負責熔斷
        }

**************************************************
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseOcelot().Wait();
        }
           

 附上Ocelot.json檔案寫法,裡面有對應的注釋。

{
  "Routes": [
    {
      "UpstreamPathTemplate": "/api/user/{url}",
      "DownstreamPathTemplate": "/{url}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "47.XX.XX.XX",
          "Port": 8080
        }
      ],
      "UpstreamHttpMethod": [
        "Get",
        "Post"
      ]
    },
    {
      "UpstreamPathTemplate": "/api/server/{url}",
      "DownstreamPathTemplate": "/{url}",
      "DownstreamScheme": "http",
      "UseServiceDiscovery": true,
      "ServiceName": "HelloServer", //ServiceName 服務名稱要跟Consul的服務名稱一緻【ServiceName DownstreamHostAndPorts】不可以同時為空,也不可以同時存在
      "Key": "server", //聲明聚合路由
      //"DownstreamHostAndPorts": [ //使用服務發現後需要注釋掉
      //  {
      //    "Host": "localhost",
      //    "Port": 8082
      //  },
      //  {
      //    "Host": "localhost",
      //    "Port": 8083
      //  }
      //],
      "UpstreamHttpMethod": [
        "Get",
        "Post"
      ],
      "LoadBalancerOptions": {
        "Type": "RoundRobin" //負載均衡,輪詢機制 LeastConnection/RoundRobin/NoLoadBalancer/CookieStickySessions
      },
      "ReRouteIsCaseSensitive": false, //重寫路由是否區分大小寫
      //緩存
      //"FileCacheOptions": {
      //  "TtlSeconds": 30, //緩存時間(秒)
      //  "Region": "CacheArea" //緩存區(名稱自定義),表示改配置緩存放到哪個區域,可以在配置管理中進行維護
      //},
      //限流
      "RateLimitOptions": {
        "ClientWhitelist": [], //數組中的客戶機不會受到路由限制的影響使用方式:在用戶端請求頭中添加key:ClientId,value為網關配置白名單。
        "EnableRateLimiting": true, //是否啟用路由限制。
        "Period": "1s", //指定周期,如1s、5m、1h、1d等。
        "PeriodTimespan": 1, //指定我們可以在一定秒數後重試【限流後多久可以重試】。
        "Limit": 1 //指定用戶端在定義的時間段内可以發出的最大請求數
      }

    }
  ],
  "GlobalConfiguration": {
    //"BaseUrl": "http://localhost:9070"
    //全局限流
    "RateLimitOptions": {
      "DisableRateLimitHeaders": false,
      "QuotaExceededMessage": "Customize Tips!", //限流傳回的資訊。
      "HttpStatusCode": 999 //限流傳回狀态碼
    },
    //服務發現
    "ServiceDiscoveryProvider": {
      "Host": "localhost", //上線後需要取線上位址
      "Port": 8500,
      "Token": "footoken",
      "Provider": "consul", //Consul PollConsul
      "PollingInterval": 100
    },
    //服務品質  熔斷?
    "QoSOptions": {
      "ExceptionsAllowedBeforeBreaking": 2, //在熔斷之前允許的異常次數
      "DurationOfBreak": 5000, //熔斷時長 ,機關毫秒
      "TimeoutValue": 2000 //請求逾時設定, 機關毫秒
    }
  }
}
           

 主要要關注是以下的坑

  1. Ocelot 最新版本的V17.0的Routes跟以前版本不一樣,以前版本是ReRoutes
  2. "UseServiceDiscovery": true  開啟服務發現的時候需要定義ServerName,ServerName的名字需要跟Consul的服務名字一緻,同時需要注釋DownstreamHostAndPorts,如果不開啟服務發現"UseServiceDiscovery": false 的話需要定義DownstreamHostAndPorts,否則将會報錯
Consul搭建

 建立一個demo項目,appsettings.json新增Consul配置

"Consul": {
    "ServiceName": "HelloServer",
    "ServiceIP": "localhost",
    "ServicePort": 8082,
    "Tags": "Server_Tag1,Server_Tag2",
    "ServiceHealthCheck": "http://localhost:8082/Heather/HealthCheck",
    "ConsulAddress": "http://localhost:8500"
  }
           
Ocelot + Consul 搭建關鍵點 主要要關注是以下的坑
string serverName = Configuration.GetSection("Consul:ServiceName").Value;
            string clientUrl = Configuration.GetSection("Consul:ConsulAddress").Value;
            string agentIP = Configuration.GetSection("Consul:ServiceIP").Value;
            string port = Configuration.GetSection("Consul:ServicePort").Value;
            string heartbeatUrl = Configuration.GetSection("Consul:ServiceHealthCheck").Value;
            string tags = Configuration.GetSection("Consul:Tags").Value;
            var agentTags = new string[] { };
            if (!string.IsNullOrEmpty(tags))
            {
                agentTags = tags.Split(',');
            }

            ConsulClient client = new ConsulClient(obj =>
            {
                obj.Address = new Uri(clientUrl);
                obj.Datacenter = serverName;
            });

            client.Agent.ServiceRegister(new AgentServiceRegistration()
            {
                ID = $"{serverName}_{Guid.NewGuid()}",
                Name = serverName,
                Address = agentIP,
                Port = Convert.ToInt32(port),
                Tags = agentTags,
                Check = new AgentServiceCheck()
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                    Interval = TimeSpan.FromSeconds(15),
                    HTTP = heartbeatUrl,
                    Timeout = TimeSpan.FromSeconds(5)
                }
            }).Wait();
           
Ocelot + Consul 搭建關鍵點 主要要關注是以下的坑

 接着建立心跳Controller

   [ApiController]

    [Route("[controller]/[action]")]

    public abstract class AbstractController : ControllerBase

    {

    }

public class HeatherController: AbstractController

    {

        [HttpGet]

        public IActionResult HealthCheck()

        {

            return Ok();

        }

    }

将Demo打包運作即可

繼續閱讀