官方文档:https://ocelot.readthedocs.io/en/latest/features/configuration.html 

Ocelot的配置文件经常变动,参考官方文档最佳。

Ocelot可以结合Consul、Eureka实现动态服务发现,参照官方文档就可以,写得很清晰。

Ocelot可以结合Polly使用。

一、新建.Net Core MVC项目, 在Program.cs文件中引用ocelot.json配置文件

public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
    var configuration = new 
                    ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory)
                                          .AddJsonFile("hosting.json")
                                          .AddJsonFile("ocelot.json")//主要代码
                                          .Build();

            return WebHost.CreateDefaultBuilder(args).UseConfiguration(configuration)
                                                     .UseStartup<Startup>();
}

二、添加nuget的ocelot引用,在Startup.cs中配置ocelot

using Ocelot.DependencyInjection;
using Ocelot.Middleware;
public IServiceProvider ConfigureServices(IServiceCollection services)
{

       services.AddOcelot(); //主要代码
       DIIoc.Injection(services);
       
       this.ApplicationContainer = AutoFacIoc.Injection(services);
       return new AutofacServiceProvider(this.ApplicationContainer);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{

       app.UseOcelot().Wait();//主要代码
       app.Run(async (context) =>
	   {
		    await context.Response.WriteAsync("Hello World!");
	   });
}

三、ocelot.json配置说明

{
  "GlobalConfiguration": {
    "BaseUrl": "http://127.0.0.1:9099" //当前ocelot站点的域名
  },
  "ReRoutes": [
    {
      //万能模板:"/{url}"  ;万能模板的优先级最低,只要有其它的路由模板,其它的路由模板则会优先生效
      "UpstreamPathTemplate": "/{url}", //上游请求地址模板
      "UpstreamHttpMethod": [ //上游请求方式
        "Get",
        "Post"
      ],
      "DownstreamPathTemplate": "/{url}", //下游跳转地址模板;将用户的请求 /post/1 转发到 localhost/api/post/1
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [ //下游服务的地址,如果使用LoadBalancer(负载均衡算法配置项)的话这里可以填多项
        {
          "Host": "appliance.abc.com.cn",
          "Port": 80
        }
      ]
    },
    {
      "UpstreamPathTemplate": "/post/{postId}", //上游请求地址模板
      "UpstreamHttpMethod": [ //上游请求方式
        "Get"
      ],
      "DownstreamPathTemplate": "/api/post/{postId}", //下游跳转地址模板;将用户的请求 /post/1 转发到 localhost/api/post/1
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [ //下游服务的地址,如果使用LoadBalancer(负载均衡算法配置项)的话这里可以填多项
        {
          "Host": "localhost",
          "Port": 51876
        }
      ],
      "RequestIdKey": "",
      //Ocelot可以对下游请求结果进行缓存 ,目前缓存的功能还不是很强大。它主要是依赖于CacheManager 来实现的
      "FileCacheOptions": {
        "TtlSeconds": 0,
        "Region": "" //Region是对缓存进行的一个分区,我们可以调用Ocelot的 administration API来移除某个区下面的缓存
      },
      "ReRouteIsCaseSensitive": false,
      "ServiceName": "",
      //服务质量与熔断
      "QoSOptions": {
        "ExceptionsAllowedBeforeBreaking": 0, //允许多少个异常请求
        "DurationOfBreak": 0, // 熔断的时间,单位为秒
        "TimeoutValue": 0 //如果下游请求的处理时间超过多少秒则自如将请求设置为超时
      },
      // 将决定负载均衡的算法:LeastConnection–将请求发往最空闲的那个服务器;RoundRobin–轮流发送;NoLoadBalance–总是发往第一个请求或者是服务发现
      "LoadBalancer": "LeastConnection",
      //对请求进行限流可以防止下游服务器因为访问过载而崩溃
      "RateLimitOptions": {
        "ClientWhitelist": [], //白名单
        "EnableRateLimiting": false, //是否启用限流
        "Period": "5m", //1s, 5m, 1h, 1d
        "PeriodTimespan": 0, //多少秒之后客户端可以重试
        "Limit": 0, //在统计时间段内允许的最大请求数量

        //在 GlobalConfiguration下我们还可以进行以下配置
        "DisableRateLimitHeaders": false, //Http头  X-Rate-Limit 和 Retry-After 是否禁用
        "QuotaExceededMessage": "Customize Tips!", //当请求过载被截断时返回的消息
        "HttpStatusCode": 999, //当请求过载被截断时返回的http status
        "ClientIdHeader": "Test" //用来识别客户端的请求头,默认是 ClientId
      },
      //鉴权认证
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "",
        "AllowedScopes": [] //这里的Scopes将从当前 token 中的 claims中来获取,我们的鉴权服务将依靠于它来实现 。当前路由的下游API需要某个权限时,我们需要在这里声明 。和oAuth2中的scope意义一致。
      },
      //我们通过认证中的AllowedScopes 拿到claims之后,如果要进行权限的鉴别需要添加以下配置
      "RouteClaimsRequirement": {
        "UserType": "registered" //当前请求上下文的token中所带的claims如果没有 name=”UserType” 并且 value=”registered” 的话将无法访问下游服务。
      },
      "HttpHandlerOptions": {
        "AllowAutoRedirect": true,
        "UseCookieContainer": true,
        "UseTracing": true
      },
      "UseServiceDiscovery": false,

      //在请求头转化这里Ocelot为我们提供了两个变量:BaseUrl和DownstreamBaseUrl。
      //BaseUrl就是我们在GlobalConfiguration里面配置的BaseUrl,
      //DownstreamBaseUrl是下游服务的Url
      //请求头转化;比如我们将客户端传过来的Header中的Location值value1改为BaseUrl后传给下游
      "UpstreamHeaderTransform": {
        "Location": "value1, {BaseUrl}"
      },
      //我们同样可以将下游Header中的Location再转为DownstreamBaseUrl之后再转给客户端。
      "DownstreamHeaderTransform": {
        "Location": "{DownstreamBaseUrl}, {BaseUrl}"
      },
      //Claims转化: 例如:name=”sub” value=”usertypevalue|useridvalue”
      //Ocelot为我们提供的功能分为三段
      //第一段是Claims[sub],很好理解[] 里面是我们的claim的名称。
      //第二段是  > 表示对字符串进行拆分, 后面跟着拆分完之后我们要取的那个数组里面的某一个元素用 value[index]来表示,取第0位元素也可以直接用value。
      //第三段也是以 > 开头后面跟着我们的分隔符,在我们上面的例子分隔符是 |
      "AddHeadersToRequest": { // Claims to Headers
        "CustomerId": "Claims[sub] > value[1] > |" //Claims 为sub;对value进行|拆分;取索引为1的值
      },
      "AddClaimsToRequest": { //Claims to Claims
        "UserType": "Claims[sub] > value[0] > |", //Claims 为sub;对value进行|拆分;取索引为0的值
        "UserId": "Claims[sub] > value[1] > |" //Claims 为sub;对value进行|拆分;取索引为1的值
      },
      "AddQueriesToRequest": { // Claims to Query String
        "LocationId": "Claims[LocationId] > value" //Claims 为LocationId;取value的值
      }
    }
  ]
}