WebEnh

.net7 mvc jquery bootstrap json 学习中 第一次学PHP,正在研究中。自学进行时... ... 我的博客 https://enhweb.github.io/ 不错的皮肤:darkgreentrip,iMetro_HD
  首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

.NET常用库-Ocelot

Posted on 2023-08-19 00:25  WebEnh  阅读(42)  评论(0编辑  收藏  举报

一 介绍

1.简介

  • Ocelot是一个.NET API网关。
  • Ocelot仅适用于.NET Core,目前是为netstandard2.0构建的。
  • Ocelot是一组按特定顺序排列的中间件。
  • Ocelot将HttpRequest对象操作到其配置指定的状态,直到它到达请求构建器中间件,在该中间件中,它创建一个HttpRequestMessage对象,该对象用于向下游服务发出请求。发出请求的中间件是Ocelot管道中的最后一件事。它不会调用下一个中间件。当请求返回Ocelot管道时,将检索下游服务的响应。有一个中间件将HttpResponseMessage映射到HttpResponse对象并返回给客户端。

2.基本功能

  • Routing(路由)
  • Request Aggregation(请求聚合)
  • Service Discovery with Consul & Eureka(服务发现 Conusl,Eureka)
  • Service Fabric()
  • Kubernetes(K8s)
  • WebSockets
  • Authentication(认证)
  • Authorisation(授权)
  • Rate Limiting(限流)
  • Caching(缓存)
  • Retry policies/QoS(重试策略/服务质量)
  • Load Balancing(负载均衡)
  • Logging/Tracing/Correlation(日志/跟踪/关联)
  • Headers/Query String/Claims Transformation
  • Custom Middleware/Delegating Handlers
  • Configuration/Administration REST API
  • Platform/Cloud Agnostic

二 Run起来

1.创建项目

  • 创建一个新的 .Net Core Web Api(空的)项目
  • Install-Package Ocelot

创建一个MyOcelot项目,并导入包Ocelot如下图:

如图

2.添加配置文件

  • 在MyOcelot项目中新增一个ocelot.json配置文件
{
    "ReRoutes": [],
    "GlobalConfiguration": {
    }
}

3.编写项目代码

  • Program.cs 代码

 public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .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();
                })
                .UseStartup<Startup>();
    }

  • Startup.cs 代码

 public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            //配置ocelot服务
            services.AddOcelot(Configuration as ConfigurationRoot);
        }
        
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            //
            app.UseOcelot().Wait();
        }
    }

这样就可以Run起来了,但是没有什么效果。

三 配置

1.配置的组成部分

  • 配置有两个部分,一 一组ReRountes 二 一个GlobalConfiguration。
  • GlobalConfiguration 允许覆盖ReRoute的特定配置。
{
    "ReRoutes": [],
    "GlobalConfiguration": {}
}

  • ReRount项的完整设置内容

{
	"ReRoutes" {
		//上游路径模板
		"UpstreamPathTemplate": "/",
		//上游请求方法
		"UpstreamHttpMethod": [
			"Get"
		],
		//上游主机名称
		"UpstreamHost:"",
		//在转发下游请求过程中 添加到Header的内容
		"AddHeadersToRequest": {},
		"AddClaimsToRequest": {},
		"RouteClaimsRequirement": {},
		//在转发下游请求过程中 添加到查询字符串的内容
		"AddQueriesToRequest": {},
		//
		"RequestIdKey": "",
		//可以对下游请求结果进行缓存,主要依赖于CacheManager实现
		"FileCacheOptions": {
			//缓存过期时间
			"TtlSeconds": 0,
			//缓存的名字
			"Region": ""
		},
		//
		//路由是否区分大小写。默认的ReRouting配置不区分大小写
		"ReRouteIsCaseSensitive": false,
		//服务名称
		"ServiceName": "",
		//下游服务模板
		"DownstreamPathTemplate": "/",
		//下游服务schema:http, https
		"DownstreamScheme": "http",
		//下游服务地址+端口号。可以多个地址端口号,然后使用负载均衡来确定转发到下游服务地址。
		"DownstreamHostAndPorts": [{
			//服务器地址
			"Host": "localhost",
			//端口号
			"Port": 51876,
		}],
		//服务质量与熔断,熔断的意思是停止将请求转发到下游服务。当下游服务已经出现故障的时候再请求也是无功而返,
        //并且增加下游服务器和API网关的负担,这个功能是用的Polly来实现的,我们只需要为路由做一些简单配置即可
		"QoSOptions": {
			//最大允许多少个异常请求
			//ExceptionsAllowedBeforeBreaking设置大于0的数字才能实现此规则
			"ExceptionsAllowedBeforeBreaking": 0,
			//熔断持续的时间,单位为毫秒
			"DurationOfBreak": 1000,
			//TimeoutValue表示如果请求超过5秒,它将自动超时
			"TimeoutValue": 5000
		},
		//负载均衡
		//LeastConnection:将请求发往最空闲的那个服务器
		//RoundRobin:轮流发送
		//NoLoadBalancer:总是发往第一个请求或者是服务发现
		//CookieStickySessions:使用cookie将所有请求粘贴到特定服务器
		"LoadBalancer": "",
		//路由限流设置
		"RateLimitOptions": {
			//客户端白名单
			"ClientWhitelist": [],
			//是否启用限流设置
			"EnableRateLimiting": false,
			//此值指定限制适用的时间段,例如1s,5m,1h,1d等。
			//如果您在超过限制允许的期限内发出更多请求,则需要等待PeriodTimespan过去,然后再发出另一个请求。
			"Period": "",
			//此值指定我们可以在一定秒数后重试
			"PeriodTimespan": 0,
			//指定客户端在定义的时间段内可以发出的最大请求数。
			"Limit": 0
		},
		"AuthenticationOptions": {
			"AuthenticationProviderKey": "",
			"AllowedScopes": []
		},
		"HttpHandlerOptions": {
			"AllowAutoRedirect": true,
			"UseCookieContainer": true,
			"UseTracing": true
		},
		"DangerousAcceptAnyServerCertificateValidator": false
    },
    "Aggregates": [ //请求聚合
    {
      "ReRouteKeys": [ //设置需要聚合的路由key
        "booking",
        "passenger"
      ],
      "UpstreamPathTemplate": "/api/getbookingpassengerinfo" //暴露给外部的聚合请求路径
    },
	"GlobalConfiguration": {
		//全局限流设置
		"RateLimitOptions": {
			//是否禁用X-Rate-Limit和Retry-After标头。
			"DisableRateLimitHeaders": false,
			//发生速率限制时返回的消息
			"QuotaExceededMessage": "Customize Tips!",
			//发生速率限制时返回的HTTP状态代码
			"HttpStatusCode": 999,
			//指定应该用于标识客户端的标头。默认情况下它是“ClientId”
			"ClientIdHeader" : "ClientId"
        },
        "BaseUrl": "https://localhost:5000" //网关基地址
	}
}


{
    //下游理由
    "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
    },
    "DangerousAcceptAnyServerCertificateValidator": false
}

2.合并配置文件

  • Ocelot合并文件的方式基本上是加载它们,循环它们,添加任何ReRoutes,添加任何AggregateReRoutes,如果文件名为ocelot.global.json,则添加GlobalConfiguration以及任何ReRoutes或AggregateReRoutes。然后,Ocelot会将合并的配置保存到名为ocelot.json的文件中,这将在ocelot运行时用作事实的来源。

3.多环境中获取配置文件

  • 待更新

4.Consul中存储配置文件

  • 待更新

四 路由

1.路由

  • Ocelot的主要功能是接收传入的http请求,并将请求转发到下游服务;从下游服务获得响应,然后返回。Ocelot目前仅仅是以一个http请求的形式支持。

  • ReRoute描述Ocelot中一个请求路由到弄一个请求。

  • ReRoute 实例说明:


{
    //下游请求的 路由
    "DownstreamPathTemplate": "/api/posts/{postId}",
    //下游请求是 http/https
    "DownstreamScheme": "https",
    //下游请求的 服务器地址(主机端口号)。可以多个服务器地址,然后选择负载均衡器。
    "DownstreamHostAndPorts": [
            //可以添加多个服务器地址,然后选择负载均衡器
            {
                "Host": "localhost",
                "Port": 80,
            }
        ],
    //负载均衡设置(后续详解) 类型有:LeastConnection ,RoundRobin ,NoLoadBalancer,CookieStickySessions 
    "LoadBalancerOptions": {
        "Type": "LeastConnection"
    },
    "UpstreamPathTemplate": "/posts/{postId}",
    //用于不同的HTTP谓词的请求,路由到不同的下游URL。
    //空数组表示允许所有的HTTP谓词请求
    "UpstreamHttpMethod": [ "Put", "Delete" ]
}

  • 您可以以{something}的形式将变量的占位符添加到模板中。占位符变量需要同时存在于DownstreamPathTemplate和UpstreamPathTemplate属性中.
  • {something} 对于GET需要请求参数时候,比较好用。

{
    "DownstreamPathTemplate": "/api/{everything}",
    "DownstreamScheme": "https",
    "DownstreamHostAndPorts": [
            {
                "Host": "localhost",
                "Port": 80,
            }
        ],
    "UpstreamPathTemplate": "/{everything}",
    "UpstreamHttpMethod": [ "Get", "Post" ]
}

  • ReRoute默认是不区分大小写,可以在ReRoute中指定"ReRouteIsCaseSensitive":true配置,这样Ocelot将传入的URL与上游模板匹配时将区分大小写。

2.路由优先级

  • “优先级”定义希望ReRoutes与上游HttpRequest匹配的顺序。
{
    "Priority": 0
}

3.匹配全部HttpRequest的路由(“捕获所有”路由)

  • “捕获所有”的优先级都低于任何其他ReRoute。如果你的配置中还有下面的ReRoute,那么Ocelot会在“捕获所有”之前去尝试匹配其他ReRount。

{
    "DownstreamPathTemplate": "/{url}",
    "DownstreamScheme": "https",
    "DownstreamHostAndPorts": [
            {
                "Host": "localhost",
                "Port": 80,
            }
        ],
    "UpstreamPathTemplate": "/{url}",
    "UpstreamHttpMethod": [ "Get" ]
}



{
    "DownstreamPathTemplate": "/",
    "DownstreamScheme": "https",
    "DownstreamHostAndPorts": [
            {
                "Host": "10.0.10.1",
                "Port": 80,
            }
        ],
    "UpstreamPathTemplate": "/",
    "UpstreamHttpMethod": [ "Get" ]
}

4.指定上游主机

  • 此功能允许您根据上游主机匹配ReRoutes。这通过查看客户端使用的主机头,然后将其用作我们用于匹配ReRoute的信息。
  • 如果您未在ReRoute上设置UpstreamHost,则任何主机标头都将与之匹配。
  • 如果你有两个相同的ReRoutes(除了UpstreamHost),其中一个为null而另一个设置,Ocelot将支持已设置的那个。
//仅当主机标头值为somedomain.com时,才会匹配上面的ReRoute
{
    "DownstreamPathTemplate": "/",
    "DownstreamScheme": "https",
    "DownstreamHostAndPorts": [
            {
                "Host": "10.0.10.1",
                "Port": 80,
            }
        ],
    "UpstreamPathTemplate": "/",
    "UpstreamHttpMethod": [ "Get" ],
    "UpstreamHost": "somedomain.com"
}

5.查询字符串

  • Ocelot允许您将查询字符串指定为DownstreamPathTemplate的一部分

{
    "ReRoutes": [
        {
            "DownstreamPathTemplate": "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}",
            "UpstreamPathTemplate": "/api/units/{subscriptionId}/{unitId}/updates",
            "UpstreamHttpMethod": [
                "Get"
            ],
            "DownstreamScheme": "http",
            "DownstreamHostAndPorts": [
                {
                    "Host": "localhost",
                    "Port": 50110
                }
            ]
        }
    ],
    "GlobalConfiguration": {
    }
}

  • Ocelot还允许您将查询字符串参数放在UpstreamPathTemplate中,以便您可以将某些查询与某些服务匹配。

{
    "ReRoutes": [
        {
            "DownstreamPathTemplate": "/api/units/{subscriptionId}/{unitId}/updates",
            "UpstreamPathTemplate": "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}",
            "UpstreamHttpMethod": [
                "Get"
            ],
            "DownstreamScheme": "http",
            "DownstreamHostAndPorts": [
                {
                    "Host": "localhost",
                    "Port": 50110
                }
            ]
        }
    ],
    "GlobalConfiguration": {
    }
}

五 负载均衡

1.配置

  • Ocelot可以为每个ReRoute在可用的下游服务之间进行负载平衡。

  • 在RrRoute中添加以下配置


"LoadBalancerOptions": {
        "Type": "LeastConnection"
    },

1.负载均衡器类型

  • LeastConnection : 将请求发往最空闲的那个服务器

  • RoundRobin - 轮流发送

  • NoLoadBalancer - 总是发往第一个请求或者是服务发现

六 限流

  • 为了让ReRoute的速率限制工作,你需要添加以下json到对应的ReRount。

"RateLimitOptions": {
    //客户端白名单
    "ClientWhitelist": [],
    //是否启用限流设置
    "EnableRateLimiting": true,
    //每次请求时间间隔
    "Period": "1s",
    //恢复的时间间隔
    "PeriodTimespan": 1,
    //请求数量
    "Limit": 1
}

  • 可以在ocelot.json的GlobalConfiguration部分中设置以下内容

"RateLimitOptions": {
  //此值指定是禁用X-Rate-Limit和Retry-After标头。
  "DisableRateLimitHeaders": false,
  //此值指定超出的消息。
  "QuotaExceededMessage": "Customize Tips!",
  //此值指定发生速率限制时返回的HTTP状态代码。
  "HttpStatusCode": 999,
  //允许您指定应该用于标识客户端的标头。默认情况下它是“ClientId”
  "ClientIdHeader" : "Test"
}

六 请求聚合

1.简介

  • Ocelot可以使用多个(带Key)ReRoute通过Aggreagete ReRoute,使用一个请求来聚合多个ReRoute(路由)的返回值。返回一个json,该json以各个key为键,各个返回值为值。

2.注意

  • 聚合服务目前只支持返回json
  • 目前只支持Get方式请求下游服务
  • 任何下游的response header并会被丢弃
  • 如果下游服务返回404,聚合服务只是这个key的value为空,它不会返回404