ASP.NET Core微服务之基于Ocelot实现API网关服务(1)

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 本篇介绍了API网关的基础概念以及一个基于适合于.NET Core的开源项目Ocelot,并通过两个小案例(一个静态配置服务,一个结合Consul服务发现)来了解了API网关的作用和Ocelot的最基础的用法。

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

一、啥是API网关?

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

  微服务架构中的任何一个环节,都是可以说很久的,而我没有太多经验,也就不多谈了。

二、开源项目:Ocelot

  Ocelot是一个使用.NET Core平台上的一个API Gateway,这个项目的目标是在.NET上面运行微服务架构。Ocelot框架内部集成了IdentityServer(身份验证)和Consul(服务注册发现),还引入了Polly(上一篇博文中提到过)来处理进行故障处理。

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

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

3.1 安装Ocelot

NuGet>Install-Package Ocelot  

3.2 快速准备两个API服务

  (1)准备一个ClientService

  创建一个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的方式为我们给出了答案。

四、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

五、小结

  本篇介绍了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

目录
相关文章
|
4天前
|
安全 Java API
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)(上)
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)
23 0
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)(上)
|
30天前
|
API 数据库 数据安全/隐私保护
利用Django框架构建高效后端API服务
本文将介绍如何利用Django框架构建高效的后端API服务。通过深入分析Django框架的特性和优势,结合实际案例,探讨了如何利用Django提供的强大功能来构建高性能、可扩展的后端服务。同时,还对Django框架在后端开发中的一些常见问题进行了解决方案的探讨,并提出了一些建设性的建议。
48 3
|
7天前
|
API
阿里云微服务引擎及 API 网关 2024 年 3 月产品动态
阿里云微服务引擎及 API 网关 2024 年 3 月产品动态。
|
8天前
|
监控 JavaScript 安全
构建微服务架构下的API网关
【4月更文挑战第15天】在微服务架构中,API网关扮演着至关重要的角色。它作为系统的唯一入口,不仅负责请求的路由、负载均衡和认证授权,还涉及到监控、日志记录和服务熔断等关键功能。本文将探讨如何构建一个高效且可靠的API网关,涵盖其设计原则、核心组件以及实现策略,旨在为后端开发人员提供一套实用的指导方案。
22 4
|
21天前
|
前端开发 Java API
构建RESTful API:Java中的RESTful服务开发
【4月更文挑战第3天】本文介绍了在Java环境中构建RESTful API的重要性及方法。遵循REST原则,利用HTTP方法处理资源,实现CRUD操作。在Java中,常用框架如Spring MVC简化了RESTful服务开发,包括定义资源、设计表示层、实现CRUD、考虑安全性、文档和测试。通过Spring MVC示例展示了创建RESTful服务的步骤,强调了其在现代Web服务开发中的关键角色,有助于提升互操作性和用户体验。
构建RESTful API:Java中的RESTful服务开发
|
27天前
|
安全 API 开发者
构建高效可扩展的RESTful API服务
在数字化转型的浪潮中,构建一个高效、可扩展且易于维护的后端API服务是企业竞争力的关键。本文将深入探讨如何利用现代后端技术栈实现RESTful API服务的优化,包括代码结构设计、性能调优、安全性强化以及微服务架构的应用。我们将通过实践案例分析,揭示后端开发的最佳实践,帮助开发者提升系统的响应速度和处理能力,同时确保服务的高可用性和安全。
26 3
|
30天前
|
消息中间件 缓存 API
微服务架构下的API网关性能优化实践
在现代的软件开发中,微服务架构因其灵活性和可扩展性被广泛采用。随着服务的细分与增多,API网关作为微服务架构中的关键组件,承担着请求路由、负载均衡、权限校验等重要职责。然而,随着流量的增长和业务复杂度的提升,API网关很容易成为性能瓶颈。本文将深入探讨API网关在微服务环境中的性能优化策略,包括缓存机制、连接池管理、异步处理等方面的具体实现,旨在为开发者提供实用的性能提升指导。
|
1月前
|
缓存 负载均衡 监控
构建高效微服务架构:API网关的作用与实践
【2月更文挑战第31天】 在当今的软件开发领域,微服务架构已成为实现系统高度模块化和易于扩展的首选方法。然而,随着微服务数量的增加,确保通信效率和管理一致性变得尤为重要。本文将探讨API网关在微服务架构中的核心角色,包括其在请求路由、安全性、负载均衡以及聚合功能方面的重要性。我们将通过具体案例分析,展示如何利用API网关优化后端服务,并讨论实施过程中的最佳实践和常见挑战。
|
1月前
|
运维 网络协议 安全
长连接网关技术专题(十):百度基于Go的千万级统一长连接服务架构实践
本文将介绍百度基于golang实现的统一长连接服务,从统一长连接功能实现和性能优化等角度,描述了其在设计、开发和维护过程中面临的问题和挑战,并重点介绍了解决相关问题和挑战的方案和实践经验。
78 1
|
5月前
|
负载均衡 应用服务中间件 API
微服务技术系列教程(25) - SpringCloud- 接口网关服务Zuul
微服务技术系列教程(25) - SpringCloud- 接口网关服务Zuul
58 0