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

目录
相关文章
|
5天前
|
API
阿里云微服务引擎及 API 网关 2024 年 2 月产品动态
阿里云微服务引擎及 API 网关 2024 年 2 月产品动态
|
1月前
|
缓存 安全 API
【亿级数据专题】「高并发架构」盘点本年度探索对外服务的百万请求量的API网关设计实现
公司对外开放的OpenAPI-Server服务,作为核心内部系统与外部系统之间的重要通讯枢纽,每天处理数百万次的API调用、亿级别的消息推送以及TB/PB级别的数据同步。经过多年流量的持续增长,该服务体系依然稳固可靠,展现出强大的负载能力。
35 9
【亿级数据专题】「高并发架构」盘点本年度探索对外服务的百万请求量的API网关设计实现
|
17天前
|
监控 持续交付 开发者
深入探讨后端服务的微服务架构设计与实践
【2月更文挑战第10天】随着互联网应用的不断发展,微服务架构作为一种灵活、高效的解决方案在后端服务开发中备受关注。本文将深入探讨微服务架构设计与实践,从服务拆分、通信机制到部署管理等方面进行详细剖析,旨在帮助开发者更好地理解和运用微服务架构。
15 2
|
2天前
|
监控 负载均衡 API
深入理解微服务架构下的API网关
【2月更文挑战第26天】在现代后端开发中,微服务架构已经成为一种主流的系统设计方式。本文将重点探讨微服务架构中的关键组件——API网关。我们将分析API网关的核心功能,包括请求路由、负载均衡、认证授权、监控和日志记录等。此外,文章还将讨论如何在实际项目中设计和实现一个高效、可扩展的API网关,以及它对微服务治理的重要性。通过本文,读者将获得对API网关在微服务架构中的重要作用和应用策略的深刻理解。
|
4天前
|
Windows
windows server 2019 安装NET Framework 3.5失败,提示:“安装一个或多个角色、角色服务或功能失败” 解决方案
windows server 2019 安装NET Framework 3.5失败,提示:“安装一个或多个角色、角色服务或功能失败” 解决方案
|
5天前
|
运维 Cloud Native 应用服务中间件
阿里云微服务引擎 MSE 及 API 网关 2024 年 02 月产品动态
阿里云微服务引擎 MSE 面向业界主流开源微服务项目, 提供注册配置中心和分布式协调(原生支持 Nacos/ZooKeeper/Eureka )、云原生网关(原生支持Higress/Nginx/Envoy,遵循Ingress标准)、微服务治理(原生支持 Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服务治理规范)能力。API 网关 (API Gateway),提供 APl 托管服务,覆盖设计、开发、测试、发布、售卖、运维监测、安全管控、下线等 API 生命周期阶段。帮助您快速构建以 API 为核心的系统架构.满足新技术引入、系统集成、业务中台等诸多场景需要。
|
6天前
|
缓存 监控 负载均衡
构建微服务架构下的API网关实践指南
【2月更文挑战第22天】在现代的软件开发实践中,微服务架构因其灵活性和可扩展性而成为众多企业的首选。随着服务数量的增长,有效地管理这些服务的入口——API网关,成为了确保系统稳定性和效率的关键。本文将探讨如何在微服务环境中构建一个高性能、可扩展的API网关,以及它如何帮助实现请求路由、负载均衡、认证授权和监控等功能,同时提供了一系列实施的最佳实践和面临的挑战解决方案。
|
7天前
|
监控 测试技术 API
构建基于微服务架构的高效API网关
【2月更文挑战第20天】 在现代软件架构中,微服务已成为企业开发云原生应用的首选模式。随着服务数量的增长,有效的服务管理和请求路由变得至关重要。本文将探讨如何构建一个高效的API网关来管理微服务架构中的服务交互,重点讨论其设计原则、关键组件以及实现方法。通过引入API网关,我们旨在简化客户端与服务的通信,提供统一的访问入口,增强安全性,并提升系统的可扩展性和维护性。
|
11天前
|
开发框架 中间件 .NET
C# .NET面试系列七:ASP.NET Core
## 第一部分:ASP.NET Core #### 1. 如何在 controller 中注入 service? 在.NET中,在ASP.NET Core应用程序中的Controller中注入服务通常使用<u>依赖注入(Dependency Injection)</u>来实现。以下是一些步骤,说明如何在Controller中注入服务: 1、创建服务 首先,确保你已经在应用程序中注册了服务。这通常在Startup.cs文件的ConfigureServices方法中完成。例如: ```c# services.AddScoped<IMyService, MyService>(); //
46 0
|
11天前
|
缓存 网络协议 微服务
微服务架构下服务注册的几种方式
【2月更文挑战第15天】微服务架构下服务注册的几种方式
22 1

相关产品

  • 微服务引擎
  • 服务网格