Ocelot之路由

前言

这节介绍Ocelot之路由。说道路由,大家都不会陌生。通俗的说就是转发请求到下游服务。

 

环境:VS2019 +.NET5.0 + Ocelot17.0.0

 

源码:https://github.com/ThreeMammals/Ocelot/tree/17.0.0

路由(Routing

 

Ocelot 的主要功能是接收传入的 http 请求并将它们转发到下游服务。Ocelot 目前只支持另一个 http 请求的形式(将来可能是任何传输机制)。

Ocelot 将一个请求到另一个请求的路由描述为 Route。为了让任何东西在 Ocelot 中运行,您需要在配置中设置一个 Route

 

{

    "Routes": [

]

}

 

要配置 Route,您需要在 Routes json 数组中添加一个

 

{

    "DownstreamPathTemplate": "/api/posts/{postId}",

    "DownstreamScheme": "https",

    "DownstreamHostAndPorts": [

            {

                "Host": "localhost",

                "Port": 80,

            }

        ],

    "UpstreamPathTemplate": "/posts/{postId}",

    "UpstreamHttpMethod": [ "Put", "Delete" ]}

 

 

DownstreamPathTemplateDownstreamScheme DownstreamHostAndPorts 定义了请求将被转发到的 URL

DownstreamHostAndPorts 是一个集合,它定义了您希望将请求转发到的任何下游服务的主机和端口。通常这将只包含一个条目,但有时您可能希望对下游服务的请求进行负载均衡,而 Ocelot 允许您添加多个条目,然后选择一个负载均衡器。

UpstreamPathTemplate Ocelot 将用于标识哪个 DownstreamPathTemplate 用于给定请求的 URL。使用 UpstreamHttpMethod 以便 Ocelot 可以区分对同一 URL 具有不同 HTTP 动词的请求。您可以设置特定的 HTTP 方法列表或设置一个空列表以允许其中任何一个。

Ocelot 中,您可以以 {something} 的形式将变量占位符添加到模板中。占位符变量需要同时出现在 DownstreamPathTemplate UpstreamPathTemplate 属性中。当 Ocelot 处理每个请求时,Ocelot 将尝试将 UpstreamPathTemplate 占位符中的值替换为 DownstreamPathTemplate

您还可以捕获所有类型的路线,例如

 

    "DownstreamPathTemplate": "/api/{everything}",

    "DownstreamScheme": "https",

    "DownstreamHostAndPorts": [

            {

                "Host": "localhost",

                "Port": 80,

            }

        ],

    "UpstreamPathTemplate": "/{everything}",

    "UpstreamHttpMethod": [ "Get", "Post" ]}

 

 

这会将任何路径 + 查询字符串组合转发到路径 /api 之后的下游服务。

默认的 ReRouting 配置不区分大小写!

为了更改此设置,您可以在每个路由的基础上指定以下设置。

 

"RouteIsCaseSensitive": true

 

这意味着当 Ocelot 尝试将传入的上游 url 与上游模板匹配时,评估将区分大小写。

 

快速实践

2.1 变量占位符添加到模板

修改默认的天气预报接口,添加获取未来几天参数。

 

1步:修改WeatherForecastController中Get接口。

 

[HttpGet("{days}")]

        public IEnumerable<WeatherForecast> Get(int days)

        {

            var rng = new Random();

            return Enumerable.Range(1, days).Select(index => new WeatherForecast

            {

                Date = DateTime.Now.AddDays(index),

                TemperatureC = rng.Next(-20, 55),

                Summary = Summaries[rng.Next(Summaries.Length)]

            })

            .ToArray();

        

 

 

2步:修改ocelot配置文件,路由中添加{everything}变量占位符。

 

{

  "Routes": [

    {

      "DownstreamPathTemplate": "/WeatherForecast/{everything}",

      "DownstreamScheme": "http",

      "DownstreamHostAndPorts": [

        {

          "Host": "localhost",

          "Port": 6000

        }

      ],

      "UpstreamPathTemplate": "/Weather/{everything}",

      "UpstreamHttpMethod": [ "Get" ]

    }

  ],

  "GlobalConfiguration": {

    "BaseUrl": "https://localhost:5000"

  }

}        

 

 

3步:运行网关服务和接口服务。

4步:使用接口工具Postman测试接口,这里参数为3,去未来3天天气。

 

 

 

万能模版转发Catch All

3.1 概念

 

Ocelot 的路由还支持捕获所有样式的路由,用户可以指定他们想要匹配所有流量。

如果你像下面这样设置你的配置,所有的请求都会被直接代理。占位符 {url} 名称不重要,任何名称都可以使用。

 

{

    "DownstreamPathTemplate": "/{url}",

    "DownstreamScheme": "https",

    "DownstreamHostAndPorts": [

            {

                "Host": "localhost",

                "Port": 80,

            }

        ],

    "UpstreamPathTemplate": "/{url}",

    "UpstreamHttpMethod": [ "Get" ]}

  

 

万能模板转发的优先级低于任何其他 Route

如果您的配置中还有下面的 Route,那么 Ocelot 会在全部捕获之前匹配它。

 

{

    "DownstreamPathTemplate": "/",

    "DownstreamScheme": "https",

    "DownstreamHostAndPorts": [

            {

                "Host": "10.0.10.1",

                "Port": 80,

            }

        ],

    "UpstreamPathTemplate": "/",

    "UpstreamHttpMethod": [ "Get" ]}

 

 

 

 

 

 

3.2 实践

还是使用上面例子获取指定未来几天天气预报接口。

 

1步:修改ocelot配置文件,路由使用万能模板。

 

{

  "Routes": [

    {

      "DownstreamPathTemplate": "/{url}",

      "DownstreamScheme": "http",

      "DownstreamHostAndPorts": [

        {

          "Host": "localhost",

          "Port": 6000

        }

      ],

      "UpstreamPathTemplate": "/{url}",

      "UpstreamHttpMethod": [ "Get" ]

    }

  ],

  "GlobalConfiguration": {

    "BaseUrl": "http://localhost:5000"

  }

}

 

 

3步:运行网关服务和接口服务。

4步:使用接口工具Postman测试接口,通过端口5000网关访问,这里参数为4,取未来4天天气。

WeatherForecast/4匹配了模板中{url}

 

注意:若模板只有"/",测路由不带参数。

 

 

上游主机(Upstream Host

4.1 概念

此功能允许您拥有基于上游主机的路由。这是通过查看客户端使用的主机头,然后将其用作我们用来识别路由的信息的一部分来实现的。

配置:

{

    "DownstreamPathTemplate": "/",

    "DownstreamScheme": "https",

    "DownstreamHostAndPorts": [

            {

                "Host": "10.0.10.1",

                "Port": 80,

            }

        ],

    "UpstreamPathTemplate": "/",

    "UpstreamHttpMethod": [ "Get" ],

"UpstreamHost": "somedomain.com"

}

 

 

只有当主机头值为 somedomain.com 时,才会匹配上面的路由。

如果您未在 路由上设置 UpstreamHost,则任何主机标头都将匹配它。这意味着,如果您有两个相同的路由,除了 UpstreamHost 之外,其中一个为空,另一个设置 Ocelot 将支持已设置的一个。

4.2 实践

还是使用上面例子获取指定未来几天天气预报接口,使用本机

 

1步:修改ocelot配置文件,路由使用万能模板。

 

{

  "Routes": [

    {

      "DownstreamPathTemplate": "/{url}",

      "DownstreamScheme": "http",

      "DownstreamHostAndPorts": [

        {

          "Host": "localhost",

          "Port": 6000

        }

      ],

      "UpstreamPathTemplate": "/{url}",

      "UpstreamHttpMethod": [ "Get" ],

      "UpstreamHost": "localhost:5000"

    }

  ],

  "GlobalConfiguration": {

    "BaseUrl": "http://localhost:5000"

  }

}

 

 

3步:运行网关服务和接口服务。

4步:使用接口工具Postman测试接口,通过端口5000网关访问,这里参数为4,取未来4天天气。

WeatherForecast/4匹配了模板中{url}

 

 

 

 

 

优先级(Priority

 

可以通过在 ocelot.json 中包含“优先级”属性来定义希望路由匹配上游 HttpRequest 的顺序。

 

 

{

"Priority": 0

}

 

 

0 是最低优先级,Ocelot 将始终为 /{catchAll} 路由使用 0,这仍然是硬编码的。

可以自由设置任何您希望的优先级。

例如

 

{

    "UpstreamPathTemplate": "/goods/{catchAll}"

"Priority": 0

}

 

 

 

 

{

    "UpstreamPathTemplate": "/goods/delete"

"Priority": 1

}

 

 

在上面的示例中,如果您在 /goods/delete 上向 Ocelot 发出请求,Ocelot 将匹配 /goods/delete 路由。

 

 

 

 

查询字符串(Query Strings

Ocelot 允许您将查询字符串指定为 DownstreamPathTemplate 的一部分,如下例所示。

 

{

    "Routes": [

        {

            "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 中,以便您可以将某些查询与某些服务相匹配。

 

{

    "Routes": [

        {

            "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} 参数,并在下游请求路径中使用它。

 

总结

这里只是介绍了静态路由,后期介绍动态路由。

 

 

鸣谢

https://ocelot.readthedocs.io/en/latest/features/routing.html

 

 

posted @ 2022-04-03 18:38  春光牛牛  阅读(385)  评论(0编辑  收藏  举报