Ocelot简易教程(三)之主要特性及路由详解

 

Ocelot简易教程目录

  1. Ocelot简易教程(一)之Ocelot是什么
  2. Ocelot简易教程(二)之快速开始1
  3. Ocelot简易教程(二)之快速开始2
  4. Ocelot简易教程(三)之主要特性及路由详解
  5. Ocelot简易教程(四)之请求聚合以及服务发现
  6. Ocelot简易教程(五)之集成IdentityServer认证以及授权
  7. Ocelot简易教程(六)之重写配置文件存储方式并优化响应数据
  8. Ocelot简易教程(七)之配置文件数据库存储插件源码解析

 

上篇中也提到了,最简单的Ocelot如下面所示,只有简单的两个节点,一个是ReRoutes,另一个就是GlobalConfiguration关于这两个节点的作用,上篇也已经讲述了,这里再简单的讲下ReRoutes:告诉Ocelot如何处理上游的请求。GlobalConfiguration:顾名思义就是全局配置,此节点的配置允许覆盖ReRoutes里面的配置,你可以在这里进行通用的一些配置信息。

<span style="color:#333333"><code>{
    <span style="color:red">"ReRoutes"</span>: [],
    <span style="color:red">"GlobalConfiguration"</span>: {}
}</code></span>

下面呢给出ReRoute 的所有的配置信息,当然在实际使用的时候你没有必要全部进行配置,只需要根据你项目的实际需要进行相关的配置就可以了。

<span style="color:#333333"><code><span style="color:#a31515">"ReRoutes"</span>: [
    {
      <span style="color:#a31515">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/api/{everything}"</span>,<span style="color:green">//下游路由模板</span>
      <span style="color:#a31515">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/good/{everything}"</span>,<span style="color:green">//上游路由模板</span>
      <span style="color:#a31515">"UpstreamHttpMethod"</span>: [ <span style="color:#a31515">"Get"</span>, <span style="color:#a31515">"Post"</span> ],<span style="color:green">//上游请求方法</span>
      <span style="color:#a31515">"AddHeadersToRequest"</span>: {},
      <span style="color:#a31515">"UpstreamHeaderTransform"</span>: {},
      <span style="color:#a31515">"DownstreamHeaderTransform"</span>: {},
      <span style="color:#a31515">"AddClaimsToRequest"</span>: {},
      <span style="color:#a31515">"RouteClaimsRequirement"</span>: {},
      <span style="color:#a31515">"AddQueriesToRequest"</span>: {},
      <span style="color:#a31515">"RequestIdKey"</span>: <span style="color:#a31515">null</span>,
      <span style="color:#a31515">"FileCacheOptions"</span>: {
        <span style="color:#a31515">"TtlSeconds"</span>: <span style="color:#000000">0</span>,
        <span style="color:#a31515">"Region"</span>: <span style="color:#a31515">null</span>
      },
      <span style="color:#a31515">"ReRouteIsCaseSensitive"</span>: <span style="color:#a31515">false</span>,
      <span style="color:#a31515">"ServiceName"</span>: <span style="color:#a31515">null</span>,
      <span style="color:#a31515">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,
      <span style="color:#a31515">"QoSOptions"</span>: {<span style="color:green">//Qos相关配置</span>
        <span style="color:#a31515">"ExceptionsAllowedBeforeBreaking"</span>: <span style="color:#000000">0</span>,
        <span style="color:#a31515">"DurationOfBreak"</span>: <span style="color:#000000">0</span>,
        <span style="color:#a31515">"TimeoutValue"</span>: <span style="color:#000000">0</span>
      },
      <span style="color:#a31515">"LoadBalancerOptions"</span>: {<span style="color:green">//负载均衡相关选项</span>
        <span style="color:#a31515">"Type"</span>: <span style="color:#a31515">"RoundRobin"</span>,
        <span style="color:#a31515">"Key"</span>: <span style="color:#a31515">null</span>,
        <span style="color:#a31515">"Expiry"</span>: <span style="color:#000000">0</span>
      },
      <span style="color:#a31515">"RateLimitOptions"</span>: {<span style="color:green">//限流相关配置</span>
        <span style="color:#a31515">"ClientWhitelist"</span>: [],
        <span style="color:#a31515">"EnableRateLimiting"</span>: <span style="color:#a31515">false</span>,
        <span style="color:#a31515">"Period"</span>: <span style="color:#a31515">null</span>,
        <span style="color:#a31515">"PeriodTimespan"</span>: <span style="color:#000000">0.0</span>,
        <span style="color:#a31515">"Limit"</span>: <span style="color:#000000">0</span>
      },
      <span style="color:#a31515">"AuthenticationOptions"</span>: {<span style="color:green">//认证相关选项</span>
        <span style="color:#a31515">"AuthenticationProviderKey"</span>: <span style="color:#a31515">null</span>,
        <span style="color:#a31515">"AllowedScopes"</span>: []
      },
      <span style="color:#a31515">"HttpHandlerOptions"</span>: {<span style="color:green">//HttpHandler相关的配置</span>
        <span style="color:#a31515">"AllowAutoRedirect"</span>: <span style="color:#a31515">false</span>,<span style="color:green">//是否对下游重定向进行响应</span>
        <span style="color:#a31515">"UseCookieContainer"</span>: <span style="color:#a31515">false</span>,<span style="color:green">//是否启动CookieContainer储存cookies</span>
        <span style="color:#a31515">"UseTracing"</span>: <span style="color:#a31515">false</span>,
        <span style="color:#a31515">"UseProxy"</span>: <span style="color:#a31515">true</span>
      },
      <span style="color:#a31515">"DownstreamHostAndPorts"</span>: [<span style="color:green">//下游端口及host</span>
        {
          <span style="color:#a31515">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:#a31515">"Port"</span>: <span style="color:#000000">1001</span>
        },
        {
          <span style="color:#a31515">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:#a31515">"Port"</span>: <span style="color:#000000">1002</span>
        }
      ],
      <span style="color:#a31515">"UpstreamHost"</span>: <span style="color:#a31515">null</span>,<span style="color:green">//上游Host</span>
      <span style="color:#a31515">"Key"</span>: <span style="color:#a31515">null</span>,
      <span style="color:#a31515">"DelegatingHandlers"</span>: [],
      <span style="color:#a31515">"Priority"</span>: <span style="color:#000000">1</span>,
      <span style="color:#a31515">"Timeout"</span>: <span style="color:#000000">0</span>,
      <span style="color:#a31515">"DangerousAcceptAnyServerCertificateValidator"</span>: <span style="color:#a31515">false</span>
    }</code></span>

当然上面的配置项我就不一一的进行介绍,因为很多配置相信大家根据意思都能知道个大概了。我只会对比较常用的配置做下介绍。而且在接下来的文章中对对每个节点进行单独的详细的介绍。在介绍之前呢先看Ocelot的几个特性。

Ocelot特性介绍

合并配置文件

这个特性允许用户创建多个配置文件来方便的对大型项目进行配置。试想一下,如果你的项目有几十个路由规则需要配置的话,那么在一个配置文件进行配置应该很痛苦吧,有了这个特性后,你就可以创建多个配置文件。Ocelot会自动合并他们。
在加载配置文件的时候 你可以通过下面的方式来调用AddOcelot()方法来替换直接加载某个配置的写法 如:AddJsonFile(“ocelot.json”)

<span style="color:#333333"><code>.ConfigureAppConfiguration((hostingContext, config) =>
    {
        config
            .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
            .AddJsonFile(<span style="color:#a31515">"appsettings.json"</span>, <span style="color:#a31515">true</span>, <span style="color:#a31515">true</span>)
            .AddJsonFile($<span style="color:#a31515">"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json"</span>, <span style="color:#a31515">true</span>, <span style="color:#a31515">true</span>)
            .AddOcelot()
            .AddEnvironmentVariables();
    })</code></span>

在这种情况下,Ocelot会寻找所有匹配了 (?i)ocelot.([a-zA-Z0-9]*).json 的文件,然后合并他们。如何你要设置GlobalConfiguration 属性,那么你需要建立一个ocelot.global.json 的文件来进行全局的配置。

这里上一个例子吧!可以方便大家的理解。

新建一个ocelot.good.json文件,并加入下面的配置:

<span style="color:#333333"><code>{
  <span style="color:red">"ReRoutes"</span>: [
    {
      <span style="color:red">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/api/{everything}"</span>,
      <span style="color:red">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,
      <span style="color:red">"DownstreamHostAndPorts"</span>: [
        {
          <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:red">"Port"</span>: <span style="color:#000000">1001</span>
        },
        {
          <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:red">"Port"</span>: <span style="color:#000000">1002</span>
        }
      ],
      <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/good/{everything}"</span>,
      <span style="color:red">"UpstreamHttpMethod"</span>: [ <span style="color:#a31515">"Get"</span>, <span style="color:#a31515">"Post"</span> ],
      <span style="color:red">"LoadBalancerOptions"</span>: {
        <span style="color:red">"Type"</span>: <span style="color:#a31515">"RoundRobin"</span>
      }
    }
  ]
}
</code></span>

然后再新建一个ocelot.order.json文件,并加入下面的配置:

<span style="color:#333333"><code>{
  <span style="color:red">"ReRoutes"</span>: [
    {
      <span style="color:red">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/api/{everything}"</span>,
      <span style="color:red">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,
      <span style="color:red">"DownstreamHostAndPorts"</span>: [
        {
          <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:red">"Port"</span>: <span style="color:#000000">1001</span>
        },
        {
          <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:red">"Port"</span>: <span style="color:#000000">1002</span>
        }
      ],
      <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/order/{everything}"</span>,
      <span style="color:red">"UpstreamHttpMethod"</span>: [ <span style="color:#a31515">"Get"</span>, <span style="color:#a31515">"Post"</span> ],
      <span style="color:red">"LoadBalancerOptions"</span>: {
        <span style="color:red">"Type"</span>: <span style="color:#a31515">"RoundRobin"</span>
      }
    }
  ]
}
</code></span>

最后新建一个ocelot.all.json文件,并把上篇文章中的路由拷贝到里面:

<span style="color:#333333"><code>{
  <span style="color:red">"ReRoutes"</span>: [
    {
      <span style="color:red">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/api/{everything}"</span>,
      <span style="color:red">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,
      <span style="color:red">"DownstreamHostAndPorts"</span>: [
        {
          <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:red">"Port"</span>: <span style="color:#000000">1001</span>
        },
        {
          <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:red">"Port"</span>: <span style="color:#000000">1002</span>
        }
      ],
      <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/{everything}"</span>,
      <span style="color:red">"UpstreamHttpMethod"</span>: [ <span style="color:#a31515">"Get"</span>, <span style="color:#a31515">"Post"</span> ],
      <span style="color:red">"LoadBalancerOptions"</span>: {
        <span style="color:red">"Type"</span>: <span style="color:#a31515">"RoundRobin"</span>
      }
    }
  ],
  <span style="color:red">"GlobalConfiguration"</span>: {

  }
}

</code></span>

然后修改下,Program.cs文件中的代码如下:

<span style="color:#333333"><code><span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> IWebHostBuilder <span style="color:#a31515">CreateWebHostBuilder</span>(<span style="color:#0000ff">string</span>[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config
                        .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                        .AddJsonFile(<span style="color:#a31515">"appsettings.json"</span>, <span style="color:#a31515">true</span>, <span style="color:#a31515">true</span>)
                        .AddJsonFile(<span style="color:#a31515">$"appsettings.<span style="color:#a31515">{hostingContext.HostingEnvironment.EnvironmentName}</span>.json"</span>, <span style="color:#a31515">true</span>, <span style="color:#a31515">true</span>)
                        .AddOcelot()
                        .AddEnvironmentVariables();
                })
                .UseUrls(<span style="color:#a31515">"http://localhost:1000"</span>)
                .UseStartup<Startup>();</code></span>

这里最重要的代码就是config.AddOcelot()了。这段代码就会按照上面的规则查找所有符合条件的文件并合并路由。合并后的代码如下:

<span style="color:#333333"><code>{
  <span style="color:red">"ReRoutes"</span>: [
    {
      <span style="color:red">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/api/{everything}"</span>,
      <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/{everything}"</span>,
      <span style="color:red">"UpstreamHttpMethod"</span>: [ <span style="color:#a31515">"Get"</span>, <span style="color:#a31515">"Post"</span> ],
      <span style="color:red">"AddHeadersToRequest"</span>: {},
      <span style="color:red">"UpstreamHeaderTransform"</span>: {},
      <span style="color:red">"DownstreamHeaderTransform"</span>: {},
      <span style="color:red">"AddClaimsToRequest"</span>: {},
      <span style="color:red">"RouteClaimsRequirement"</span>: {},
      <span style="color:red">"AddQueriesToRequest"</span>: {},
      <span style="color:red">"RequestIdKey"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"FileCacheOptions"</span>: {
        <span style="color:red">"TtlSeconds"</span>: <span style="color:#000000">0</span>,
        <span style="color:red">"Region"</span>: <span style="color:#a31515">null</span>
      },
      <span style="color:red">"ReRouteIsCaseSensitive"</span>: <span style="color:#a31515">false</span>,
      <span style="color:red">"ServiceName"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,
      <span style="color:red">"QoSOptions"</span>: {
        <span style="color:red">"ExceptionsAllowedBeforeBreaking"</span>: <span style="color:#000000">0</span>,
        <span style="color:red">"DurationOfBreak"</span>: <span style="color:#000000">0</span>,
        <span style="color:red">"TimeoutValue"</span>: <span style="color:#000000">0</span>
      },
      <span style="color:red">"LoadBalancerOptions"</span>: {
        <span style="color:red">"Type"</span>: <span style="color:#a31515">"RoundRobin"</span>,
        <span style="color:red">"Key"</span>: <span style="color:#a31515">null</span>,
        <span style="color:red">"Expiry"</span>: <span style="color:#000000">0</span>
      },
      <span style="color:red">"RateLimitOptions"</span>: {
        <span style="color:red">"ClientWhitelist"</span>: [],
        <span style="color:red">"EnableRateLimiting"</span>: <span style="color:#a31515">false</span>,
        <span style="color:red">"Period"</span>: <span style="color:#a31515">null</span>,
        <span style="color:red">"PeriodTimespan"</span>: <span style="color:#000000">0.0</span>,
        <span style="color:red">"Limit"</span>: <span style="color:#000000">0</span>
      },
      <span style="color:red">"AuthenticationOptions"</span>: {
        <span style="color:red">"AuthenticationProviderKey"</span>: <span style="color:#a31515">null</span>,
        <span style="color:red">"AllowedScopes"</span>: []
      },
      <span style="color:red">"HttpHandlerOptions"</span>: {
        <span style="color:red">"AllowAutoRedirect"</span>: <span style="color:#a31515">false</span>,
        <span style="color:red">"UseCookieContainer"</span>: <span style="color:#a31515">false</span>,
        <span style="color:red">"UseTracing"</span>: <span style="color:#a31515">false</span>,
        <span style="color:red">"UseProxy"</span>: <span style="color:#a31515">true</span>
      },
      <span style="color:red">"DownstreamHostAndPorts"</span>: [
        {
          <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:red">"Port"</span>: <span style="color:#000000">1001</span>
        },
        {
          <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:red">"Port"</span>: <span style="color:#000000">1002</span>
        }
      ],
      <span style="color:red">"UpstreamHost"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"Key"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"DelegatingHandlers"</span>: [],
      <span style="color:red">"Priority"</span>: <span style="color:#000000">1</span>,
      <span style="color:red">"Timeout"</span>: <span style="color:#000000">0</span>,
      <span style="color:red">"DangerousAcceptAnyServerCertificateValidator"</span>: <span style="color:#a31515">false</span>
    },
    {
      <span style="color:red">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/api/{everything}"</span>,
      <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/good/{everything}"</span>,
      <span style="color:red">"UpstreamHttpMethod"</span>: [ <span style="color:#a31515">"Get"</span>, <span style="color:#a31515">"Post"</span> ],
      <span style="color:red">"AddHeadersToRequest"</span>: {},
      <span style="color:red">"UpstreamHeaderTransform"</span>: {},
      <span style="color:red">"DownstreamHeaderTransform"</span>: {},
      <span style="color:red">"AddClaimsToRequest"</span>: {},
      <span style="color:red">"RouteClaimsRequirement"</span>: {},
      <span style="color:red">"AddQueriesToRequest"</span>: {},
      <span style="color:red">"RequestIdKey"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"FileCacheOptions"</span>: {
        <span style="color:red">"TtlSeconds"</span>: <span style="color:#000000">0</span>,
        <span style="color:red">"Region"</span>: <span style="color:#a31515">null</span>
      },
      <span style="color:red">"ReRouteIsCaseSensitive"</span>: <span style="color:#a31515">false</span>,
      <span style="color:red">"ServiceName"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,
      <span style="color:red">"QoSOptions"</span>: {
        <span style="color:red">"ExceptionsAllowedBeforeBreaking"</span>: <span style="color:#000000">0</span>,
        <span style="color:red">"DurationOfBreak"</span>: <span style="color:#000000">0</span>,
        <span style="color:red">"TimeoutValue"</span>: <span style="color:#000000">0</span>
      },
      <span style="color:red">"LoadBalancerOptions"</span>: {
        <span style="color:red">"Type"</span>: <span style="color:#a31515">"RoundRobin"</span>,
        <span style="color:red">"Key"</span>: <span style="color:#a31515">null</span>,
        <span style="color:red">"Expiry"</span>: <span style="color:#000000">0</span>
      },
      <span style="color:red">"RateLimitOptions"</span>: {
        <span style="color:red">"ClientWhitelist"</span>: [],
        <span style="color:red">"EnableRateLimiting"</span>: <span style="color:#a31515">false</span>,
        <span style="color:red">"Period"</span>: <span style="color:#a31515">null</span>,
        <span style="color:red">"PeriodTimespan"</span>: <span style="color:#000000">0.0</span>,
        <span style="color:red">"Limit"</span>: <span style="color:#000000">0</span>
      },
      <span style="color:red">"AuthenticationOptions"</span>: {
        <span style="color:red">"AuthenticationProviderKey"</span>: <span style="color:#a31515">null</span>,
        <span style="color:red">"AllowedScopes"</span>: []
      },
      <span style="color:red">"HttpHandlerOptions"</span>: {
        <span style="color:red">"AllowAutoRedirect"</span>: <span style="color:#a31515">false</span>,
        <span style="color:red">"UseCookieContainer"</span>: <span style="color:#a31515">false</span>,
        <span style="color:red">"UseTracing"</span>: <span style="color:#a31515">false</span>,
        <span style="color:red">"UseProxy"</span>: <span style="color:#a31515">true</span>
      },
      <span style="color:red">"DownstreamHostAndPorts"</span>: [
        {
          <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:red">"Port"</span>: <span style="color:#000000">1001</span>
        },
        {
          <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:red">"Port"</span>: <span style="color:#000000">1002</span>
        }
      ],
      <span style="color:red">"UpstreamHost"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"Key"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"DelegatingHandlers"</span>: [],
      <span style="color:red">"Priority"</span>: <span style="color:#000000">1</span>,
      <span style="color:red">"Timeout"</span>: <span style="color:#000000">0</span>,
      <span style="color:red">"DangerousAcceptAnyServerCertificateValidator"</span>: <span style="color:#a31515">false</span>
    },
    {
      <span style="color:red">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/api/{everything}"</span>,
      <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/order/{everything}"</span>,
      <span style="color:red">"UpstreamHttpMethod"</span>: [ <span style="color:#a31515">"Get"</span>, <span style="color:#a31515">"Post"</span> ],
      <span style="color:red">"AddHeadersToRequest"</span>: {},
      <span style="color:red">"UpstreamHeaderTransform"</span>: {},
      <span style="color:red">"DownstreamHeaderTransform"</span>: {},
      <span style="color:red">"AddClaimsToRequest"</span>: {},
      <span style="color:red">"RouteClaimsRequirement"</span>: {},
      <span style="color:red">"AddQueriesToRequest"</span>: {},
      <span style="color:red">"RequestIdKey"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"FileCacheOptions"</span>: {
        <span style="color:red">"TtlSeconds"</span>: <span style="color:#000000">0</span>,
        <span style="color:red">"Region"</span>: <span style="color:#a31515">null</span>
      },
      <span style="color:red">"ReRouteIsCaseSensitive"</span>: <span style="color:#a31515">false</span>,
      <span style="color:red">"ServiceName"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,
      <span style="color:red">"QoSOptions"</span>: {
        <span style="color:red">"ExceptionsAllowedBeforeBreaking"</span>: <span style="color:#000000">0</span>,
        <span style="color:red">"DurationOfBreak"</span>: <span style="color:#000000">0</span>,
        <span style="color:red">"TimeoutValue"</span>: <span style="color:#000000">0</span>
      },
      <span style="color:red">"LoadBalancerOptions"</span>: {
        <span style="color:red">"Type"</span>: <span style="color:#a31515">"RoundRobin"</span>,
        <span style="color:red">"Key"</span>: <span style="color:#a31515">null</span>,
        <span style="color:red">"Expiry"</span>: <span style="color:#000000">0</span>
      },
      <span style="color:red">"RateLimitOptions"</span>: {
        <span style="color:red">"ClientWhitelist"</span>: [],
        <span style="color:red">"EnableRateLimiting"</span>: <span style="color:#a31515">false</span>,
        <span style="color:red">"Period"</span>: <span style="color:#a31515">null</span>,
        <span style="color:red">"PeriodTimespan"</span>: <span style="color:#000000">0.0</span>,
        <span style="color:red">"Limit"</span>: <span style="color:#000000">0</span>
      },
      <span style="color:red">"AuthenticationOptions"</span>: {
        <span style="color:red">"AuthenticationProviderKey"</span>: <span style="color:#a31515">null</span>,
        <span style="color:red">"AllowedScopes"</span>: []
      },
      <span style="color:red">"HttpHandlerOptions"</span>: {
        <span style="color:red">"AllowAutoRedirect"</span>: <span style="color:#a31515">false</span>,
        <span style="color:red">"UseCookieContainer"</span>: <span style="color:#a31515">false</span>,
        <span style="color:red">"UseTracing"</span>: <span style="color:#a31515">false</span>,
        <span style="color:red">"UseProxy"</span>: <span style="color:#a31515">true</span>
      },
      <span style="color:red">"DownstreamHostAndPorts"</span>: [
        {
          <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:red">"Port"</span>: <span style="color:#000000">1001</span>
        },
        {
          <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
          <span style="color:red">"Port"</span>: <span style="color:#000000">1002</span>
        }
      ],
      <span style="color:red">"UpstreamHost"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"Key"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"DelegatingHandlers"</span>: [],
      <span style="color:red">"Priority"</span>: <span style="color:#000000">1</span>,
      <span style="color:red">"Timeout"</span>: <span style="color:#000000">0</span>,
      <span style="color:red">"DangerousAcceptAnyServerCertificateValidator"</span>: <span style="color:#a31515">false</span>
    }
  ],
  <span style="color:red">"DynamicReRoutes"</span>: [],
  <span style="color:red">"Aggregates"</span>: [],
  <span style="color:red">"GlobalConfiguration"</span>: {
    <span style="color:red">"RequestIdKey"</span>: <span style="color:#a31515">null</span>,
    <span style="color:red">"ServiceDiscoveryProvider"</span>: {
      <span style="color:red">"Host"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"Port"</span>: <span style="color:#000000">0</span>,
      <span style="color:red">"Type"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"Token"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"ConfigurationKey"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"PollingInterval"</span>: <span style="color:#000000">0</span>
    },
    <span style="color:red">"RateLimitOptions"</span>: {
      <span style="color:red">"ClientIdHeader"</span>: <span style="color:#a31515">"ClientId"</span>,
      <span style="color:red">"QuotaExceededMessage"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"RateLimitCounterPrefix"</span>: <span style="color:#a31515">"ocelot"</span>,
      <span style="color:red">"DisableRateLimitHeaders"</span>: <span style="color:#a31515">false</span>,
      <span style="color:red">"HttpStatusCode"</span>: <span style="color:#000000">429</span>
    },
    <span style="color:red">"QoSOptions"</span>: {
      <span style="color:red">"ExceptionsAllowedBeforeBreaking"</span>: <span style="color:#000000">0</span>,
      <span style="color:red">"DurationOfBreak"</span>: <span style="color:#000000">0</span>,
      <span style="color:red">"TimeoutValue"</span>: <span style="color:#000000">0</span>
    },
    <span style="color:red">"BaseUrl"</span>: <span style="color:#a31515">null</span>,
    <span style="color:red">"LoadBalancerOptions"</span>: {
      <span style="color:red">"Type"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"Key"</span>: <span style="color:#a31515">null</span>,
      <span style="color:red">"Expiry"</span>: <span style="color:#000000">0</span>
    },
    <span style="color:red">"DownstreamScheme"</span>: <span style="color:#a31515">null</span>,
    <span style="color:red">"HttpHandlerOptions"</span>: {
      <span style="color:red">"AllowAutoRedirect"</span>: <span style="color:#a31515">false</span>,
      <span style="color:red">"UseCookieContainer"</span>: <span style="color:#a31515">false</span>,
      <span style="color:red">"UseTracing"</span>: <span style="color:#a31515">false</span>,
      <span style="color:red">"UseProxy"</span>: <span style="color:#a31515">true</span>
    }
  }
}</code></span>

Ocelot的合并方式是先对满足格式的文件遍历查找,然后循环加载他们,并提取所有的ReRoutes以及AggregateReRoutes 的数据。如果发现ocelot.global.json ,则添加到GlobalConfiguration 中。然后Ocelto会将合并后的配置保存在ocelot.json的文件中,当Ocelot运行时会加载这个合并后的ocelot.json文件,从而加载了所有的配置。

注意:这里需要注意的是Ocelot在合并的过程中不会对内容进行验证,只有在最终合并的配置进行校验,所以如果发现问题的话,那么你需要检查最终生成的ocelot.json 是否出错了!

在consul中存储配置

这里你首先要做的就是安装Ocelot中提供的Consul的NuGet包,Nuget安装方式:

Install-Package Ocelot.Provider.Consul

然后在注册服务时添加如下内容:Ocelot将会尝试在Consul KV存储并加载配置。

<span style="color:#333333"><code><span style="color:#0000ff">services</span>
   <span style="color:#000000">.AddOcelot</span>()
   <span style="color:#000000">.AddConsul</span>()
   <span style="color:#000000">.AddConfigStoredInConsul</span>();</code></span>

当然你还得把下面的配置添加到你的ocelot.json文件中。这里定义Ocelot如何查找Consul根并从Consul中加载并存储配置.

<span style="color:#333333"><code><span style="color:#a31515">"GlobalConfiguration"</span>: {
    <span style="color:#a31515">"ServiceDiscoveryProvider"</span>: {
        <span style="color:#a31515">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
        <span style="color:#a31515">"Port"</span>: <span style="color:#000000">9500</span>
    }
}</code></span>

变化时重新加载配置文件

Ocelot支持在配置文件发生改变的时候重新加载json配置文件。在加载ocelot.json文件的时候按照下面进行配置,那么当你手动更新ocelot.json文件时,Ocelot将重新加载ocelot.json配置文件。

config.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);

配置Key

如果你使用Consul进行配置,你可能需要配置Key以便区分多个配置,为了指定Key,你需要在json配置文件中的ServiceDiscoveryProvider部分设置ConfigurationKey属性:

<span style="color:#333333"><code><span style="color:#a31515">"GlobalConfiguration"</span>: {
    <span style="color:#a31515">"ServiceDiscoveryProvider"</span>: {
        <span style="color:#a31515">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
        <span style="color:#a31515">"Port"</span>: <span style="color:#000000">9500</span>,
        <span style="color:#a31515">"ConfigurationKey"</span>: <span style="color:#a31515">"Oceolot_A"</span>
    }
}</code></span>

在此实例中,Ocelot将会在Consul查找时使用Oceolot_A 作为配置的Key.如果没有设置ConfigurationKey 则Ocelot将使用字符串InternalConfiguration 作为此配置的Key

跟踪重定向和使用CookieContainer

在ReRoute配置中可以使用HttpHandlerOptions来设置HttpHandler行为:

  1. AllowAutoRedirect是一个值,指示请求是否应遵循重定向响应。如果请求应自动遵循来自下游资源的重定向响应,则将其设置为true; 否则是假的。默认值为false。
  2. UseCookieContainer是一个值,指示处理程序是否使用CookieContainer属性存储服务器cookie并在发送请求时使用这些cookie。默认值为false。请注意,如果您使CookieContainer,则Ocelot会为每个下游服务缓存HttpClient。这意味着对该DownstreamService的所有请求将共享相同的cookie。

SSL 错误处理

如果你想忽略SSL 警告/错误,你可以在你的ReRoute 配置中加上如下配置:

<span style="color:#333333"><code><span style="color:red">"DangerousAcceptAnyServerCertificateValidator":</span> <span style="color:#a31515">false</span></code></span>

当然作者是不建议这样做的,最好的方式是创建你本地以及远程所信任的证书。

Ocelot路由详解

路由

Ocelot的最主要的功能是接收传入的http请求并将其转发到下游服务。

Ocelot使用ReRoute节点描述将一个请求路由到另一个请求。为了让路由在Ocelot中起作用,您需要在配置中设置ReRoute:

<span style="color:#333333"><code>{
    <span style="color:red">"ReRoutes"</span>: [
    ]
}</code></span>

要配置ReRoute,您需要在ReRoutes json数组中至少添加一个:

<span style="color:#333333"><code>{
    <span style="color:#a31515">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/api/good/{goodId}"</span>,<span style="color:green">//下游路由模板</span>
    <span style="color:#a31515">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,<span style="color:green">//下游路由请求的方式</span>
    <span style="color:#a31515">"DownstreamHostAndPorts"</span>: [<span style="color:green">//下游路由的Host以及端口</span>
            {
                <span style="color:#a31515">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
                <span style="color:#a31515">"Port"</span>: <span style="color:#000000">1001</span>,
            }
        ],
    <span style="color:#a31515">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/good/{goodId}"</span>,<span style="color:green">//上游路由请求的模板</span>
    <span style="color:#a31515">"UpstreamHttpMethod"</span>: [ <span style="color:#a31515">"Put"</span>, <span style="color:#a31515">"Delete"</span> ]<span style="color:green">//上游路由请求的方式</span>
}</code></span>

DownstreamPathTemplate,DownstreamScheme和DownstreamHostAndPorts定义请求将转发到的URL。

DownstreamHostAndPorts是一个集合,用于定义您希望将请求转发到的任何下游服务的主机和端口。通常这只包含一个条目,但有时你希望对下游请求服务进行负载均衡,这个时候你就可以添加多个条目,并配合负载均衡选项进行相关的负载均衡设置。

UpstreamPathTemplate是Ocelot用于标识要用于给定请求的DownstreamPathTemplate对应的URL。使用UpstreamHttpMethod以便Ocelot可以区分具有不同HTTP谓词的请求到相同的URL。您可以设置特定的HTTP方法列表,也可以设置一个空列表以允许所有的。

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

你也可以像下面这样配置,捕获所有的路由:

<span style="color:#333333"><code>{
    <span style="color:red">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/api/{everything}"</span>,
    <span style="color:red">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,
    <span style="color:red">"DownstreamHostAndPorts"</span>: [
            {
                <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
                <span style="color:red">"Port"</span>: <span style="color:#000000">1001</span>,
            },
            {
                <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
                <span style="color:red">"Port"</span>: <span style="color:#000000">1002</span>,
            }
        ],
    <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/{everything}"</span>,
    <span style="color:red">"UpstreamHttpMethod"</span>: [ <span style="color:#a31515">"Get"</span>, <span style="color:#a31515">"Post"</span> ]
}</code></span>

这个配置将会把路径+查询字符串统统转发到下游路由.

注意:默认的ReRouting的配置是不区分大小写的,如果需要修改此配置,可以通过下面进行配置:

"ReRouteIsCaseSensitive": true

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

全部捕获

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

如果您设置如下所示的配置,则所有请求都将直接代理。占位符{url}名称不重要,任何名称都可以使用。

<span style="color:#333333"><code>{
    <span style="color:red">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/{url}"</span>,
    <span style="color:red">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,
    <span style="color:red">"DownstreamHostAndPorts"</span>: [
            {
                <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
                <span style="color:red">"Port"</span>: <span style="color:#000000">1001</span>,
            }
        ],
    <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/{url}"</span>,
    <span style="color:red">"UpstreamHttpMethod"</span>: [ <span style="color:#a31515">"Get"</span> ]
}</code></span>

上面配置的全部捕获的优先级低于任何其他法人ReRoute。如果您的配置中还有下面的ReRoute,那么Ocelot会在全部捕获之前匹配它。

<span style="color:#333333"><code>{
    <span style="color:red">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/"</span>,
    <span style="color:red">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,
    <span style="color:red">"DownstreamHostAndPorts"</span>: [
            {
                <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
                <span style="color:red">"Port"</span>: <span style="color:#000000">1001</span>,
            }
        ],
    <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/"</span>,
    <span style="color:red">"UpstreamHttpMethod"</span>: [ <span style="color:#a31515">"Get"</span> ]
}</code></span>

上游主机

此功能允许您根据上游主机获得ReRoutes。这通过查看客户端使用的主机头,然后将其用作我们用于识别ReRoute的信息的一部分来工作。

要使用此功能,请在配置中添加以下内容。

<span style="color:#333333"><code>{
    <span style="color:red">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/"</span>,
    <span style="color:red">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,
    <span style="color:red">"DownstreamHostAndPorts"</span>: [
            {
                <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
                <span style="color:red">"Port"</span>: <span style="color:#000000">1001</span>,
            }
        ],
    <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/"</span>,
    <span style="color:red">"UpstreamHttpMethod"</span>: [ <span style="color:#a31515">"Get"</span> ],
    <span style="color:red">"UpstreamHost"</span>: <span style="color:#a31515">"yilezhu.cn"</span>
}</code></span>

仅当主机标头值为yilezhu.cn时,才会匹配上面的ReRoute。

如果您没有在ReRoute上设置UpstreamHost,那么任何主机头都将与之匹配。这意味着如果你有两个相同的ReRoutes,除了UpstreamHost,其中一个为null而另一个不为null 那么Ocelot将支持已设置的那个。

优先级

你可以通过ocelot.json文件的ReRoutes节点中的Priorty属性来设置匹配上游HttpRequest的优先级顺序
比如,下面两个路由:

<span style="color:#333333"><code>{
    <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/goods/{catchAll}"</span>
    <span style="color:#a31515">"Priority"</span>: <span style="color:#000000">0</span>
}</code></span>

以及

<span style="color:#333333"><code>{
    <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/goods/delete"</span>
    <span style="color:#a31515">"Priority"</span>: <span style="color:#000000">1</span>
}</code></span>

上面两个路由中,如果向Ocelot发出的请求时/goods/delete格式的话,则Ocelot会优先匹配/goods /delete 的路由。

动态路由

作者的想法是在使用服务发现提供程序时启用动态路由,这样您就不必提供ReRoute的配置。我们会在服务发现那一章进行详细的介绍。

查询字符串

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

<span style="color:#333333"><code>{
    <span style="color:red">"ReRoutes"</span>: [
        {
            <span style="color:red">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/api/subscriptions/{subscriptionId}/updates?unitId={unitId}"</span>,
            <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/api/units/{subscriptionId}/{unitId}/updates"</span>,
            <span style="color:red">"UpstreamHttpMethod"</span>: [
                <span style="color:#a31515">"Get"</span>
            ],
            <span style="color:red">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,
            <span style="color:red">"DownstreamHostAndPorts"</span>: [
                {
                    <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
                    <span style="color:red">"Port"</span>: <span style="color:#000000">50110</span>
                }
            ]
        }
    ],
    <span style="color:red">"GlobalConfiguration"</span>: {
    }
}</code></span>

在此示例中,Ocelot将使用上游路径模板中{unitId}的值,并将其作为名为unitId的查询字符串参数添加到下游请求中!

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

<span style="color:#333333"><code>{
    <span style="color:red">"ReRoutes"</span>: [
        {
            <span style="color:red">"DownstreamPathTemplate"</span>: <span style="color:#a31515">"/api/units/{subscriptionId}/{unitId}/updates"</span>,
            <span style="color:red">"UpstreamPathTemplate"</span>: <span style="color:#a31515">"/api/subscriptions/{subscriptionId}/updates?unitId={unitId}"</span>,
            <span style="color:red">"UpstreamHttpMethod"</span>: [
                <span style="color:#a31515">"Get"</span>
            ],
            <span style="color:red">"DownstreamScheme"</span>: <span style="color:#a31515">"http"</span>,
            <span style="color:red">"DownstreamHostAndPorts"</span>: [
                {
                    <span style="color:red">"Host"</span>: <span style="color:#a31515">"localhost"</span>,
                    <span style="color:red">"Port"</span>: <span style="color:#000000">50110</span>
                }
            ]
        }
    ],
    <span style="color:red">"GlobalConfiguration"</span>: {
    }
}</code></span>

在此示例中,Ocelot将仅匹配具有匹配的url路径的请求,并且查询字符串以unitId = something开头。您可以在此之后进行其他查询,但必须以匹配参数开头。此外,Ocelot将交换查询字符串中的{unitId}参数,并在下游请求路径中使用它。

源码地址

当然是放上实例中的源码地址了:https://github.com/yilezhu/OcelotDemo

 

 

总结

本文主要是对Ocelot的新特性以及路由进行详细的介绍,这些介绍对你使用ocelot会有很大的帮助。下篇文章呢,我会对请求聚合以及服务发现以及动态路由进行记录,敬请期待!同时需要说明一点是,本文大部分内容是翻译自官方文档,当然中间穿插着自己在使用过程中一些理解,希望大家能够喜欢!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章