Ocelot
的主要功能是接管进入的http
请求并把它们转发给下游服务。目前是以另一个http
请求的形式(将来可能是任何传输机制)。
Ocelot
将路由一个请求到另一个请求描述为ReRoute
。为了在Ocelot
做任何工作,都需要在配置中设置一个ReRoute
。
{
"ReRoutes": [
]
}
为了设置ReRoute
,你需要如下所示添加一个ReRoute
到ReRoutes
的json
数组。
{
"DownstreamPathTemplate": "/api/posts/{postId}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 80,
}
],
"UpstreamPathTemplate": "/posts/{postId}",
"UpstreamHttpMethod": [ "Put", "Delete" ]
}
DownstreamPathTemplate、DownstreamScheme
和DownstreamHostAndPorts
确定请求的转发。
DownstreamHostAndPorts
是一个数组,包含请求要转发的主机和端口。通常这只包含一个条目,但有时您可能需要将请求负载平衡到您的下游服务,这是Ocelot
允许我们添加多个条目,然后选择一个负载均衡器。
UpstreamPathTemplate
是Ocelot
用来标识哪个DownstreamPathTemplate
用于给定的请求URL。 最后,UpstreamHttpMethod
的使用,可以让Ocelot
区分对同一个URL
的请求,并且显然这是需要的工作。
你可以指定一个Http
请求方法列表,或者一个空的列表以允许任务Http
请求方法。在Ocelot
中,你可以使用{something}
的方式在模板中添加变量占位符。占位符需要在DownstreamPathTemplate
和UpstreamPathTemplate
中都添加。如果是这样,当请求到达时Ocelot
将试图使用上游url
中的正确的变量值来替换占位符。
你也可以想这样使用一个ReRoute
处理所有请求:
{
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 80,
}
],
"UpstreamPathTemplate": "/{everything}",
"UpstreamHttpMethod": [ "Get", "Post" ]
}
这将转发所有请求到下游服务路径/api
。
目前在没有任何配置的请求下,Ocelot
将默认所有ReRoutes
不区分大小写。 为了改变这种情况,您可以在每个ReRoute
中指定以下设置:
"ReRouteIsCaseSensitive": true
这意味着,当Ocelot
尝试将上行url与上游模板匹配时将区分大小写。 此设置默认为false
,这也是我的建议。因此只有在您希望ReRoute
区分大小写时才用设置它。
捕获所有
Ocelot
的路由还支持捕获所有样式的路由,用户可以指定他们想要匹配所有流量。
如果你像下面那样设置你的配置,请求将被直接代理(它不一定叫url
,任何占位符名称都可以)。
{
"DownstreamPathTemplate": "/{url}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 80,
}
],
"UpstreamPathTemplate": "/{url}",
"UpstreamHttpMethod": [ "Get" ]
}
该捕获所有的优先级低于其他任何ReRoute
。 如果你的配置中还有下面的ReRoute
,那么Ocelot
会在捕获所有配置之前先匹配它。
{
"DownstreamPathTemplate": "/",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "10.0.10.1",
"Port": 80,
}
],
"UpstreamPathTemplate": "/",
"UpstreamHttpMethod": [ "Get" ]
}
上游主机
此功能允许您基于上游主机进行ReRoutes
。 这是通过查看客户端使用的主机头来工作,然后将其用作识别ReRoute
的信息的一部分。
为了使用这个功能,在你的配置中加上如下配置。
{
"DownstreamPathTemplate": "/",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "10.0.10.1",
"Port": 80,
}
],
"UpstreamPathTemplate": "/",
"UpstreamHttpMethod": [ "Get" ],
"UpstreamHost": "somedomain.com"
}
上面的ReRoute
只会匹配主机头是somedomain.com
的请求。
如果您没有在ReRoue
上设置UpstreamHost
,则任何主机头都可以匹配它。 这基本上是一个捕获所有功能并保留构建功能时的现有功能。这意味着如果您有两个相同的ReRoute
,其中一个与UpstreamHost
是null
,另一个有值。 Ocelot
会倾向于设定值的那个。
这个功能在问题 216提出要求。
优先级
在问题 270中,我最终决定在ocelot.json
中公开ReRoute
的优先级。这意味着您可以决定上游HttpRequest
与你的ReRoutes
的匹配顺序。
为了是其起作用,将以下内容添加到ocelot.json
的ReRoute
中,0
仅仅是一个示例值,将在下面解释。
{
"Priority": 0
}
0
是最低优先级,Ocelot
将始终使用0
作为/{catchAll}
路由条目,并且可以硬编码。之后,你可以自由设置你想要的任何优先级。
例如你可以这样:
{
"UpstreamPathTemplate": "/goods/{catchAll}"
"Priority": 0
}
还可以:
{
"UpstreamPathTemplate": "/goods/delete"
"Priority": 1
}
在上面的例子中,如果您向Ocelot
请求/goods/delete
,Ocelot
将匹配/goods/delete
这个ReRoute
。不过在不设置优先级以前它会匹配/goods/{catchAll}
(因为这是列表中的第一个ReRoute
!)。
动态路由
在发行340中已请求此功能。
这个想法是在使用服务发现提供程序时启用动态路由,因此您不必提供路由配置。 如果您觉得这很有趣,请参阅docs service-discovery。
Query Strings
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
将使用上游路径模板中{unitId}
中的值,并将其作为名为unitId
的查询字符串参数添加到下游请求中!
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": {
}
}
在此示例中,Ocelot
将仅匹配具有匹配URL
路径的请求,并且查询字符串以unitId = something
开头。此后您可以进行其他查询,但是必须以匹配的参数开头。 Ocelot
还将交换查询字符串中的{unitId}
参数,并在下游请求路径中使用它。