【微服務No.4】 API網關組件Ocelot+Consul

介紹:html

Ocelot是一個.NET API網關。該項目針對的是使用.NET運行微服務/面向服務架構的人員,他們須要一個統一的入口進入他們的系統。然而,它能夠處理任何說HTTP並在ASP.NET Core支持的任何平臺上運行的任何東西。web

Ocelot是一組按特定順序的中間件,Ocelot操縱HttpRequest對象進入由其配置指定的狀態,直到它到達請求生成器中間件,在該中間件中建立HttpRequestMessage對象,該對象用於向下遊服務發出請求。提出請求的中間件是Ocelot管道中的最後一件事。它不叫下一個中間件。來自下游服務的響應存儲在每一個請求做用域存儲庫中,並在請求返回到Ocelot管道時進行恢復。有一件中間件將HttpResponseMessage映射到HttpResponse對象上,並返回給客戶端。這基本上是與其餘一些功能。算法

Ocelot只能用於.NET Core,而且目前已經構建到netstandard2.0。全部下面 咱們使用.NET Core 2.1作演示。編程

建立一個基本示例:

首先咱們建立一個.NET Core 2.1空項目。json

固然咱們仍是要先引用的拉, Nuget 命令行: Install-Package Ocelotwindows

配置:添加一個json文件實現最基本的配置:api

{
    "ReRoutes": [],
    "GlobalConfiguration": {
        "BaseUrl": "urladdress"
    }
}

這裏最重要的是BaseUrl。Ocelot須要知道它正在運行的URL,以便執行標題查找和替換以及某些管理配置。當設置這個URL時,它應該是客戶端將看到的Ocelot運行的外部URL。數組

而後咱們將剛纔的配置文件加入到ASP.NET Core Configuration:Program.cs緩存

 public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                   .ConfigureAppConfiguration((hostingContext, builder) =>
                   {
                       builder
                       .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                       .AddJsonFile("ocelot.json");
                   })
                .UseStartup<Startup>();
View Code

最後在添加服務以及設置中間件:Startup.cs架構

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddOcelot();//添加ocelot服務
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseOcelot().Wait();//設置全部的Ocelot中間件
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }
    }
View Code

 這些就是基本的所需編程代碼。

配置文件的詳細分析:

Ocelot的主要功能是收取HTTP請求並將它們轉發到下游服務。目前以另外一個http請求的形式出現。Ocelot描述了將一個請求做爲ReRoute路由到另外一個請求。爲了在Ocelot中得到任何工做,您須要在配置中設置ReRoute。

說道這裏咱們補充一下剛纔寫的json文件的兩個根節點:ReRoutes和GlobalConfiguration。

    ReRoutes:是一個數組,其中的每個元素表明了一個路由,咱們能夠針對每個路由進行以上功能配置,告訴Ocelot如何處理上游請求的對象。

    GlobalConfiguration:全局配置,能夠適當的節約配置,好比baseurl節點,服務發現配置。

這樣咱們就實現了經過配置文件能夠完成對Ocelot的功能配置:路由、服務聚合、服務發現、認證、鑑權、限流、熔斷、緩存、Header頭傳遞等。

配置一個示例:下面這個配置信息就是將用戶的請求 /ProductService/1 轉發到 localhost:8001/api/Test/1

{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/Test/{postId}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "127.0.0.1",
          "Port": 8001
        }
      ],
      "UpstreamPathTemplate": "/ProductService/{postId}",
      "UpstreamHttpMethod": [ "Get", "Delete" ]
    }
  ],
  "GlobalConfiguration": {
   // "BaseUrl": "http://127.0.0.1:8887/"
  }
}
View Code
  • DownstreamPathTemplate:下游方位url路徑
  • DownstreamScheme:下游服務http schema
  • DownstreamHostAndPorts:下游服務的地址,若是使用LoadBalancer的話這裏能夠填多項
  • UpstreamPathTemplate: 上游也就是用戶輸入的請求Url模板
  • UpstreamHttpMethod: 上游請求http方法,可以使用數組:Get ,Delete等

好了這樣就實現了一個基本的Ocelot網關的轉發示例。

下面讓咱們來看一下效果吧:

首先咱們運行起來webapi項目發佈在8001端口。而後訪問地址是:http://127.0.0.1:8001/api/Test/5

咱們看到的結果是:

而後咱們啓動咱們的網關服務;發佈在端口8888下,根據以上配置咱們能夠看到方位地址爲:http://127.0.0.1:8888/ProductService/5

而後一樣的請求結果是:

這樣咱們就實現使用統一網關來訪問不一樣的地址,以便咱們之後實現微服務的分發部署,雖然是否是多個接口,可是咱們給上游訪問仍是提供一個接口,咱們內部實現訪問該訪問那個接口。

至於具體怎發佈也可參考這篇文章:http://www.cnblogs.com/yanbigfeg/p/9198345.html

路由小知識:

UpstreamHost=>"UpstreamHost": "baidu.com":上游主機

    此功能容許您基於上游主機進行ReRoutes。這經過查看客戶端使用的主機頭來工做,而後將其用做咱們用來識別ReRoute的信息的一部分。這樣就是顯示了只有在主機頭值爲baidu.com時纔會匹配。

Priority=> "Priority": 0:優先級

    此功能設置訪問路由的優先級,假設在同一個路由下有多個路由,會根據優先級匹配優先級最高的,0是最低的。

Dynamic Routing:動態路由

    這個主要是爲了服務發現而實現的,在這種模式下,Ocelot將使用上游路徑的第一個分段來查找服務發現提供商的下游服務。官網給出的大概配置效果:

{
    "ReRoutes": [],
    "Aggregates": [],
    "GlobalConfiguration": {
        "RequestIdKey": null,
        "ServiceDiscoveryProvider": {
            "Host": "localhost",
            "Port": 8510,
            "Type": null,
            "Token": null,
            "ConfigurationKey": null
        },
        "RateLimitOptions": {
            "ClientIdHeader": "ClientId",
            "QuotaExceededMessage": null,
            "RateLimitCounterPrefix": "ocelot",
            "DisableRateLimitHeaders": false,
            "HttpStatusCode": 429
        },
        "QoSOptions": {
            "ExceptionsAllowedBeforeBreaking": 0,
            "DurationOfBreak": 0,
            "TimeoutValue": 0
        },
        "BaseUrl": null,
            "LoadBalancerOptions": {
            "Type": "LeastConnection",
            "Key": null,
            "Expiry": 0
        },
        "DownstreamScheme": "http",
        "HttpHandlerOptions": {
            "AllowAutoRedirect": false,
            "UseCookieContainer": false,
            "UseTracing": false
        }
    }
}
View Code

Ocelot實現多個端口的輪詢:

以上實現的這個有什麼用啊,單獨發佈了接口,而後使用另一個接口去複製他嗎?別急,這只是其中的一個基本使用,如今咱們有了基本步驟,咱們改一改,實現webapi發佈兩個接口,8001,8002.而後還使用網關地址訪問,能夠循環的訪問到8001端口和8002端口。

提及來簡單,作起來也簡單,咱們只須要在咱們上面的配置上修改一下便可:

{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/Test/{postId}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "127.0.0.1",
          "Port": 8001
        },
        {
          "Host": "127.0.0.1",
          "Port": 8002
        }
      ],
      "UpstreamPathTemplate": "/ProductService/{postId}",
      "UpstreamHttpMethod": [ "Get" ],
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      }
    }
  ],
  "GlobalConfiguration": {
    // "BaseUrl": "http://127.0.0.1:8887/"
  }
}
View Code

啓動兩個端口:

重複請求網關兩次結果:

Ocelot+ Consul:

實現目標:啓動服務發現而後模擬集羣發佈功能,實現發佈端口8001,8002後,啓動服務發現,而後配置Ocelot網關。實現訪問統一接口能夠輪詢訪問8001,8002,8001,8002,...這樣。而後能夠在添加8003,繼續規則。

實現以上目標咱們不須要該咱們的示例代碼,只須要修改配置json文件便可:

{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/Test/{postId}",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/Product123Service/{postId}",
      "UpstreamHttpMethod": [ "Get" ],
      "ServiceName": "ProductService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "UseServiceDiscovery": true
    }
  ],
  "GlobalConfiguration": {
    // "BaseUrl": "http://127.0.0.1:8887/"
    "ServiceDiscoveryProvider": {
      "Host": "localhost",
      "Port": 8500,
      "Type": "PollConsul",
      "PollingInterval": 100
    }
  }
}
View Code

這個就是咱們的服務功能:

Ocelot容許您指定服務發現提供程序,並使用它來查找Ocelot正在將請求轉發給下游服務的主機和端口。目前,這僅在GlobalConfiguration部分中受支持,這意味着將爲全部的ReRoute使用相同的服務發現提供程序,以便在ReRoute級別指定ServiceName。

  • ServiceName:consul的服務名稱
  • LoadBalancerOptions:使用的算法,目前有兩種RoundRobin(輪詢方式)和LeastConnection(最小鏈接)
  • UseServiceDiscovery:是否啓用服務發現功能 true:爲啓動
  • ServiceDiscoveryProvider:配置服務發現的一些配置
  • Host:主機地址
  • Port:端口
  • PollingInterval:輪詢的間隔時間,以毫秒爲單位。並告訴Ocelot多久能夠向Consul調用服務配置的更改

想要了解更多能夠訪問Ocelot官網:http://ocelot.readthedocs.io/en/latest/features/servicediscovery.html

系列目錄:

微服務系列文章主要介紹微服務所使用到的一些技術和一些技術示例:

相關文章
相關標籤/搜索