Ocelot学习(二)
Ocelot学习(二)
入门
Ocelot 旨在与 ASP.NET 一起使用,目前在 net6.0 上。
.NET 6.0
安装 NuGet 包
使用 nuget 安装 Ocelot 及其依赖项。您将需要创建一个 net6.0 项目并将包放入其中。然后按照下面的启动和配置部分启动并运行。
复制Install-Package Ocelot
所有版本都可以在这里找到。
配置
下面是一个很基础的ocelot.json。它不会做任何事情,但应该让 Ocelot 开始。
{
"Routes": [],
"GlobalConfiguration": {
"BaseUrl": "https://api.mybusiness.com"
}
}
如果您想要一些实际执行某些操作的示例,请使用以下命令:
{
"Routes": [
{
"DownstreamPathTemplate": "/todos/{id}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "jsonplaceholder.typicode.com",
"Port": 443
}
],
"UpstreamPathTemplate": "/todos/{id}",
"UpstreamHttpMethod": [ "Get" ]
}
],
"GlobalConfiguration": {
"BaseUrl": "https://localhost:5000"
}
}
这里最需要注意的是BaseUrl。Ocelot 需要知道它正在运行的 URL 以便执行 Header 查找和替换以及某些管理配置。设置此 URL 时,它应该是客户端将看到 Ocelot 在其上运行的外部 URL,例如,如果您正在运行容器,Ocelot 可能会在 url http://123.12.1.1:6543上运行,但它前面有类似 nginx 的东西在https上响应://api.mybusiness.com。在这种情况下,Ocelot 基本 url 应该是https://api.mybusiness.com。
如果您使用容器并且需要 Ocelot 响应http://123.12.1.1:6543上的客户端,那么您可以这样做,但是如果您要部署多个 Ocelot,您可能希望在命令行上以某种方式传递它脚本。希望您使用的任何调度程序都可以通过 IP。
程序
然后在您的 Program.cs 中,您将需要以下内容。主要需要注意的是 AddOcelot() (添加 ocelot 服务), UseOcelot().Wait() (设置所有的 Ocelot 中间件)。
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
namespace OcelotBasic
{
public class Program
{
public static void Main(string[] args)
{
new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
config
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
.AddJsonFile("appsettings.json", true, true)
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
.AddJsonFile("ocelot.json")
.AddEnvironmentVariables();
})
.ConfigureServices(s => {
s.AddOcelot();
})
.ConfigureLogging((hostingContext, logging) =>
{
//add your logging
})
.UseIISIntegration()
.Configure(app =>
{
app.UseOcelot().Wait();
})
.Build()
.Run();
}
}
}
配置
可以在此处找到示例配置。配置有两个部分。一个路由数组和一个 GlobalConfiguration。Routes 是告诉 Ocelot 如何处理上游请求的对象。全局配置有点 hacky,允许覆盖 Route 特定的设置。如果您不想管理大量 Route 特定设置,它会很有用。
{
"Routes": [],
"GlobalConfiguration": {}
}
这是一个示例路由配置,您不需要设置所有这些东西,但这是目前可用的所有内容:
{
"DownstreamPathTemplate": "/",
"UpstreamPathTemplate": "/",
"UpstreamHttpMethod": [
"Get"
],
"DownstreamHttpMethod": "",
"DownstreamHttpVersion": "",
"AddHeadersToRequest": {},
"AddClaimsToRequest": {},
"RouteClaimsRequirement": {},
"AddQueriesToRequest": {},
"RequestIdKey": "",
"FileCacheOptions": {
"TtlSeconds": 0,
"Region": ""
},
"RouteIsCaseSensitive": 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,
"MaxConnectionsPerServer": 100
},
"DangerousAcceptAnyServerCertificateValidator": false
}
合并配置文件
此功能是在Issue 296中提出的,它允许用户拥有多个配置文件,以便更轻松地管理大型配置。
您可以调用 AddOcelot(),而不是直接添加配置,例如 AddJsonFile(“ocelot.json”),如下所示。
.ConfigureAppConfiguration((hostingContext, config) =>
{
config
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
.AddJsonFile("appsettings.json", true, true)
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
.AddOcelot(hostingContext.HostingEnvironment)
.AddEnvironmentVariables();
})
在这种情况下,Ocelot 将查找与 (?i)ocelot.([a-zA-Z0-9]*).json 模式匹配的任何文件,然后将它们合并在一起。如果要设置 GlobalConfiguration 属性,则必须有一个名为 ocelot.global.json 的文件。
Ocelot 合并文件的方式基本上是加载它们,循环它们,添加任何路由,添加任何 AggregateRoutes,如果文件名为 ocelot.global.json,则添加 GlobalConfiguration 以及任何路由或 AggregateRoutes。然后,Ocelot 会将合并后的配置保存到一个名为 ocelot.json 的文件中,这将在 ocelot 运行时用作事实来源。
目前在此阶段没有验证,它仅在 Ocelot 验证最终合并配置时发生。这是您在调查问题时需要注意的事项。如果您有任何问题,我建议您始终检查 ocelot.json 中的内容。
您还可以为 Ocelot 指定一个特定路径来查找配置文件,如下所示。
.ConfigureAppConfiguration((hostingContext, config) =>
{
config
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
.AddJsonFile("appsettings.json", true, true)
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
.AddOcelot("/foo/bar", hostingContext.HostingEnvironment)
.AddEnvironmentVariables();
})
Ocelot 需要 HostingEnvironment,因此它知道从算法中排除任何特定环境。
在 consul 中存储配置
您需要做的第一件事是在 Ocelot 中安装提供 Consul 支持的 NuGet 包。
Install-Package Ocelot.Provider.Consul
然后在注册服务时添加以下内容,Ocelot 将尝试在 consul KV 存储中存储和检索其配置。
services
.AddOcelot()
.AddConsul()
.AddConfigStoredInConsul();
您还需要将以下内容添加到您的 ocelot.json。这就是 Ocelot 找到您的 Consul 代理并进行交互以从 Consul 加载和存储配置的方式。
"GlobalConfiguration": {
"ServiceDiscoveryProvider": {
"Host": "localhost",
"Port": 9500
}
}
在研究了 Raft 共识算法并发现它的超级难之后,我决定创建这个功能。为什么不利用 Consul 已经给你这个的事实呢!我想这意味着如果你想充分利用 Ocelot,你现在就把 Consul 作为一个依赖项。
在向本地领事代理发出新请求之前,此功能有 3 秒的 ttl 缓存。
更改时重新加载 JSON 配置
Ocelot 支持在更改时重新加载 json 配置文件。例如,以下将在手动更新 ocelot.json 文件时重新创建 Ocelots 内部配置。
config.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);
配置密钥
如果您使用 Consul 进行配置(或将来使用其他提供程序),您可能需要键入您的配置,以便您可以拥有多个配置 😃问题 346中请求了此功能!为了指定密钥,您需要在配置 json 文件的 ServiceDiscoveryProvider 部分中设置 ConfigurationKey 属性,例如
"GlobalConfiguration": {
"ServiceDiscoveryProvider": {
"Host": "localhost",
"Port": 9500,
"ConfigurationKey": "Oceolot_A"
}
}
在这个例子中,Ocelot 将使用 Oceolot_A 作为您在 Consul 中查找配置的键。
如果不设置 ConfigurationKey,Ocelot 将使用字符串 InternalConfiguration 作为键。
对配置更改做出反应
如果您希望通过 Ocelot.Administration API 或从磁盘重新加载的 ocelot.json 对 Ocelot 配置的更改做出反应,请从 DI 容器中解析 IOcelotConfigurationChangeTokenSource。您可以轮询更改令牌的 HasChanged 属性,也可以使用 RegisterChangeCallback 方法注册回调。
服务发现
Ocelot 允许您指定服务发现提供程序,并将使用它来查找 Ocelot 将请求转发到的下游服务的主机和端口。目前这仅在 GlobalConfiguration 部分中受支持,这意味着相同的服务发现提供程序将用于您在路由级别指定 ServiceName 的所有路由。
Consule
需要做的第一件事是在 Ocelot 中安装提供 Consul 支持的 NuGet 包。
Install-Package Ocelot.Provider.Consul
然后将以下内容添加到您的 ConfigureServices 方法中。
s.AddOcelot()
.AddConsul();
GlobalConfiguration 中需要以下内容。Provider 是必需的,如果您不指定主机和端口,则将使用 Consul 默认值。
请注意 Scheme 选项默认为 HTTP。它被添加到这个PR中。它默认为 HTTP 以不引入重大更改。
"ServiceDiscoveryProvider": {
"Scheme": "https",
"Host": "localhost",
"Port": 8500,
"Type": "Consul"
}
将来我们可以添加一个允许特定路由配置的功能。
为了告诉 Ocelot Route 是为其主机和端口使用服务发现提供程序,您必须添加您希望在向下游发出请求时使用的 ServiceName 和负载均衡器。目前,Ocelot 有一个可以使用的 RoundRobin 和 LeastConnection 算法。如果没有指定负载均衡器,Ocelot 将不会对请求进行负载均衡。
{
"DownstreamPathTemplate": "/api/posts/{postId}",
"DownstreamScheme": "https",
"UpstreamPathTemplate": "/posts/{postId}",
"UpstreamHttpMethod": [ "Put" ],
"ServiceName": "product",
"LoadBalancerOptions": {
"Type": "LeastConnection"
},
}
设置完成后,Ocelot 将从服务发现提供者那里查找下游主机和端口,并在任何可用服务之间实现负载平衡请求。
很多人要求我实现一个功能,即 Ocelot 轮询 Consul 以获取最新的服务信息,而不是每个请求。如果您想轮询 Consul 以获取最新服务而不是每个请求(默认行为),那么您需要设置以下配置。
"ServiceDiscoveryProvider": {
"Host": "localhost",
"Port": 8500,
"Type": "PollConsul",
"PollingInterval": 100
}
轮询间隔以毫秒为单位,告诉 Ocelot 多久调用一次 Consul 以更改服务配置。
请注意这里有权衡。如果您轮询 Consul,Ocelot 可能不会根据您的轮询间隔知道服务是否已关闭,并且您可能会遇到比您获得每个请求的最新服务更多的错误。这实际上取决于您的服务有多不稳定。我怀疑这对大多数人来说很重要,轮询可能会比每个请求调用 Consul(作为 Sidecar 代理)带来微小的性能改进。如果您正在调用远程 Consul 代理,那么轮询将是一个很好的性能改进。
您的服务需要添加到 Consul 中,如下所示(C# 风格,但希望这是有意义的)……唯一需要注意的是不要在地址字段中添加 http 或 https。之前有人联系过我关于不接受地址中的方案和接受地址中的方案。读完这篇文章后,我认为该计划不应该在那里。
要么
"Service": {
"ID": "some-id",
"Service": "some-service-name",
"Address": "localhost",
"Port": 8080
}
授权
Ocelot 支持在身份验证后运行的基于声明的授权。这意味着如果您有要授权的路线,您可以将以下内容添加到您的路线配置中。
"RouteClaimsRequirement": {
"UserType": "registered"
}
实战配置文件
配置文件
{
"Routes": [
{
"DownstreamPathTemplate": "/api/{url}", //服务地址--url变量
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "192.168.3.230",
"Port": 5030 //服务端口
}
],
"UpstreamPathTemplate": "/T5030/{url}", //网关地址--url变量
"UpstreamHttpMethod": [ "Get", "Post" ]
},
{
"UpstreamPathTemplate": "/webapi/swagger/v1/swagger.json",
"UpstreamHttpMethod": [ "Get" ],
"DownstreamHostAndPorts": [
{
"Host": "192.168.3.230",
"Port": 5030 //服务端口
}
],
"DownstreamPathTemplate": "/swagger/v1/swagger.json",
"DownstreamScheme": "http"
},
{
"UpstreamPathTemplate": "/webapiV2/swagger/v2/swagger.json",
"UpstreamHttpMethod": [ "Get" ],
"DownstreamHostAndPorts": [
{
"Host": "192.168.3.230",
"Port": 5030 //服务端口
}
],
"DownstreamPathTemplate": "/swagger/v1/swagger.json",
"DownstreamScheme": "http"
}
]
}
{
"GlobalConfiguration": {
"ServiceDiscoveryProvider": {
"Host": "192.168.3.230",
"Port": 15500,
"ConfigurationKey": "Ocelot_Consul"
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!