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會有很大的幫助。下篇文章呢,我會對請求聚合以及服務發現以及動態路由進行記錄,敬請期待!同時需要說明一點是,本文大部分內容是翻譯自官方文檔,當然中間穿插着自己在使用過程中一些理解,希望大家能夠喜歡!

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