.Net Core使用Ocelot网关(一) -负载,限流,熔断,Header转换
1.什么是API網(wǎng)關(guān)
API網(wǎng)關(guān)是微服務(wù)架構(gòu)中的唯一入口,它提供一個(gè)單獨(dú)且統(tǒng)一的API入口用于訪問(wèn)內(nèi)部一個(gè)或多個(gè)API。它可以具有身份驗(yàn)證,監(jiān)控,負(fù)載均衡,緩存,請(qǐng)求分片與管理,靜態(tài)響應(yīng)處理等。API網(wǎng)關(guān)方式的核心要點(diǎn)是,所有的客戶(hù)端和消費(fèi)端都通過(guò)統(tǒng)一的網(wǎng)關(guān)接入微服務(wù),在網(wǎng)關(guān)層處理所有的非業(yè)務(wù)功能。通常,網(wǎng)關(guān)也是提供REST/HTTP的訪問(wèn)API。服務(wù)端通過(guò)API-GW注冊(cè)和管理服務(wù)。
Ocelot介紹
Ocelot是用.net Core實(shí)現(xiàn)的一款開(kāi)源的網(wǎng)關(guān),Ocelot其實(shí)就是一組按照順序排列的.net core中間件。它接受到請(qǐng)求之后用request builder構(gòu)建一個(gè)HttpRequestMessage對(duì)象并發(fā)送到下游服務(wù),當(dāng)下游請(qǐng)求返回到Ocelot管道時(shí)再由一個(gè)中間件將HttpRequestMessage映射到HttpResponse上返回客戶(hù)端。
開(kāi)源地址點(diǎn)擊這里
使用Ocelot傻瓜式轉(zhuǎn)發(fā)
新建三個(gè)項(xiàng)目webApi項(xiàng)目,分別命名為ApiGateway,Api_A,Api_B
設(shè)置Api_A端口為5001,Api_B端口為5002,ApiGateway為5000
為ApiGateway項(xiàng)目安裝Ocelot,在Nuget中搜索Ocelot或者直接使用Install-Package Ocelot進(jìn)行安裝。最新版本為13.8.x支持core3.0。
在ApiGateway新建一個(gè)configuration.json配置文件。
{"ReRoutes": [{//上游Api請(qǐng)求格式"UpstreamPathTemplate": "/Api_A/{controller}/{action}",//網(wǎng)關(guān)轉(zhuǎn)發(fā)到下游格式"DownstreamPathTemplate": "/api/{controller}/{action}",//上下游支持請(qǐng)求方法"UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],"DownstreamScheme": "http",//下游服務(wù)配置"DownstreamHostAndPorts": [{//下游地址"Host": "localhost",//下游端口號(hào)"Port": 5001}]},{"UpstreamPathTemplate": "/Api_B/{controller}/{action}","DownstreamPathTemplate": "/api/{controller}/{action}","UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],"DownstreamScheme": "http","DownstreamHostAndPorts": [{"Host": "localhost","Port": 5002}]}] }在Startup.cs?的ConfigureServices和Configure中配置Ocelot
public void ConfigureServices(IServiceCollection services) {services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);services.AddOcelot(new ConfigurationBuilder().AddJsonFile("configuration.json").Build()); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) {app.UseOcelot();if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseMvc(); }分別為Api_A,和Api_B分別添加一個(gè)print接口。
[HttpGet("print")] public string Print() {return "Api_A"; }[HttpGet("print")] public string Print() {return "Api_B"; }測(cè)試網(wǎng)關(guān)
啟動(dòng)三個(gè)項(xiàng)目,使用postman來(lái)調(diào)用網(wǎng)關(guān)
訪問(wèn)Api_A服務(wù)
訪問(wèn)Api_B服務(wù)
可以看到網(wǎng)關(guān)通過(guò)接受到的請(qǐng)求的Url后通過(guò)我們的配置自動(dòng)轉(zhuǎn)發(fā)到了我們想要訪問(wèn)的服務(wù)。
網(wǎng)關(guān)的負(fù)載均衡
當(dāng)下游擁有多個(gè)節(jié)點(diǎn)的時(shí)候,我們可以用DownstreamHostAndPorts來(lái)配置
{"UpstreamPathTemplate": "/Api_A/{controller}/{action}","DownstreamPathTemplate": "/api/{controller}/{action}","DownstreamScheme": "https","LoadBalancer": "LeastConnection","UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],"DownstreamHostAndPorts": [{"Host": "127.0.0.1","Port": 5001,},{"Host": "127.00.1","Port": 5002,}], }LoadBalancer是來(lái)決定負(fù)載的算法
LeastConnection:將請(qǐng)求發(fā)往最空閑的那個(gè)服務(wù)器
RoundRobin:輪流轉(zhuǎn)發(fā)
NoLoadBalance:總是發(fā)往第一個(gè)請(qǐng)求或者是服務(wù)發(fā)現(xiàn)
限流
限流可以防止上下游服務(wù)器因?yàn)檫^(guò)載而崩潰,可以使用RateLimitOptions來(lái)配置限流
{"RateLimitOptions": {"ClientWhitelist": [“127.0.0.1”],"EnableRateLimiting": true,"Period": "5s","PeriodTimespan": 1,"Limit": 10} }ClientWihteList:白名單,不受限流控制。
EnableRateLimiting:使用啟用限流。
Period:限流控制的時(shí)間段 1s, 5m, 1h, 1d。
PeroidTimeSpan:超過(guò)限流限制的次數(shù)后,需要等待重置的時(shí)間(單位是秒)。
Limit:在限流控制時(shí)間段內(nèi)最大訪問(wèn)數(shù)。
對(duì)于除了請(qǐng)求頭中ClientId=127.0.0.1的意外所有求情啟用限流,5秒該api最多10次,如果達(dá)到10次需要從第10次請(qǐng)求閉合后等待一秒進(jìn)行下一次訪問(wèn)。
超過(guò)限流后會(huì)返回429狀態(tài)碼,并在在返回頭(Response Header)的Retry-After屬性中返回等待重置時(shí)間。
限流的默認(rèn)提示,code碼,和限制標(biāo)志都是可以自己配置的
DisableRateLimitHeaders:是否顯示X-Rate-Limit和Retry-After頭
QuotaExceededMessage:提示信息
HttpStatusCode:狀態(tài)碼
ClientIdHeader:用來(lái)設(shè)別客戶(hù)請(qǐng)求頭,默認(rèn)為ClientId。
BaseUrl 網(wǎng)關(guān)暴露的的地址。
熔斷
熔斷是在下游服務(wù)故障或者請(qǐng)求無(wú)響應(yīng)的時(shí)候停止將請(qǐng)求轉(zhuǎn)發(fā)到下游服務(wù)。
{"QoSOptions": {"ExceptionsAllowedBeforeBreaking": 3,"DurationOfBreak": 20,"TimeoutValue": 5000} }ExceptionsAllowedBeforeBreaking:允許多少個(gè)異常請(qǐng)求。
DurationOfBreak:熔斷的時(shí)間(秒)。
TimeoutValue:下游請(qǐng)求的處理時(shí)間超過(guò)多少則將請(qǐng)求設(shè)置為超時(shí)。
緩存
Ocelot可以對(duì)下游請(qǐng)求結(jié)果進(jìn)行緩存,主要是依賴(lài)于CacheManager來(lái)實(shí)現(xiàn)的。
{"FileCacheOptions": {"TtlSeconds": 60,"Region": "key"} }TtlSeconds:緩存時(shí)間(秒)。
Region:緩存分區(qū)名
我們可以調(diào)用Ocelot的API來(lái)移除某個(gè)區(qū)下面的緩存 。
請(qǐng)求頭的轉(zhuǎn)化
Ocelot允許在請(qǐng)求下游服務(wù)之前和之后轉(zhuǎn)換Header.目前Ocelot只支持查找和替換.
如果們需要轉(zhuǎn)發(fā)給下游的Header重添加一個(gè)key/value
{"UpstreamHeaderTransform": {"demo": "xxxxxxx"} }如果們需要在返回給客戶(hù)端的的Header中添加一個(gè)key/value
{"DownstreamHeaderTransform": {"demo": "xxxxxxx"} }如果我們需要替換Heaher中某些值
{//請(qǐng)求"UpstreamHeaderTransform": {"demo": "a,b"},//響應(yīng)"DownstreamHeaderTransform":{"demo": "a,b"} }語(yǔ)法是{find},{replace}, 利用b取代a
在Header轉(zhuǎn)換中可以使用占位符
{BaseUrl} - 這個(gè)是Ocelot暴露在外的url. 例如http://localhost:5000/.
{DownstreamBaseUrl} - 這個(gè)是下游服務(wù)的基本url 例如http://localhost:5001/. 目前這個(gè)只在DownstreamHeaderTransform中起作用.
{TraceId} - 這個(gè)是Butterfly的跟蹤id.目前這個(gè)也只在DownstreamHeaderTransform中起作用
如果您想將location頭返回給客戶(hù)端,可能需要將location更改為Ocelot的地址而不是下游服務(wù)地址。Ocelot可以使用以下配置實(shí)現(xiàn)。
{"DownstreamHeaderTransform": {"Location": "{DownstreamBaseUrl},{BaseUrl}"}, }給Header中添加下游地址
響應(yīng)的Header中已經(jīng)替換成BaseUrl了
總結(jié)
簡(jiǎn)單的實(shí)現(xiàn)了通過(guò)網(wǎng)關(guān)來(lái)訪問(wèn)api接口。ocelot功能遠(yuǎn)不止這些,之后會(huì)實(shí)現(xiàn)與IdentityServer的認(rèn)證鑒權(quán)。服務(wù)發(fā)現(xiàn)。
總結(jié)
以上是生活随笔為你收集整理的.Net Core使用Ocelot网关(一) -负载,限流,熔断,Header转换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何让 Azure AD 里的应用只允许
- 下一篇: [Asp.net core 3.1] 通