上一篇 介紹了Ocelot網關和認證服務的結合使用,本篇繼續介紹Ocelot相關請求聚合和Ocelot限流html
Ocelot容許聲明聚合路由,這樣能夠把多個正常的Routes打包並映射到一個對象來對客戶端的請求進行響應。json
例如:在獲取訂單記錄時,也須要查看訂單中對應的商品信息,這裏的數據就來源於兩個微服務:訂單服務、商品服務。若是不使用聚合路由時,對於現實一個訂單信息時,客戶端須要調用兩次服務請求,實際上會形成服務端額外的性能消耗。這是若是配置了聚合路由時,客戶端只須要請求一次聚合路由,而後聚合路由會合並訂單服務和商品服務的請求結果到一個對象中,並返回給客戶端。使用Ocelot的此特性可讓你很容易的實現先後端分離的架構。接下來咱們就來驗證該功能的實現。後端
在ocelot.json中進行以下配置:api
一、爲每一個Route設置一個Key屬性:如:"Key": "Catalog"數組
二、在ocelot.json中添加Aggregates節點,並指定RouteKeys中指定1中設置的Key值組成的數組,並設置UpstreamPathTemplate匹配上游用戶請求;它的工做方式和正常的Route相似。服務器
調整後以下:數據結構
{ "Aggregates": [ { "RouteKeys": [ "Catalog", "Ordering" ], "UpstreamPathTemplate": "/GetOrderDetail/{id}" } ], "GlobalConfiguration": { }, "Routes": [ { "DownstreamPathTemplate": "/api/Values/{id}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 5332 } ], "UpstreamPathTemplate": "/Catalog/{id}", "UpstreamHttpMethod": [ "Get", "Post" ], "LoadBalancerOptions": { "Type": "RoundRobin" }, "Key": "Catalog" }, { "DownstreamPathTemplate": "/api/Values/{id}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 5331 } ], "UpstreamPathTemplate": "/Ordering/{id}", "UpstreamHttpMethod": [ "Get", "Post" ], "LoadBalancerOptions": { "Type": "RoundRobin" }, "Key": "Ordering" } ] }
三、如圖調整項目代碼:返回不一樣結果架構
四、訪問設置的聚合地址結果以下:前後端分離
返回結果爲設置的Key組合的數據結構。async
五、若是服務出現異常會怎麼樣:
a) 若是當某個服務出現異常會返回什麼呢?接下來作個驗證,修改訂單服務返回結果:
public IActionResult Get(int id) { throw new Exception("模擬異常"); }
如圖所示返回的結果和正常是結構是相同的,只是Ordering返回的是異常信息;
b) 若是某個服務宕機,回獲得什麼結果呢?接下來中止了Ordering服務訪問結果以下,獲得502錯誤
六、若是默認的聚合返回的結果數據結構不是咱們想要的,想要修改怎麼辦?答案是使用自定義聚合
a)添加一個自動以聚合器FakeDefinedAggregator, 必須實現IDefinedAggregator接口。這個聚合器的功能很簡單,就是將兩個聚合請求的結果,用逗號拼接起來返回
public class FakeDefinedAggregator : IDefinedAggregator { public FakeDefinedAggregator() { } public async Task<DownstreamResponse> Aggregate(List<HttpContext> responses) { List<string> result = new List<string>(); foreach (var item in responses) { byte[] tmp = new byte[item.Response.Body.Length]; await item.Response.Body.ReadAsync(tmp, 0, tmp.Length); var val = Encoding.UTF8.GetString(tmp); result.Add(val); } var merge = string.Join(";", result.ToArray()); List<Header> headers = new List<Header>(); return new DownstreamResponse(new StringContent(merge), HttpStatusCode.OK, headers, "some reason"); } }
b)註冊自定義聚合器
services.AddOcelot()
.AddSingletonDefinedAggregator<FakeDefinedAggregator>();
c)修改ocelot.json配置文件
"Aggregates": [ { "ReRouteKeys": [ "Orders", "Products" ], "UpstreamPathTemplate": "/GetOrderDetail/{id}",
"Aggregator": "FakeDefinedAggregator" } ]
d)運行結果:
{"id":1,"name":"Api.Catalog1"};{"id":1,"name":"Api.Ordering"}}
一、修改Route節點中的添加以下節點:
"RateLimitOptions": { "ClientWhitelist": [], "EnableRateLimiting": true, "Period": "10m", "PeriodTimespan": 3, "Limit": 1 }
二、在GlobalConfiguration添加以下節點:
//限流 "RateLimitOptions": { "QuotaExceededMessage": "您的請求量超過了配額1/10分鐘", "HttpStatusCode": 999 }
三、配置說明:
在Route和GlobalConfiguration節點中添加了RateLimitOptions節點 ClientWhitelist - 白名單,也就是不受限流控制的客戶端 EnableRateLimiting - 是否開啓限流 Period & Limit - 在一段時間內容許的請求次數 PeriodTimespan - 客戶端的重試間隔數,也就是客戶端間隔多長時間能夠重試 QuotaExceededMessage - 限流之後的提示信息 HttpStatusCode - 超出配額時,返回的http狀態碼
四、配置說明:
客戶端在10分鐘以內只容許請求一次,在請求以後3秒鐘以後能夠重試
一、請求聚合須要爲每一個Route設置一個Key,並設置Aggregates節點指定須要的RouteKeys。
二、請求聚合支持自定義設置返回結果:實現IDefinedAggregator接口,並註冊自定義聚合器;
三、在須要對服務器請求進行限流時,Ocelot也能很好的支持
後續將對Consul介紹,並結合Ocelot使用。