.NET Core API网关Ocelot(七)【服务发现,Service Fabric】

Ocelot允许您指定服务发现提供程序,并使用它来查找Ocelot正在将请求转发给下游服务的主机和端口。目前,这仅在GlobalConfiguration部分中受支持,这意味着所有Route将使用相同的服务发现提供程序,以便在Route级别指定ServiceName

Consul

您需要做的第一件事是安装在Ocelot中提供Consul支持的NuGet软件包。

Install-Package Ocelot.Provider.Consul

然后将以下内容添加到您的ConfigureServices方法中。

s.AddOcelot()
    .AddConsul();

GlobalConfiguration中需要以下内容。 提供者是必需的,如果你没有指定主机和端口,默认使用Consul。

"ServiceDiscoveryProvider": {
    "Host": "localhost",
    "Port": 8500,
    "Type": "Consul"
}

将来我们可以添加一个功能,允许Route配置服务发现提供程序。

为了告诉Ocelot一个Route需要使用服务发现提供程序来发现下游主机和端口,您必须在下游请求配置中添加ServiceNameLoadBalancer。 目前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的性能有所改善。 如果您呼叫远程Consul代理,则轮询将改善性能。

需要将您的服务添加到Consul中,如下所示(C#样式,但希望这是有道理的)…要注意的唯一重要的事情是不要在Address字段中添加httphttps。 之前已经联系过我关于不接受地址中的方案和地址中的方案的联系。 看完这篇文章后,我认为该方案不应该存在。

还可以

"Service": {
       "ID": "some-id",
       "Service": "some-service-name",
       "Address": "localhost",
       "Port": 8080
   }

ACL Token

如果您使用Consul的ACL,Ocelot也支持添加X-Consul-Token头。 为了实现ACL访问,您必须添加下面的附加属性Token

"ServiceDiscoveryProvider": {
    "Host": "localhost",
    "Port": 8500,
    "Token": "footoken",
    "Type": "Consul"
}

Ocelot会将这个令牌添加到用来发出请求的Consul客户端,然后用于后续的每个请求。

Eureka

这个功能是作为问题 262的一部分被提出。为Netflix的Eureka服务发现提供程序添加支持。 主要原因是它是Steeltoe的一个关键部分,Steeltoe又与Pivotal有关! 反正背景很牛逼。

您需要做的第一件事是在Ocelot中安装提供Eureka支持的NuGet软件包。

Install-Package Ocelot.Provider.Eureka

然后将以下内容添加到您的ConfigureServices方法中。

s.AddOcelot()
    .AddEureka();

为了使Eureka工作,需要在 ocelot.json中添加如下配置.

"ServiceDiscoveryProvider": {
    "Type": "Eureka"
}

遵循这里的指导,您可能还需要添加一些内容到appsettings.json。 例如,下面的json告诉steeltoe/pivotal服务在哪里寻找服务发现服务器,以及服务是否应该向其注册。

"eureka": {
    "client": {
    "serviceUrl": "http://localhost:8761/eureka/",
    "shouldRegisterWithEureka": false,
    "shouldFetchRegistry": true
    }
}

我被告知,如果shouldRegisterWithEurekafalse,那么shouldFetchRegistry将会默认为true,所以你不需要显式地将它留在这里。

现在Ocelot将在启动时注册所有必要的服务,并且如果配置有上述json,则会将其注册到Eureka。其中一项服务每30秒(默认)轮询一次Eureka获取最新的服务状态并将其保留在内存中。当Ocelot要求提供给定的服务时,它会从内存中检索出来,因此性能不是一个大问题。注意,此代码由Pivotal.Discovery.ClientNuGet包提供,所以非常感谢他们的辛勤工作。

Dynamic Routing

在发行版340中请求了此功能。其思想是在使用服务发现提供程序时启用动态路由(有关更多信息,请参阅文档的该部分)。在这种模式下,Ocelot将使用上游路径的第一段通过服务发现提供程序查找下游服务。

这样的一个例子是使用诸如https://api.mywebsite.com/product/products之类的URL调用Ocelot。 Ocelot将采用路径的第一部分即产品,并将其用作在Consul中查找服务的键。如果Consul返回服务,则Ocelot将在Consul返回的任何主机和端口以及本例中产品的其余路径段上请求该服务,从而进行下游调用http://hostfromconsul:portfromconsul/products。 Ocelot将像往常一样将任何查询字符串添加到下游URL。

为了启用动态路由,您的配置中需要有0条路由。目前,您无法混合使用动态路由和配置路由。除此之外,您还需要指定上述服务发现提供者详细信息,并将下游http / https方案指定为DownstreamScheme

除此之外,您还可以设置RateLimitOptions,QoSOptions,LoadBalancerOptionsHttpHandlerOptions,DownstreamScheme(您可能希望在https上调用Ocelot,但通过http与私有服务对话)将应用于所有动态路由。

配置可能看起来像

{
    "ReRoutes": [],
    "Aggregates": [],
    "GlobalConfiguration": {
        "RequestIdKey": null,
        "ServiceDiscoveryProvider": {
            "Host": "localhost",
            "Port": 8500,
            "Type": "Consul",
            "Token": null,
            "ConfigurationKey": null
        },
        "RateLimitOptions": {
            "ClientIdHeader": "ClientId",
            "QuotaExceededMessage": null,
            "RateLimitCounterPrefix": "ocelot",
            "DisableRateLimitHeaders": false,
            "HttpStatusCode": 429
        },
        "QoSOptions": {
            "ExceptionsAllowedBeforeBreaking": 0,
            "DurationOfBreak": 0,
            "TimeoutValue": 0
        },
        "BaseUrl": null,
            "LoadBalancerOptions": {
            "Type": "LeastConnection",
            "Key": null,
            "Expiry": 0
        },
        "DownstreamScheme": "http",
        "HttpHandlerOptions": {
            "AllowAutoRedirect": false,
            "UseCookieContainer": false,
            "UseTracing": false
        }
    }
}

Ocelot还允许您设置DynamicRoutes,从而可以为每个下游服务设置速率限制规则。 例如,如果您有产品和搜索服务,并且想要对两者进行最高限价,这将非常有用。 一个例子如下。

{
    "DynamicReRoutes": [
        {
        "ServiceName": "product",
        "RateLimitRule": {
                "ClientWhitelist": [],
                "EnableRateLimiting": true,
                "Period": "1s",
                "PeriodTimespan": 1000.0,
                "Limit": 3
            }
        }
    ],
    "GlobalConfiguration": {
        "RequestIdKey": null,
        "ServiceDiscoveryProvider": {
            "Host": "localhost",
            "Port": 8523,
            "Type": "Consul"
        },
        "RateLimitOptions": {
            "ClientIdHeader": "ClientId",
            "QuotaExceededMessage": "",
            "RateLimitCounterPrefix": "",
            "DisableRateLimitHeaders": false,
            "HttpStatusCode": 428
        }
        "DownstreamScheme": "http",
    }
}

此配置意味着,如果您有一个请求进入/product/*上的Ocelot,则动态路由将启动,并且ocelot将使用DynamicRoutes部分中针对产品服务设置的速率限制。

请浏览所有文档以了解这些选项。


Service Fabric

如果您在Service Fabric中部署了服务,则通常将使用命名服务来访问它们。

以下示例显示了如何设置将在Service Fabric中工作的路由。 最重要的是ServiceName,它由Service Fabric应用程序名称和特定的服务名称组成。 我们还需要在GlobalConfiguration中设置ServiceDiscoveryProvider。 此处的示例显示了典型配置。 假定服务结构在本地主机上运行,并且命名服务在端口19081上。

下面的示例取自samples文件夹,因此,如果这没有意义,请进行检查!

{
    "ReRoutes": [
        {
        "DownstreamPathTemplate": "/api/values",
        "UpstreamPathTemplate": "/EquipmentInterfaces",
        "UpstreamHttpMethod": [
            "Get"
        ],
        "DownstreamScheme": "http",
        "ServiceName": "OcelotServiceApplication/OcelotApplicationService",
        }
    ],
    "GlobalConfiguration": {
        "RequestIdKey": "OcRequestId",
        "ServiceDiscoveryProvider": {
            "Host": "localhost",
            "Port": 19081,
            "Type": "ServiceFabric"
        }
    }
}

如果您使用无状态/guest服务,则ocelot将能够通过命名服务进行代理,而无需其他任何操作。 但是,如果您使用statefull /actor服务,则必须随客户端请求一起发送PartitionKindPartitionKey查询字符串值,例如

GET http://ocelot.com/EquipmentInterfaces?PartitionKind=xxx&PartitionKey=xxx

Ocelot无法为您解决这些问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值