介紹:
Ocelot是一個.NET API網關。該項目針對的是使用.NET運行微服務/面向服務架構的人員,他們需要一個統一的入口進入他們的系統。然而,它可以處理任何說HTTP並在ASP.NET Core支持的任何平台上運行的任何東西。
Ocelot是一組按特定順序的中間件,Ocelot操縱HttpRequest對象進入由其配置指定的狀態,直到它到達請求生成器中間件,在該中間件中創建HttpRequestMessage對象,該對象用於向下游服務發出請求。提出請求的中間件是Ocelot管道中的最后一件事。它不叫下一個中間件。來自下游服務的響應存儲在每個請求作用域存儲庫中,並在請求返回到Ocelot管道時進行恢復。有一件中間件將HttpResponseMessage映射到HttpResponse對象上,並返回給客戶端。這基本上是與其他一些功能。
Ocelot只能用於.NET Core,並且目前已經構建到netstandard2.0。所有下面 我們使用.NET Core 2.1做演示。
創建一個基本示例:
首先我們創建一個.NET Core 2.1空項目。
當然我們還是要先引用的拉, Nuget 命令行: Install-Package Ocelot
配置:添加一個json文件實現最基本的配置:
{ "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>();
最后在添加服務以及設置中間件: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!"); }); } }
這些就是基本的所需編程代碼。
配置文件的詳細分析:
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/" } }
- 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 } } }
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/" } }
啟動兩個端口:
重復請求網關兩次結果:
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 } } }
這個就是我們的服務功能:
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
系列目錄:
微服務系列文章主要介紹微服務所使用到的一些技術和一些技術示例: