.NET Core + Ocelot:API 网关
關(guān)于 API 網(wǎng)關(guān)的作用,核心是 API 請求的收口及控制,如:鑒權(quán)、限流、熔斷、數(shù)據(jù)緩存 等都是開發(fā)中常見的需求,將此類需求交給網(wǎng)關(guān)層處理,可以使每個微服務(wù)更聚焦于業(yè)務(wù)功能開發(fā),同時也可為下游服務(wù)的安全及穩(wěn)定性保駕護航。
在之前的文章 ?.NET Core + Spring Cloud:API 網(wǎng)關(guān) 有介紹過如何基于 Spring Cloud 中的 Zuul 實現(xiàn) API 網(wǎng)關(guān),功能實現(xiàn)上拋開不提,另外一個較大的特點是 .NET Core 可以完美的擁抱 Java 體系中的部分能力。本文將主要介紹 .NET Core 體系中的 API 網(wǎng)關(guān)框架:Ocelot[1],它包含了 路由、鑒權(quán)、限流、熔斷、服務(wù)發(fā)現(xiàn)、請求聚合等非常豐富的功能,這些功能大多基于少量的配置實現(xiàn),使用起來也并不復雜。
接下來通過簡單例子先跑起來,然后再繼續(xù)延伸更多特性的介紹,下面是 Ocelot 官方給出的一個最基礎(chǔ)的架構(gòu)圖:
外網(wǎng)訪問 Ocelot API 網(wǎng)關(guān)服務(wù)(單例),通過配置的規(guī)則(configuration.json),路由到下游的兩個微服務(wù)實例(Http Service),這也就是最基本的轉(zhuǎn)發(fā)能力。
路由轉(zhuǎn)發(fā)
以下創(chuàng)建的 .NET Core API 服務(wù)均基于 .NET Core 3.1
創(chuàng)建微服務(wù)(ServiceA),并啟動2個實例,兩個實例使用的配置文件設(shè)置不同的 Id,方便后面接口調(diào)用識別不同實例。
[Route("[controller]/[action]")] [ApiController] public class TestController : ControllerBase {public readonly IConfiguration _configuration;public TestController(IConfiguration configuration){_configuration = configuration;}[HttpGet]public string Get(){return $"service-a {_configuration["Id"]}";} }創(chuàng)建網(wǎng)關(guān)服務(wù)
安裝 Ocelot NuGet 包;
創(chuàng)建配置文件 configuration.json,內(nèi)容如下:
{"Routes": [ // 路由規(guī)則定義,數(shù)組{"DownstreamPathTemplate": "/{url}", // 下游路徑匹配模板"DownstreamScheme": "http","DownstreamHostAndPorts": [ // 下游服務(wù)的 host 和 port 設(shè)置,支持多實例{"Host": "192.168.124.11","Port": 8000},{"Host": "192.168.124.11","Port": 8001}],"UpstreamPathTemplate": "/servicea/{url}", // 客戶端訪問地址路徑匹配模板"UpstreamHttpMethod": [ "Get" ], // 支持的 HttpMethod ,如:Get、Post、Put、Delete 等"LoadBalancerOptions": { // 多實例下負載均衡方式,支持:LeastConnection(最閑)、RoundRobin(輪詢)、NoLoadBalance"Type": "RoundRobin"}}] }在 Program.cs 中添加 Ocelot 配置文件引用
public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();webBuilder.UseUrls("http://*:9600");webBuilder.ConfigureAppConfiguration(c =>{c.AddJsonFile("configuration.json");});});在 Startup.cs ?中注冊服務(wù)與管道配置
public void ConfigureServices(IServiceCollection services) {services.AddControllers();services.AddOcelot(); }public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {// ....app.UseOcelot().Wait();app.UseRouting();app.UseEndpoints(endpoints =>{endpoints.MapControllers();}); }
網(wǎng)關(guān)層接口調(diào)用測試 通過以上服務(wù)搭建,就完成了路由轉(zhuǎn)發(fā)的功能,即當訪問 /servicea/{任意路由地址} 都將自動轉(zhuǎn)發(fā)到下游任意一個服務(wù)實例中相匹配的路由地址,網(wǎng)關(guān)服務(wù)訪問地址為:http://192.168.124.11:9600(192.168.124.11 是本機的 IPV4 地址),測試效果如下(下游服務(wù)實例被輪詢訪問):
服務(wù)發(fā)現(xiàn)(Consul)
Ocelot 支持與具備 服務(wù)發(fā)現(xiàn)[2] 功能的一些框架相結(jié)合,如:Consul、Eureka,下游服務(wù)地址可直接從服務(wù)注冊中心進行獲取。接下來將結(jié)合 Consul 進行測試,有關(guān) Consul 與 .NET Core 結(jié)合請參考文章:.NET Core + Consul 服務(wù)注冊與發(fā)現(xiàn) ,這部分內(nèi)容這里就不重復介紹了,最終注冊中心 service-a 有兩個實例,如下:
安裝 Ocelot.Provider.Consul NuGet 包;
Startup.cs 中進行服務(wù)注冊:
services.AddOcelot().AddConsul();configuration.json 配置修改為如下:
{"GlobalConfiguration": {"ServiceDiscoveryProvider": { // 提供服務(wù)發(fā)現(xiàn)的 Provider"Scheme": "http","Host": "192.168.124.9", // Consul 服務(wù) host"Port": 8500, // Consul 服務(wù)端口"Type": "Consul" // 類型}},"Routes": [{"DownstreamPathTemplate": "/{url}","DownstreamScheme": "http","ServiceName": "service-a", // 注冊的服務(wù)名"UpstreamPathTemplate": "/servicea/{url}","UpstreamHttpMethod": [ "Get" ],"LoadBalancerOptions": {"Type": "RoundRobin"}}] }
最終測試結(jié)果與上一部分一致,所以 Ocelot 完全可以與服務(wù)注冊發(fā)現(xiàn)相結(jié)合應(yīng)用到項目中。
限流
為了可以防止因請求過載而引起服務(wù)不穩(wěn)定,可為路由規(guī)則添加相應(yīng)的限流配置,如下:
"RateLimitOptions": {"ClientWhitelist": [ "clientId1" ],"EnableRateLimiting": true,"Period": "5s","PeriodTimespan": 5,"Limit": 5 // 測試設(shè)置比較小 }ClientWhitelist:限流白名單。如上,當請求頭中包含 ClientId=clientId1 的請求則不受限流規(guī)則控制(ClientId key 名可修改)EnableRateLimiting:開啟限流Period:限流控制時間段,也就是多長時間內(nèi)。支持 s(秒)、m(分)、h(小時)、d(天)PeriodTimespan:超過限制次數(shù)后,需要等待的時長(秒)Limit:在 Period 時長內(nèi)最大訪問次數(shù)
當超出限流數(shù)量時,默認返回如下:
如果需要修改返回值及狀態(tài)碼等可以通過修改 GlobalConfiguration 配置中的 RateLimitOptions 參數(shù)。
熔斷
熔斷是結(jié)合 Polly 實現(xiàn)的,在使用之前需要先安裝 Ocelot.Provider.Polly NuGet 包,然后添加服務(wù)注冊,如下:
services.AddOcelot() .AddConsul().AddPolly();路由規(guī)則中增加如下配置:
"QoSOptions": {"ExceptionsAllowedBeforeBreaking": 3,"DurationOfBreak": 5000,"TimeoutValue": 3000 }ExceptionsAllowedBeforeBreaking:允許連續(xù)發(fā)生異常次數(shù)DurationOfBreak:熔斷時長(ms)TimeoutValue:請求超時時間(ms)
當超出允許異常次數(shù)時,接口 5s 內(nèi)都會返回 503:
網(wǎng)關(guān)高可用
API 網(wǎng)關(guān)是所有請求的唯一入口,壓力自然是比較大的,自身的高可用也很關(guān)鍵,所以網(wǎng)關(guān)服務(wù)在部署上必須多實例,網(wǎng)關(guān)上層還需要添加一層 LB,官方架構(gòu)圖如下:
Ocelot 整體主要圍繞配置進行功能擴充,本文只介紹了部分 Ocelot ?的功能,另外還有 鑒權(quán)、緩存、請求合并、與 Kubernetes 結(jié)合等都是非常普遍的功能。
參考資料
[1]
Ocelot: https://github.com/ThreeMammals/Ocelot
[2]服務(wù)發(fā)現(xiàn): https://ocelot.readthedocs.io/en/latest/features/servicediscovery.html
總結(jié)
以上是生活随笔為你收集整理的.NET Core + Ocelot:API 网关的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 初识ABP vNext(3):vue对接
- 下一篇: IT技术人,“三十而已”