1. 程式人生 > >.Net Core微服務入門全紀錄(五)——Ocelot-API閘道器(下)

.Net Core微服務入門全紀錄(五)——Ocelot-API閘道器(下)

# 前言 上一篇【[.Net Core微服務入門全紀錄(四)——Ocelot-API閘道器(上)](https://www.cnblogs.com/xhznl/p/13092535.html)】已經完成了Ocelot閘道器的基本搭建,實現了服務入口的統一。當然,這只是API閘道器的一個最基本功能,它的進階功能還有很多很多。 # 服務發現 首先需要解決的就是服務發現的問題,服務發現的優點之前講過,就不說了。 上一篇中我們的服務地址都是寫在ocelot.json配置檔案裡,現在我們需要結合之前的Consul來實現服務發現。 - 改造程式碼: 首先NuGet安裝`Ocelot.Provider.Consul`: ![](https://img2020.cnblogs.com/blog/610959/202006/610959-20200615213448863-1043664447.png) 修改Startup.cs: ``` public void ConfigureServices(IServiceCollection services) { //新增ocelot服務 services.AddOcelot() .AddConsul();//新增consul支援 } ``` 修改ocelot.json配置: ``` { "Routes": [ { "DownstreamPathTemplate": "/products", "DownstreamScheme": "http", "UpstreamPathTemplate": "/products", "UpstreamHttpMethod": [ "Get" ], "ServiceName": "ProductService", "LoadBalancerOptions": { "Type": "RoundRobin" } }, { "DownstreamPathTemplate": "/orders", "DownstreamScheme": "http", "UpstreamPathTemplate": "/orders", "UpstreamHttpMethod": [ "Get" ], "ServiceName": "OrderService", "LoadBalancerOptions": { "Type": "RoundRobin" } } ], "GlobalConfiguration": { "BaseUrl": "http://localhost:9070", "ServiceDiscoveryProvider": { "Scheme": "http", "Host": "localhost", "Port": 8500, "Type": "Consul" } } } ``` 這個配置應該很好理解,就是把我們上次的DownstreamHostAndPorts節點去掉了,然後增加了ServiceDiscoveryProvider服務發現相關配置。 注意,Ocelot除了支援Consul服務發現以外,還有Eureka也可以,Eureka也是一個類似的註冊中心。 好了,程式碼修改就差不多了,下面執行程式測試一下: ![](https://img2020.cnblogs.com/blog/610959/202006/610959-20200615221633113-1526943266.png) ![](https://img2020.cnblogs.com/blog/610959/202006/610959-20200615221920176-9130658.gif) 客戶端正常執行。 至此我們就實現了服務註冊與發現和api閘道器的基本功能。接下來就要提到:**服務治理** # 服務治理 其實服務治理也沒有一個非常明確的定義。它的作用簡單來說,就是幫助我們更好的管理服務,提升服務的可用性。——快取,限流,熔斷,鏈路追蹤 等等。。。都屬於常用的服務治理手段。 之前講的負載均衡,服務發現也可以算是服務治理。 - 快取: 在Ocelot中啟用快取,需要NuGet安裝一下`Ocelot.Cache.CacheManager`: ![](https://img2020.cnblogs.com/blog/610959/202006/610959-20200616201422921-1718170282.png) 修改Startup.cs中的ConfigureServices()方法: ``` //新增ocelot服務 services.AddOcelot() //新增consul支援 .AddConsul() //新增快取 .AddCacheManager(x => { x.WithDictionaryHandle(); }); ``` 修改ocelot.json配置檔案: ``` { "Routes": [ { "DownstreamPathTemplate": "/products", "DownstreamScheme": "http", "UpstreamPathTemplate": "/products", "UpstreamHttpMethod": [ "Get" ], "ServiceName": "ProductService", "LoadBalancerOptions": { "Type": "RoundRobin" }, "FileCacheOptions": { "TtlSeconds": 5, "Region": "regionname" } }, { "DownstreamPathTemplate": "/orders", "DownstreamScheme": "http", "UpstreamPathTemplate": "/orders", "UpstreamHttpMethod": [ "Get" ], "ServiceName": "OrderService", "LoadBalancerOptions": { "Type": "RoundRobin" }, "FileCacheOptions": { "TtlSeconds": 5, "Region": "regionname" } } ], "GlobalConfiguration": { "BaseUrl": "http://localhost:9070", "ServiceDiscoveryProvider": { "Scheme": "http", "Host": "localhost", "Port": 8500, "Type": "Consul" } } } ``` 在Routes路由配置中增加了FileCacheOptions。TtlSeconds代表快取的過期時間,Region代表緩衝區名稱,這個我們目前用不到。 好了,程式碼修改完需要編譯重啟一下閘道器專案,然後開啟客戶端網站測試一下: ![](https://img2020.cnblogs.com/blog/610959/202006/610959-20200616203849105-1496099469.gif) 可以看到,5秒之內的請求都是同樣的快取資料。Ocelot也支援自定義快取。 - 限流: 限流就是限制客戶端一定時間內的請求次數。 繼續修改配置: ``` { "Routes": [ { "DownstreamPathTemplate": "/products", "DownstreamScheme": "http", "UpstreamPathTemplate": "/products", "UpstreamHttpMethod": [ "Get" ], "ServiceName": "ProductService", "LoadBalancerOptions": { "Type": "RoundRobin" }, "FileCacheOptions": { "TtlSeconds": 5, "Region": "regionname" }, "RateLimitOptions": { "ClientWhitelist": [ "SuperClient" ], "EnableRateLimiting": true, "Period": "5s", "PeriodTimespan": 2, "Limit": 1 } }, { "DownstreamPathTemplate": "/orders", "DownstreamScheme": "http", "UpstreamPathTemplate": "/orders", "UpstreamHttpMethod": [ "Get" ], "ServiceName": "OrderService", "LoadBalancerOptions": { "Type": "RoundRobin" }, "FileCacheOptions": { "TtlSeconds": 5, "Region": "regionname" }, "RateLimitOptions": { "ClientWhitelist": [ "SuperClient" ], "EnableRateLimiting": true, "Period": "5s", "PeriodTimespan": 2, "Limit": 2 } } ], "GlobalConfiguration": { "BaseUrl": "http://localhost:9070", "ServiceDiscoveryProvider": { "Scheme": "http", "Host": "localhost", "Port": 8500, "Type": "Consul" }, "RateLimitOptions": { "DisableRateLimitHeaders": false, "QuotaExceededMessage": "too many requests...", "HttpStatusCode": 999, "ClientIdHeader": "Test" } } } ``` 在Routes路由配置中增加了RateLimitOptions。ClientWhitelist代表客戶端白名單,在白名單中的客戶端可以不受限流的影響;EnableRateLimiting代表是否限流;Period代表限流的單位時間,例如1s,5m,1h,1d等;PeriodTimespan代表客戶端達到請求上限多少秒後可以重試;Limit代表客戶端在定義的時間內可以發出的最大請求數。 在GlobalConfiguration配置中也增加了RateLimitOptions。DisableRateLimitHeaders代表是否禁用X-Rate-Limit和Retry-After標頭(請求達到上限時response header中的限制數和多少秒後能重試);QuotaExceededMessage:代表請求達到上限時返回給客戶端的訊息;HttpStatusCode:代表請求達到上限時返回給客戶端的HTTP狀態程式碼。ClientIdHeader可以允許自定義用於標識客戶端的標頭。預設情況下為“ ClientId”。 最重要的就是Period,PeriodTimespan,Limit這幾個配置。 重新編譯啟動看一下效果: ![](https://img2020.cnblogs.com/blog/610959/202006/610959-20200616211944189-440946732.gif) - 超時/熔斷 超時很好理解,就是閘道器請求服務時可容忍的最長響應時間。熔斷的意思就是當請求某個服務的異常次數達到一定量時,那麼閘道器在一定時間內就不再對這個服務發起請求了,直接熔斷。 Ocelot中啟用 超時/熔斷 需要NuGet安裝一下`Ocelot.Provider.Polly`: ![](https://img2020.cnblogs.com/blog/610959/202006/610959-20200616214037176-1072442140.png) 修改Startup.cs中的ConfigureServices()方法: ``` //新增ocelot服務 services.AddOcelot() //新增consul支援 .AddConsul() //新增快取 .AddCacheManager(x => { x.WithDictionaryHandle(); }) //新增Polly .AddPolly(); ``` 同樣的在ocelot.json路由配置中增加QoSOptions: ``` "QoSOptions": { "ExceptionsAllowedBeforeBreaking": 3, "DurationOfBreak": 10000, "TimeoutValue": 5000 } ``` ExceptionsAllowedBeforeBreaking代表發生錯誤的次數,DurationOfBreak代表熔斷時間,TimeoutValue代表超時時間。 以上的配置意思就是當服務發生3次錯誤時,那麼就熔斷10秒,期間客戶端的請求直接返回錯誤,10秒之後恢復。 這個不太好模擬,就不演示了,應該也挺好理解的。 。。。。。。 關於服務治理的學問還有很多,不繼續了。。。就到此為止吧。 想要更深入瞭解Ocelot的,請看官網:https://ocelot.readthedocs.io/en/latest/ 或者看原始碼:https://github.com/ThreeMammals/Ocelot 下一篇準備說一下:事件匯流排。 程式碼放在:https://github.com/xiajingren/NetCoreMicroserviceDemo 未完待續...