Ocelot(一)- .Net Core开源网关

今天要给大家介绍的Ocelot是一个基于 .net core的开源WebAPI服务网关项目,它的功能非常强大,包括了路由、请求聚合、服务发现、认证鉴权、限流、负载均衡等功能。而这些功能都可以直接通过修改json配置文件即可使用,非常方便。Ocelot是系统中对外暴露的一个请求入口,所有外部接口都必须通过这个网关才能向下游API发出请求,就如地铁中的安检系统,所有人都必须经过安检才能乘坐地铁。

我将通过具体案例对Ocelot的功能进行一一展开说明,而本文中涉及案例的完整代码都可以从我的代码仓库进行下载。

搭建Ocelot项目

通过VS2017新建一个基于 .net core WebAPI项目,然后通过nuget直接搜索Ocelot或者使用以下命令行添加Ocelot的引用。

Install-Package Ocelot

在项目的根目录添加一个.json配置文件,文件名自定义,此案例为Ocelot.json.添加配置如下:

{    
    "ReRoutes": [],    
    "GlobalConfiguration": {}
}

可以看到在我们的配置文件中包含两个配置项,ReRoutes是一个数组,将会包含服务器的路由配置,GlobalConfiguration则是一个全局配置项。我会在下文中通过各种案例详细说明配置项中的具体内容以及如何使用,因此,在这里暂时不展开说明。
将该配置文件添加到 .net core configuration中
Program.cs

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, builder) => {
            builder.AddJsonFile("Ocelot.json");
        })
        .UseStartup<Startup>();

因为 .net core支持当配置文件被修改后会重新加载,所以如果我们需要支持重新加载,可修改为:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, builder) => {
            builder.AddJsonFile("Ocelot.json", optional: false, reloadOnChange: true);
        })
        .UseStartup<Startup>();

将Ocelot作为中间件注册,需要添加两个命名空间
Startup.cs

using Ocelot.DependencyInjection;using Ocelot.Middleware;
public void ConfigureServices(IServiceCollection services)
{    
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);    
    services.AddOcelot();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{    
    if(env.IsDevelopment())
    {        
        app.UseDeveloperExceptionPage();
    }    
    app.UseMvc();    
    app.UseOcelot().Wait();
}

至此,我们的Ocelot就已经搭建完成了。下面我们通过具体案例来说明如何修改配置进行相关功能的使用。

配置参数介绍

我们先来认识一下到底包含哪些参数,以及这些参数的含义。前面我们有介绍到,配置文件中包含两个配置项:ReRoutes和GlobalConfiguration。
我们先来看GlobalConfiguration,它是一个全局配置项,通常我们都要在这个配置项中添加一个属性BaseUrl,BaseUrl就是Ocelot服务对外暴露的Url。

"GlobalConfiguration": {"BaseUrl": "http://localhost:4727"}

ReRoutes是一个数组,其中的每一个元素代表了一个路由,而一个路由所包含的所有可配置参数如下:

{    
    "DownstreamPathTemplate": "/",    
    "UpstreamPathTemplate": "/",    
    "UpstreamHttpMethod": 
    [        
        "Get"
    ],    
    "AddHeadersToRequest": {},    
    "AddClaimsToRequest": {},    
    "RouteClaimsRequirement": {},    
    "AddQueriesToRequest": {},    
    "RequestIdKey": "",    
    "FileCacheOptions": 
    {        
        "TtlSeconds": 0,        
        "Region": ""
    },    
    "ReRouteIsCaseSensitive": false,    
    "ServiceName": "",    
    "DownstreamScheme": "http",    
    "DownstreamHostAndPorts": 
    [
        {            
        "Host": "localhost",            
        "Port": 8001,
        }
    ],    
    "QoSOptions": 
    {        
        "ExceptionsAllowedBeforeBreaking": 0,        
        "DurationOfBreak": 0,        
        "TimeoutValue": 0
    },    
    "LoadBalancer": "",    
    "RateLimitOptions": 
    {        
        "ClientWhitelist": [],        
        "EnableRateLimiting": false,        
        "Period": "",        
        "PeriodTimespan": 0,        
        "Limit": 0
    },    
    "AuthenticationOptions": 
    {        
        "AuthenticationProviderKey": "",        
        "AllowedScopes": []
    },    
    "HttpHandlerOptions": 
    {        
        "AllowAutoRedirect": true,        
        "UseCookieContainer": true,        
        "UseTracing": true
    },    
    "UseServiceDiscovery": false
}
  • Downstream 下游服务配置

  • UpStream 上游服务配置

  • Aggregates 服务聚合配置

  • ServiceName, LoadBalancer, UseServiceDiscovery 服务发现配置

  • AuthenticationOptions 服务认证配置

  • RouteClaimsRequirement Claims 鉴权配置

  • RateLimitOptions 限流配置

  • FileCacheOptions 缓存配置

  • QosOptions 服务质量与熔断配置

  • DownstreamHeaderTransform 头信息转发配置

当然,我们在实际使用过程中不需要设置所有的参数,只需要根据实际需要进行配置即可。

案例一 路由

路由是Ocelot最基本的功能。Ocelot接收到来自上游服务的请求,经过验证后,将请求转发到下游服务,因此,我们首先要配置路由当中上下游服务参数。

{    
    "DownstreamPathTemplate": "/api/ocelot/{Id}",    
    "DownstreamScheme": "http",    
    "DownstreamHostAndPorts": 
    [
      {                
        "Host": "localhost",                
        "Port": 8001,
      }
    ],    
    "UpstreamPathTemplate": "/ocelot/{Id}",    
    "UpstreamHttpMethod": ["Get"]
}
  • DownstreamPathTemplate 下游请求Url模板,{}中的内容代表动态参数

  • DownstreamScheme 下游服务http scheme

  • DownstreamHostAndPorts 下游服务的地址,如果使用LoadBalancer的话这里可以填多项

  • UpstreamPathTemplate 上游也就是用户输入的请求Url模板

  • UpstreamHttpMethod 上游请求http方法,可使用数组

因此,当上游服务向地址http://localhost:4727/ocelot/5发出请求时,Ocelot会将请求转发到下游服务http://localhost:8001/api/ocelot/5
本案例提供了下游服务Demo - OcelotDownAPI,将OcelotDownAPI发布到IIS端口即可使用。下游服务在接收到请求后返回一个字符串用于表明自己的身份。

[HttpGet("{id}")]
public async Task<IActionResult> Get(int id)
{    
  var result = await Task.Run(() =>
  {        
      return $"This is from {HttpContext.Request.Host.Value}, path: {HttpContext.Request.Path}";
  });    
  return Ok(result);
}

测试结果:
Ocelot_001_routing1.png

如果希望Ocelot能够转发所有的请求,则可以配置如下:

{    
    "DownstreamPathTemplate": "/{url}",    
    "DownstreamScheme": "http",    
    "DownstreamHostAndPorts": 
    [
      {
        "Host": "localhost",                
        "Port": 8001,
      }
    ],    
    "UpstreamPathTemplate": "/{url}",    
    "UpstreamHttpMethod": ["Get"]
}

这样就能将所有Get请求转发到下游服务。不过这样配置的优先级是最低的,一旦匹配到其它路由模板,会优先选择。

如果希望Ocelot只转发来自某个特定上游服务Host的请求,则可以配置如下:

{    
    "DownstreamPathTemplate": "/{url}",    
    "DownstreamScheme": "http",    
    "DownstreamHostAndPorts": [
                   {                
                     "Host": "localhost",                
                     "Port": 8001,
                   }
                  ],    
    "UpstreamPathTemplate": "/{url}",    
    "UpstreamHttpMethod": ["Get"],    
    "UpstreamHost": "localhost:4023"
}

这样Ocelot就只会转发来自localhost:4023的请求。需要注意的是,如果路由配置中包含两个除UpstreamHost以外都相同的路由,即其中一个带有UpstreamHost,而另外一个没有,则Ocelot会优先选择带有UpstreamHost的路由。

设置路由的优先级。我们可以定义ReRoutes路由数组中响应的优先级。0是最低的优先级,数字越大,优先级越高。

[
   {    
      "UpstreamPathTemplate": "/ocelot/{Id}"    
      "Priority": 0
   },
   {    
      "UpstreamPathTemplate": "/ocelot/10"    
      "Priority": 1
   },
]

总结

本文主要介绍了Ocelot的功能,并通过简单的案例讲述如何构建Ocelot网关以及对Ocelot的基本应用。由于Ocelot功能非常的强大,如果将所有的案例都放到同一篇文章中会导致篇幅过长,不便于阅读,因此,我将会针对Ocelot功能写成系列文章,希望大家继续捧场。


来源:.Net框架学苑(让你懂.Net)
出处:www.letyouknow.net
欢迎转载,但未经本站同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究责任的权利。
我们学的不仅是框架,更是梦想!更多技术文章汇总,请查看www.letyouknow.net

        这是一个专门分享.Net架构设计的社区,我们期望能以行动、教材、源码、视频等,逐步引导编程人员从程序员如何进阶到架构设计!故而成立.Net框架学苑,授人以渔,贡献微薄之力。

学的不仅是框架,更是梦想!再牛逼的勤奋也抵不住良师指引!
昨天、今天、明天,技术都在不断的改变
加入.Net框架学苑,我们一起去探索未来
.Net框架学苑
QQ技术群:285354514







相关文章