.NET Core微服务之基于Ocelot实现API网关服务

Tip: 此篇已加入.NET Core微服务基础系列文章索引html

1、啥是API网关?

  API 网关通常放到微服务的最前端,而且要让API 网关变成由应用所发起的每一个请求的入口。这样就能够明显的简化客户端实现和微服务应用程序之间的沟通方式。之前的话,客户端不得不去请求微服务A(假设为Customers),而后再到微服务B(假设为Orders),而后是微服务C(假设为Invoices)。客户端须要去知道怎么去一块儿来消费这三个不一样的service。使用API网关,咱们能够抽象全部这些复杂性,并建立客户端们可使用的优化后的端点,并向那些模块们发出请求。API网关的核心要点是:全部的客户端和消费端都经过统一的网关接入微服务,在网关层处理全部的非业务功能(好比验证、鉴权、监控等等)。前端

  关于API网关,我的以为园友杨晓东的这篇文章《谈谈微服务中的API网关》值得一读。微服务架构中的任何一个环节,都是能够说好久的,而我没有太多经验,也就很少谈了。git

2、开源项目:Ocelot

  Ocelot是一个使用.NET Core平台上的一个API Gateway,这个项目的目标是在.NET上面运行微服务架构。Ocelot框架内部集成了IdentityServer(身份验证)和Consul(服务注册发现),还引入了Polly(上一篇博文中提到过)来处理进行故障处理。目前,腾讯和微软是Ocelot在官网贴出来的客户,我想也是由于这两家公司都是巨头,因此要标榜一下,哈哈。github

  Ocelot github : https://github.com/TomPallister/Ocelotjson

3、快速开始第一个API网关

3.1 安装Ocelot

NuGet>Install-Package Ocelot  后端

3.2 快速准备两个API服务

  (1)准备一个ClientServiceapi

  

  建立一个ASP.NET Core WebAPI程序,保留默认ValuesController,作一下修改:数组

[Route("api/[controller]")] public class ValuesController : Controller { // GET api/values
 [HttpGet] public IEnumerable<string> Get() { return new string[] { "ClinetService-value1", "ClinetService-value2" }; } ...... }

  (2)准备一个ProductService浏览器

  

  建立一个ASP.NET Core WebAPI程序,保留默认ValuesController,作一下修改:缓存

[Route("api/[controller]")] public class ValuesController : Controller { // GET api/values
 [HttpGet] public IEnumerable<string> Get() { return new string[] { "ProductService-value1", "ProductService-value2" }; } ...... }

3.3 静态配置两个API服务

  建立一个ASP.NET Core WebAPI程序,这里命名为APIGateway.

  (1)新建一个json文件:eg.configuration.json

  首先,一个最基本的配置文件以下:

{ "ReRoutes": [], "GlobalConfiguration": { "BaseUrl": "https://api.mybusiness.com" } }

  这里特别注意一下BaseUrl是咱们外部暴露的Url,好比咱们的Ocelot运行在http://123.111.11.1的一个地址上,可是前面有一个Nginx绑定了域名http://api.edisonchou.cn,那这里咱们的BaseUrl就是 http://api.edisonchou.cn。如今咱们的实验环境不存在这个条件,因此咱们暂时不须要配置这个option。下面咱们根据模板将刚刚建立并启动的两个Service的信息进行了配置:

{ "ReRoutes": [ // API:CAS.ClientService { "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "192.168.2.231", "Port": "8810" } ], "UpstreamPathTemplate": "/ClientService/{url}", "UpstreamHttpMethod": [ "Get", "Post" ] }, // API:CAS.ProductService { "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "192.168.2.231", "Port": "8820" } ], "UpstreamPathTemplate": "/ProductService/{url}", "UpstreamHttpMethod": [ "Get", "Post" ] } ] }

  其中,咱们得了解一下微服务架构中的上游服务器和下游服务器,通常下游服务器指的是提供API服务的REST Service Server(好比WebAPI、WCF App等),而上游服务器则指的是提供Web网页服务的Web Server(好比MVC Application,可能须要访问REST Service)。那么,这里咱们能够了解到:

  • Downstream 是下游服务配置 => 即咱们刚刚建立的提供API服务的配置,咱们会指定PathTemplate,Host和Port等信息(具体调哪一台服务器是由我说了算)
  • UpStream 是上游服务配置 => 即服务消费方(eg.MVC Server, SPA App)的调用配置(你要怎么按照什么URL格式和什么HTTP类型调用我才能理解)

  经过配置文件,咱们能够猜想Ocelot的实现原理大体应该就是把客户端对网关的请求(Request),按照configuration.json的映射配置,转发给对应的后端http service,而后从后端http service获取响应(Response)后,再返回给客户端。固然,具体细节应该十分复杂,等后面有时间深刻看看实现机制。

  其余再也不解释,能够看明白,另外,须要对这个配置文件进行如下设置:为了确保直接运行时可以找到这个configuration.json文件

  

  *.经过配置文件能够完成对Ocelot的功能配置:路由、服务聚合、服务发现、认证、鉴权、限流、熔断、缓存、Header头传递等。在配置文件中包含两个根节点:ReRoutes和GlobalConfiguration。ReRoutes是一个数组,其中的每个元素表明了一个路由,咱们能够针对每个路由进行以上功能配置。

  (2)改写Program和StartUp类,才能正常使用Ocelot

  ①在Program类的BuildWebHost中让程序读取configuration.json文件

public class Program { public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) { return WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseUrls($"http://{IP}:{Port}") .ConfigureAppConfiguration((hostingContext, builder) => { builder.AddJsonFile("configuration.json", false, true); }) .Build(); } }

  ②在StartUp类中为Ocelot注入配置,并启动Ocelot

public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services) { //services.AddMvc(); -- no need MVC // Ocelot
 services.AddOcelot(Configuration); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } //app.UseMvc(); -- no need MVC // Ocelot
 app.UseOcelot().Wait(); } }

3.3 测试一下

  (1)先启动ClientService和ProductService => 也能够经过在VS中更改启动顺序来指定

  

  (2)再启动APIGateway,在浏览器中直接访问API网关所在的地址和端口(这里是192.168.2.231:8800)进行测试:先请求ClientService,再请求ProductService,能够看到API网关对请求进行了转发,服务消费方不须要记住每一个service所在的IP和端口,而是只须要告诉网关我须要消费哪一个service便可。

  

  

  *.tip:这里配置的PathTemplate大小写不敏感,能够选择经过设置ReRouteIsCaseSensitive:true来实现大小写敏感

  到这里,第一个API网关的实现就结束了,可是对于众多的微服务,若是咱们都一一硬编码地配置其IP和Port在配置文件中,不适合微服务架构的风格,由于众多的服务地址变化会让静态配置的工做变得愈来愈大。所以,咱们学习了服务发现,那么是否能够结合服务发现呢?Ocelot + Consul的方式为咱们给出了答案。

4、Ocelot+Consul的结合

4.1 实验节点部署结构

  这里仍然采用以前的Consul实验集群,三个Consul Server节点(1个leader,2个follwer),一个Consul Client节点(部署了两个服务ClientService和ProductService),以及一个API网关节点(基于Ocelot)。

4.2 启动Consul

  启动方式以及步骤这里再也不赘述,如不了解请浏览个人前两篇博文《.NET Core微服务之基于Consul实现服务治理》以及《.NET Core微服务之基于Consul实现服务治理(续)》。这里能够看到,咱们已经成功地注册了ClientService和ProductService。

4.3 启动API Gateway

  (1)为了适配Consul服务发现,减小服务IP和Port的hard-code,咱们须要改一下配置文件:

{ "ReRoutes": [ // API01:CAS.ClientService { "UseServiceDiscovery": true, // use Consul service discovery "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "http", "ServiceName": "CAS.ClientService", "LoadBalancerOptions": { "Type": "RoundRobin" }, "UpstreamPathTemplate": "/api/clientservice/{url}", "UpstreamHttpMethod": [ "Get", "Post" ], "ReRoutesCaseSensitive": false // non case sensitive }, // API02:CAS.ProductService { "UseServiceDiscovery": true, // use Consul service discovery "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "http", "ServiceName": "CAS.ProductService", "LoadBalancerOptions": { "Type": "RoundRobin" }, "UpstreamPathTemplate": "/api/productservice/{url}", "UpstreamHttpMethod": [ "Get", "Post" ], "ReRoutesCaseSensitive": false // non case sensitive } ], "GlobalConfiguration": { //"BaseUrl": "https://api.mybusiness.com" "ServiceDiscoveryProvider": { "Host": "192.168.80.100", // Consul Service IP "Port": 8500 // Consul Service Port } } }

  Ocelot提供了基本的负载均衡选项(LoadBalanceOptions):轮询和最小链接数,若是咱们部署了多个同样的服务,那么咱们设置一个选项。

  (2)其余代码无须更改,对于基本用法,咱们要作的基本只是对配置文件的修改。配置完成后,便可启动API网关项目。

4.4 测试

  (1)请求ClientService

  

  (2)请求ProductService

  

5、小结

  本篇介绍了API网关的基础概念以及一个基于适合于.NET Core的开源项目Ocelot,并经过两个小案例(一个静态配置服务,一个结合Consul服务发现)来了解了API网关的做用和Ocelot的最基础的用法。下一篇会继续Ocelot的一些比较有用的功能(好比:限流、熔断、缓存,以及结合Swagger),继续作一些实践,也但愿到时能够总结下来与各位园友分享。

示例代码

  Click here => 点我下载

参考资料

杨晓东,《谈谈微服务中的API网关

桂素伟,《Ocelot + Consul实践

杨中科,《.NET微服务直播课课件pdf》

李朝强,《ASP.NET Core API网关Ocelot

jesse 腾飞,《.NET Core开源API网关 – Ocelot中文文档

Ocelot官网:https://github.com/ThreeMammals/Ocelot => tip: 张善友大队长为主要贡献者之一

Ocelot官方文档:http://ocelot.readthedocs.io/en/latest/index.html

 

做者:周旭龙

出处:http://edisonchou.cnblogs.com

本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文连接。

相关文章
相关标签/搜索