微信版网站开发,php钓鱼网站怎么做视频教程,充值网站架设,商标设计注册一条龙价格Ocelot是一个用.NET Core实现并且开源的API网关#xff0c;它功能强大#xff0c;包括了#xff1a;路由、请求聚合、服务发现、认证、鉴权、限流熔断、并内置了负载均衡器与Service Fabric、Butterfly Tracing集成。这些功能只都只需要简单的配置即可完成#xff0c;下面我… Ocelot是一个用.NET Core实现并且开源的API网关它功能强大包括了路由、请求聚合、服务发现、认证、鉴权、限流熔断、并内置了负载均衡器与Service Fabric、Butterfly Tracing集成。这些功能只都只需要简单的配置即可完成下面我们会对这些功能的配置一一进行说明。介绍简单的来说Ocelot是一堆的asp.net core middleware组成的一个管道。当它拿到请求之后会用一个request builder来构造一个HttpRequestMessage发到下游的真实服务器等下游的服务返回response之后再由一个middleware将它返回的HttpResponseMessage映射到HttpResponse上。API网关—— 它是系统的暴露在外部的一个访问入口。这个有点像代理访问的家伙就像一个公司的门卫承担着寻址、限制进入、安全检查、位置引导、等等功能。Ocelot的基本使用用一台web service来host Ocelot在这里有一个json配置文件里面设置了所有对当前这个网关的配置。它会接收所有的客户端请求并路由到对应的下游服务器进行处理再将请求结果返回。而这个上下游请求的对应关系也被称之为路由。集成Identity Server当我们涉及到认证和鉴权的时候我们可以跟Identity Server进行结合。当网关需要请求认证信息的时候会与Identity Server服务器进行交互来完成。网关集群只有一个网关是很危险的也就是我们通常所讲的单点只要它挂了所有的服务全挂。这显然无法达到高可用所以我们也可以部署多台网关。当然这个时候在多台网关前你还需要一台负载均衡器。Consul 服务发现在Ocelot已经支持简单的负载功能也就是当下游服务存在多个结点的时候Ocelot能够承担起负载均衡的作用。但是它不提供健康检查服务的注册也只能通过手动在配置文件里面添加完成。这不够灵活并且在一定程度下会有风险。这个时候我们就可以用Consul来做服务发现它能与Ocelot完美结合。集成网关在asp.net core 2.0里通过nuget即可完成集成或者命令行dotnet add package Ocelot以及通过vs2017 UI添加Ocelot nuget引用都可以。Install-Package Ocelot配置我们需要添加一个.json的文件用来添加Ocelot的配置以下是最基本的配置信息。{ReRoutes: [],GlobalConfiguration: {BaseUrl: https://api.mybusiness.com}
}要特别注意一下BaseUrl是我们外部暴露的Url比如我们的Ocelot运行在http://123.111.1.1的一个地址上但是前面有一个 nginx绑定了域名http://api.jessetalk.cn那这里我们的BaseUrl就是 http://api.jessetalk.cn。将配置文件加入ASP.NET Core Configuration我们需要通过WebHostBuilder将我们添加的json文件添加进asp.net core的配置public static IWebHost BuildWebHost(string[] args) WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration( (hostingContext,builder) { builder .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath) .AddJsonFile(Ocelot.json); }) .UseStartupStartup() .Build(); 配置依赖注入与中间件在startup.cs中我们首先需要引用两个命名空间using Ocelot.DependencyInjection;using Ocelot.Middleware;接下来就是添加依赖注入和中间件public void ConfigureServices(IServiceCollection services) { services.AddOcelot(); }public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseOcelot().Wait(); }Ocelot功能介绍通过配置文件可以完成对Ocelot的功能配置路由、服务聚合、服务发现、认证、鉴权、限流、熔断、缓存、Header头传递等。在配置文件中包含两个根节点ReRoutes和GlobalConfiguration。ReRoutes是一个数组其中的每一个元素代表了一个路由我们可以针对每一个路由进行以上功能配置。下面是一个完整的路由配置{DownstreamPathTemplate: /,UpstreamPathTemplate: /,UpstreamHttpMethod: [ Get ], AddHeadersToRequest: {}, AddClaimsToRequest: {}, RouteClaimsRequirement: {}, AddQueriesToRequest: {}, RequestIdKey: , FileCacheOptions: { TtlSeconds: 0, Region: }, ReRouteIsCaseSensitive: false, ServiceName: , DownstreamScheme: http, DownstreamHostAndPorts: [ { Host: localhost, Port: 51876, } ], QoSOptions: { ExceptionsAllowedBeforeBreaking: 0, DurationOfBreak: 0, TimeoutValue: 0 }, LoadBalancer: , RateLimitOptions: { ClientWhitelist: [], EnableRateLimiting: false, Period: , PeriodTimespan: 0, Limit: 0 }, AuthenticationOptions: { AuthenticationProviderKey: , AllowedScopes: [] }, HttpHandlerOptions: { AllowAutoRedirect: true, UseCookieContainer: true, UseTracing: true }, UseServiceDiscovery: false }Downstream是下游服务配置UpStream是上游服务配置Aggregates 服务聚合配置ServiceName, LoadBalancer, UseServiceDiscovery 配置服务发现AuthenticationOptions 配置服务认证RouteClaimsRequirement 配置Claims鉴权RateLimitOptions为限流配置FileCacheOptions 缓存配置QosOptions 服务质量与熔断DownstreamHeaderTransform头信息转发我们接下来将对这些功能一一进行介绍和配置路由路由是API网关最基本也是最核心的功能、ReRoutes下就是由多个路由节点组成。{ReRoutes: []
}而每一个路由由以下几个基本信息组成下面这个配置信息就是将用户的请求 /post/1 转发到 localhost/api/post/1{DownstreamPathTemplate: /api/post/{postId},DownstreamScheme: https,DownstreamHostAndPorts: [ { Host: localhost, Port: 80, } ], UpstreamPathTemplate: /post/{postId}, UpstreamHttpMethod: [ Get] }DownstreamPathTemplate下游戏DownstreamScheme下游服务http schemaDownstreamHostAndPorts下游服务的地址如果使用LoadBalancer的话这里可以填多项UpstreamPathTemplate: 上游也就是用户输入的请求Url模板UpstreamHttpMethod: 上游请求http方法可使用数组万能模板万能模板即所有请求全部转发UpstreamPathTemplate 与DownstreamPathTemplate 设置为 “/{url}”{DownstreamPathTemplate: /{url},DownstreamScheme: https,DownstreamHostAndPorts: [ { Host: localhost, Port: 80, } ], UpstreamPathTemplate: /{url}, UpstreamHttpMethod: [ Get ] }万能模板的优先级最低只要有其它的路由模板其它的路由模板则会优先生效。上游Host上游Host也是路由用来判断的条件之一由客户端访问时的Host来进行区别。比如当a.jesetalk.cn/users/{userid}和b.jessetalk.cn/users/{userid}两个请求的时候可以进行区别对待。{DownstreamPathTemplate: /,DownstreamScheme: https,DownstreamHostAndPorts: [ { Host: 10.0.10.1, Port: 80, } ], UpstreamPathTemplate: /, UpstreamHttpMethod: [ Get ], UpstreamHost: a.jessetalk.cn }Prioirty优先级对多个产生冲突的路由设置优化级{UpstreamPathTemplate: /goods/{catchAll} Priority: 0
}{UpstreamPathTemplate: /goods/delete Priority: 1
}比如你有同样两个路由当请求/goods/delete的时候则下面那个会生效。也就是说Prority是大的会被优先选择。路由负载均衡当下游服务有多个结点的时候我们可以在DownstreamHostAndPorts中进行配置。{DownstreamPathTemplate: /api/posts/{postId},DownstreamScheme: https,DownstreamHostAndPorts: [ { Host: 10.0.1.10, Port: 5000, }, { Host: 10.0.1.11, Port: 5000, } ], UpstreamPathTemplate: /posts/{postId}, LoadBalancer: LeastConnection, UpstreamHttpMethod: [ Put, Delete ] }LoadBalancer将决定负载均衡的算法LeastConnection – 将请求发往最空闲的那个服务器RoundRobin – 轮流发送NoLoadBalance – 总是发往第一个请求或者是服务发现在负载均衡这里我们还可以和Consul结合来使用服务发现我们将在后面的小节中进行详述。请求聚合即将多个API请求结果合并为一个返回。要实现请求聚合我们需要给其它参与的路由起一个Key。{ReRoutes: [{DownstreamPathTemplate: /,UpstreamPathTemplate: /laura, UpstreamHttpMethod: [ Get ], DownstreamScheme: http, DownstreamHostAndPorts: [ { Host: localhost, Port: 51881 } ], Key: Laura }, { DownstreamPathTemplate: /, UpstreamPathTemplate: /tom, UpstreamHttpMethod: [ Get ], DownstreamScheme: http, DownstreamHostAndPorts: [ { Host: localhost, Port: 51882 } ], Key: Tom } ], Aggregates: [ { ReRouteKeys: [ Tom, Laura ], UpstreamPathTemplate: / } ] }当我们请求/的时候会将/tom和/laura两个结果合并到一个response返回{Tom:{Age: 19},Laura:{Age: 25}}需要注意的是聚合服务目前只支持返回json目前只支持Get方式请求下游服务任何下游的response header并会被丢弃如果下游服务返回404聚合服务只是这个key的value为空它不会返回404有一些其它的功能会在将来实现下游服务很慢的处理做一些像 GraphQL的处理对下游服务返回结果进行处理404的处理限流对请求进行限流可以防止下游服务器因为访问过载而崩溃这个功能就是我们的张善友张队进添加进去的。非常优雅的实现我们只需要在路由下加一些简单的配置即可以完成。RateLimitOptions: { ClientWhitelist: [], EnableRateLimiting: true, Period: 1s, PeriodTimespan: 1, Limit: 1 }ClientWihteList 白名单EnableRateLimiting 是否启用限流Period 统计时间段1s, 5m, 1h, 1dPeroidTimeSpan 多少秒之后客户端可以重试Limit 在统计时间段内允许的最大请求数量在 GlobalConfiguration下我们还可以进行以下配置RateLimitOptions: { DisableRateLimitHeaders: false, QuotaExceededMessage: Customize Tips!, HttpStatusCode: 999, ClientIdHeader : Test }Http头 X-Rate-Limit 和 Retry-After 是否禁用QuotaExceedMessage 当请求过载被截断时返回的消息HttpStatusCode 当请求过载被截断时返回的http statusClientIdHeader 用来识别客户端的请求头默认是 ClientId服务质量与熔断熔断的意思是停止将请求转发到下游服务。当下游服务已经出现故障的时候再请求也是功而返并且增加下游服务器和API网关的负担。这个功能是用的Pollly来实现的我们只需要为路由做一些简单配置即可QoSOptions: { ExceptionsAllowedBeforeBreaking:3, DurationOfBreak:5, TimeoutValue:5000 }ExceptionsAllowedBeforeBreaking 允许多少个异常请求DurationOfBreak 熔断的时间单位为秒TimeoutValue 如果下游请求的处理时间超过多少则自如将请求设置为超时缓存Ocelot可以对下游请求结果进行缓存 目前缓存的功能还不是很强大。它主要是依赖于CacheManager 来实现的我们只需要在路由下添加以下配置即可FileCacheOptions: { TtlSeconds: 15, Region: somename }Region是对缓存进行的一个分区我们可以调用Ocelot的 administration API来移除某个区下面的缓存 。认证如果我们需要对下游API进行认证以及鉴权服务的则首先Ocelot 网关这里需要添加认证服务。这和我们给一个单独的API或者ASP.NET Core Mvc添加认证服务没有什么区别。public void ConfigureServices(IServiceCollection services) { var authenticationProviderKey TestKey; services.AddAuthentication() .AddJwtBearer(authenticationProviderKey, x { }); }然后在ReRoutes的路由模板中的AuthenticationOptions进行配置只需要我们的AuthenticationProviderKey一致即可。ReRoutes: [{ DownstreamHostAndPorts: [{ Host: localhost, Port: 51876, } ], DownstreamPathTemplate: /, UpstreamPathTemplate: /, UpstreamHttpMethod: [Post], ReRouteIsCaseSensitive: false, DownstreamScheme: http, AuthenticationOptions: { AuthenticationProviderKey: TestKey, AllowedScopes: [] } }]JWT Tokens要让网关支持JWT 的认证其实和让API支持JWT Token的认证是一样的public void ConfigureServices(IServiceCollection services) { var authenticationProviderKey TestKey; services.AddAuthentication() .AddJwtBearer(authenticationProviderKey, x { x.Authority test; x.Audience test; }); services.AddOcelot(); }Identity Server Bearer Tokens添加Identity Server的认证也是一样public void ConfigureServices(IServiceCollection services) { var authenticationProviderKey TestKey; var options o { o.Authority https://whereyouridentityserverlives.com; o.ApiName api; o.SupportedTokens SupportedTokens.Both; o.ApiSecret secret; }; services.AddAuthentication() .AddIdentityServerAuthentication(authenticationProviderKey, options); services.AddOcelot(); }Allowed Scopes这里的Scopes将从当前 token 中的 claims中来获取我们的鉴权服务将依靠于它来实现 。当前路由的下游API需要某个权限时我们需要在这里声明 。和oAuth2中的 scope意义一致。鉴权我们通过认证中的AllowedScopes 拿到claims之后如果要进行权限的鉴别需要添加以下配置RouteClaimsRequirement: { UserType: registered
}当前请求上下文的token中所带的claims如果没有 name”UserType” 并且 value”registered” 的话将无法访问下游服务。请求头转化请求头转发分两种转化之后传给下游和从下游接收转化之后传给客户端。在Ocelot的配置里面叫做Pre Downstream Request和Post Downstream Request。目前的转化只支持查找和替换。我们用到的配置主要是 UpstreamHeaderTransform 和 DownstreamHeaderTransformPre Downstream RequestTest: http://www.bbc.co.uk/, http://ocelot.com/比如我们将客户端传过来的Header中的 Test 值改为 http://ocelot.com/之后再传给下游 UpstreamHeaderTransform: { Test: http://www.bbc.co.uk/, http://ocelot.com/
},Post Downstream Request而我们同样可以将下游Header中的Test再转为 http://www.bbc.co.uk/之后再转给客户端。DownstreamHeaderTransform: { Test: http://www.bbc.co.uk/, http://ocelot.com/
},变量在请求头转化这里Ocelot为我们提供了两个变量BaseUrl和DownstreamBaseUrl。BaseUrl就是我们在GlobalConfiguration里面配置的BaseUrl后者是下游服务的Url。这里用301跳转做一个示例如何使用这两个变量。默认的301跳转我们会返回一个Location的头于是我们希望将http://www.bbc.co.uk 替换为 http://ocelot.com后者者网关对外的域名。DownstreamHeaderTransform: { Location: http://www.bbc.co.uk/, http://ocelot.com/
}, HttpHandlerOptions: { AllowAutoRedirect: false, },我们通过DownstreamHeaderTranfrom将下游返回的请求头中的Location替换为了网关的域名而不是下游服务的域名。所以在这里我们也可以使用BaseUrl来做为变量替换。DownstreamHeaderTransform: { Location: http://localhost:6773, {BaseUrl}
}, HttpHandlerOptions: { AllowAutoRedirect: false, },当我们的下游服务有多个的时候我们就没有办法找到前面的那个http://localhost:6773因为它可能是多个值。所以这里我们可以使用DownstreamBaseUrl。DownstreamHeaderTransform: { Location: {DownstreamBaseUrl}, {BaseUrl}
}, HttpHandlerOptions: { AllowAutoRedirect: false, },Claims转化Claims转化功能可以将Claims中的值转化到请求头、Query String、或者下游的Claims中对于Claims的转化比较特殊的一点是它提供了一种对字符串进行解析的方法。举个例子比如我们有一个sub的claim。这个claims的 name”sub” value”usertypevalue|useridvalue”实际上我们不会弄这么复杂的value它是拼接来的但是我们为了演示这个字符串解析的功能所以使用了这么一个复杂的value。Ocelot为我们提供的功能分为三段第一段是Claims[sub]很好理解[] 里面是我们的claim的名称。第二段是 表示对字符串进行拆分, 后面跟着拆分完之后我们要取的那个数组里面的某一个元素用 value[index]来表示取第0位元素也可以直接用value。第三段也是以 开头后面跟着我们的分隔符在我们上面的例子分隔符是 |所以在这里如果我们要取 usertype这个claim就会这样写 Claims[sub] value[0] |Claim取到之后我们如果要放到请求头、QueryString、以及Claim当中对应有以下三个配置。Claims to Claims AddClaimsToRequest: { UserType: Claims[sub] value[0] |, UserId: Claims[sub] value[1] | }Claims to Headers AddHeadersToRequest: { CustomerId: Claims[sub] value[1] |
}这里我们还是用的上面那个 sub usertypevalue|useridvalue 的claim来进行处理和转化。Claims to Query StringAddQueriesToRequest: { LocationId: Claims[LocationId] value,
}这里没有进行分隔所以直接取了value。Consul服务发现由于Consul服务发现更多的是Consul的安装、配置、以及使用所以本小节内容将由另一篇文章来进行详细介绍欢迎关注。相关文章Ocelot——初识基于.Net Core的API网关Ocelot API网关的实现剖析微服务网关OcelotAPI网关Ocelot 使用Polly 处理部分失败问题谈谈微服务中的 API 网关API GatewayOcelot网关Ocelot统一权限验证应用监控怎么做ASP.NET Core之跨平台的实时性能监控.Net Core 2.0 InfluxDBGrafanaApp Metrics 实现跨平台的实时性能监控应用程序的8个关键性能指标以及测量方法使用Metrics监控应用程序的性能下一个计划 : .NET/.NET Core应用性能管理Ocelot监控Ocelot 集成Butterfly 实现分布式跟踪Ocelot中使用Butterfly实践Ocelot Consul实践原文地址http://www.jessetalk.cn/2018/03/19/net-core-apigateway-ocelot-docs/.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com