Asp.Net Core使用Ocelot结合Consul实现服务注册和发现

目录
  • 1.服务注册与发现(Service Discovery)
  • 2.Consul
  • 3.Asp.Net Core向Consul注册服务实例
  • 4.项目演示
    • 4.1APIGateway项目
    • 4.2Common项目
    • 4.3APIServiceA项目
    • 4.4APIServiceB项目
    • 4.5项目运行

1.服务注册与发现(Service Discovery)

  • 服务注册:我们通过在每个服务实例写入注册代码,实例在启动的时候会先去注册中心(例如Consul、ZooKeeper、etcd、Eureka)注册一下,那么客户端通过注册中心可以知道每个服务实例的地址,端口号,健康状态等等信息,也可以通过注册中心删除服务实例。这里注册中心相当于是负责维护服务实例的管控中心。
  • 服务发现:服务实例在注册中心注册之后,客户端通过注册中心可以了解这些服务实例运行状况。

2.Consul

如果要实现服务注册与发现,需要一个注册中心,这里主要介绍是Consul。

Consul官网:https://www.consul.io/,它主要功能有:服务注册与发现、健康检查、Key/Value、多数据中心。

如果在Windows上部署Consul,在consul.exe目录下执行consul.exe agent -dev命令行即可。

3.Asp.Net Core向Consul注册服务实例

Asp.Net Core向Consul注册服务实例调用过程如下图所示:

Asp.Net Core向Consul注册服务实例需要在Gateway项目中引用Consul支持的NuGet软件包,安装命令如下:

Install-Package Ocelot.Provider.Consul

然后将以下内容添加到您的ConfigureServices方法中:

services.AddOcelot().AddConsul();

在Ocelot服务发现项目示例中,通过APIGateway项目GlobalConfiguration选项可以配置服务注册与发现,文件配置具体代码如下:

{
  "Routes": [
    {
      "UseServiceDiscovery": true,
      "DownstreamPathTemplate": "/{url}",
      "DownstreamScheme": "http",
      "ServiceName": "MyService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "UpstreamPathTemplate": "/{url}",
      "UpstreamHttpMethod": [ "Get" ],
      "ReRoutesCaseSensitive": false
    }
  ],
  "GlobalConfiguration": {
    //服务发现配置
    "ServiceDiscoveryProvider": {
      //注册中心Consul地址
      "Host": "192.168.113.128",
      //注册中心Consul端口号
      "Port": 8500,
      "Type": "Consul",
      //以毫秒为单位,告诉Ocelot多久调用一次Consul来更改服务配置。
      "PollingInterval": 100,
      //如果你有在Consul上配置key/value,则在这里输入配置key。
      "ConfigurationKey": "MyService_AB"
    }
  }
}

ServiceDiscoveryProvider选项说明:

  • Host:注册中心Consul地址。
  • Port:注册中心Consul端口号。
  • Type:注册中心类型。
  • PollingInterval:以毫秒为单位,告诉Ocelot多久调用一次Consul来更改服务配置。
  • ConfigurationKey:如果你有在Consul上配置key/value,则在这里输入配置key。

4.项目演示

4.1APIGateway项目

ConfigureServices添加Ocelot、Consul注入:

services.AddOcelot().AddConsul();

Configure添加使用Ocelot:

app.UseOcelot().Wait();

服务发现配置如Ocelot服务发现项目示例一样。

4.2Common项目

先安装Consul的NuGet软件包,安装命令如下:

Install-Package Consul

在该项目添加一个AppExtensions扩展类,用来对服务APIServiceA、APIServiceB项目在Consul注册实例,为了展示效果,具体代码稍作修改如下:

public static class AppExtensions
{
    public static IServiceCollection AddConsulConfig(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddSingleton<IConsulClient, ConsulClient>(p => new ConsulClient(consulConfig =>
        {
            var address = configuration.GetValue<string>("Consul:Host");
            consulConfig.Address = new Uri(address);
        }));
        return services;
    }
    public static IApplicationBuilder UseConsul(this IApplicationBuilder app, string host = null, string port = null)
    {
        //获取consul客户端实例
        var consulClient = app.ApplicationServices.GetRequiredService<IConsulClient>();
        var logger = app.ApplicationServices.GetRequiredService<ILoggerFactory>().CreateLogger("AppExtensions");
        var lifetime = app.ApplicationServices.GetRequiredService<IApplicationLifetime>();

        if (!(app.Properties["server.Features"] is FeatureCollection features)) return app;

        //var addresses = features.Get<IServerAddressesFeature>();
        //var address = addresses.Addresses.FirstOrDefault();
        //if (address == null)
        //{
        //    return app;
        //}

        var address = host + ":" + port;
        if (string.IsNullOrWhiteSpace(host) || string.IsNullOrWhiteSpace(port))
        {
            Console.WriteLine($"host或者port为空!");
            return app;
        }

        Console.WriteLine($"address={address}");
        var uri = new Uri(address);
        Console.WriteLine($"host={uri.Host},port={uri.Port}");

        var registration = new AgentServiceRegistration()
        {
            ID = $"MyService-{uri.Port}",
            Name = "MyService",
            Address = $"{uri.Host}",
            Port = uri.Port,
            Check = new AgentServiceCheck()
            {
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册
                Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔
                HTTP = $"{address}/HealthCheck",//健康检查地址
                Timeout = TimeSpan.FromSeconds(5)//超时时间
            }
        };
        logger.LogInformation("Registering with Consul");
        logger.LogInformation($"Consul RegistrationID:{registration.ID}");
        //注销
        consulClient.Agent.ServiceDeregister(registration.ID).ConfigureAwait(true);
        //注册
        consulClient.Agent.ServiceRegister(registration).ConfigureAwait(true);
        //应用程序关闭时候
        lifetime.ApplicationStopping.Register(() =>
        {
            //正在注销
            logger.LogInformation("Unregistering from Consul");
            consulClient.Agent.ServiceDeregister(registration.ID).ConfigureAwait(true);
        });
        //每个服务都需要提供一个用于健康检查的接口,该接口不具备业务功能。服务注册时把这个接口的地址也告诉注册中心,注册中心会定时调用这个接口来检测服务是否正常,如果不正常,则将它移除,这样就保证了服务的可用性。
        app.Map("/HealthCheck", s =>
        {
            s.Run(async context =>
            {
                await context.Response.WriteAsync("ok");
            });
        });
        return app;
    }
}

4.3APIServiceA项目

项目添加一个Get方法,对应APIGateway项目的路由上下游配置,具体代码如下:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        var port = Request.Host.Port;
        return new string[] { "value1", "value2", port.Value.ToString() };
    }
}

appsettings.json配置加入Consul地址:

"Consul": {
  "Host": "http://192.168.113.128:8500"
}

4.4APIServiceB项目

项目添加一个Get方法,对应APIGateway项目的路由上下游配置,具体代码如下:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        var port = Request.Host.Port;
        return new string[] { "value3", "value4", port.Value.ToString() };
    }
}

appsettings.json配置加入Consul地址:

"Consul": {
  "Host": "http://192.168.113.128:8500"
}

4.5项目运行

在APIServiceA、APIServiceB项目的ConfigureServices添加Consul配置:

services.AddConsulConfig(Configuration);

在Configure添加Consul服务注册:

APIServiceA:app.UseConsul("http://172.168.18.73", "9999");
APIServiceB:app.UseConsul("http://172.168.18.73", "9998");

把APIGateway、APIServiceA、APIServiceB三个项目部署到IIS上:

三个项目运行起来后,通过浏览器Consul客户端可以看到MyService节点服务情况:

点击打开MyService节点可以看到注册到Consul的APIServiceA、APIServiceB服务状况:

如果把APIServiceB服务实例站点停掉:

通过Consul客户端会看到APIServiceB服务实例已经被剔除了:

如果输入CTRL+C把集群中某一个Consul服务关闭,那么集群会重新选举一个新的leader,负责处理所有服务实例的查询和事务:

到此这篇关于Asp.Net Core使用Ocelot结合Consul实现服务注册和发现的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • ASP.NET Core为Ocelot网关配置Swagger

    1.前言 前端与后端的联系更多是通过API接口对接,API文档变成了前后端开发人员联系的纽带,开始变得越来越重要,而Swagger就是一款让你更好的书写规范API文档的框架.在Ocelot Swagger项目示例中,通过APIGateway项目路由配置网关.上下游服务Swagger.对解决方案中的示例APIServiceA.APIServiceB项目Get方法进行配置,文件配置具体代码如下: { "Routes": [ { //下游服务地址 "DownstreamPathTe

  • ASP.NET Core中的Ocelot网关介绍

    目录 1.简介 2.Ocelot配置 2.1基础集成(Basic Implementation) 2.2集成IdentityServer(With IdentityServer) 2.3多个网关实例集群(Multiple Instances) 2.4集成Consul服务发现(With Consul) 2.5集成Service Fabric(With Service Fabric) 3.总结 1.简介 Ocelot原本设计仅为与.NET Core一起使用的,它是一个.NET API网关,作为面向使

  • ASP.NET Core3.1 Ocelot负载均衡的实现

    1.负载均衡 Ocelot可以在每个路由的可用下游服务中实现负载均衡,这使我们更有效地选择下游服务来处理请求.负载均衡类型: LeastConnection:根据服务正在处理请求量的情况来决定哪个服务来处理新请求,即将新请求发送到具有最少现有请求的服务去处理.算法状态没有分布在Ocelot集群中. RoundRobin:遍历可用服务并发送请求.算法状态没有分布在Ocelot集群中. NoLoadBalancer:从配置或服务发现中获取第一个可用服务来处理新请求. CookieStickySess

  • ASP.NET Core设置Ocelot网关限流

    1.限流(Rate Limiting) 很多时候为了防止DoS攻击,我们会通过限流方式对上游请求进行限制,以保护下游服务不会负荷过载,为客户端提供高质量的资源服务.在Ocelot限流项目示例中,通过APIGateway项目路由RateLimitOptions选项可以配置限流.对解决方案的示例APIServices项目Get方法进行限流,文件配置具体代码如下: { "Routes": [ { "DownstreamPathTemplate": "/api/v

  • .Net Core微服务网关Ocelot超时、熔断、限流

    基本概念 超时.熔断.限流听起来好像很远,但实际上用在方方面面.很多人可能还搞不懂熔断是做什么,其实可以把熔断理解为一种防护措施.做个假设,在微服务体系下,某个下游服务响应很慢,然后随着时间推移,会有越来越多的请求堆积,从而会导致各种严重后果,单说连接池大量被占用就很要命.更不用说服务之间还要相互调用,你等我10秒,我等你5秒,不仅毫无体验感,高可用也就成了空谈.不如换个思路:与其等10秒返回一个请求失败,不如马上就返回请求失败.这样一来,请求堆不起来,资源也有时间释放或者恢复.这个动作就叫熔断

  • ASP.NET Core3.1 Ocelot路由的实现

    1.路由 前一个章节我们已经介绍过Ocelot,相信大家也了解到,Ocelot的主要功能是接收客户端等传入的HTTP请求,并将其转发到下游服务.Ocelot当前仅以另一个http请求的形式支持此功能(将来可能是任何传输机制). Ocelot将一个请求路由到另一个请求.为了让Ocelot正常工作,您需要在配置中设置一个Route.下面我们就Ocelot基础项目构建简单介绍下路由功能. 2.Ocelot基础项目构建(APIGatewayBasicDemo) 现在我们根据GitHub贡献者开源项目来学

  • .Net Core微服务网关Ocelot集成Consul

    有consul基础的都知道,consul可以发现新增的服务,剔除掉无效的服务,赋予应用自动伸缩的能力.而ocelot如果集成了consul,那ocelot也能拥有这些能力,还可以自主选择负载均衡策略,灵活性更强. (建议看完前一篇文章再来实践这一篇,不然可能有难度) 上干货. 首先打开上一篇新建好的项目,继续添加nuget包: 然后注册相关服务: public void ConfigureServices(IServiceCollection services) { services.AddOc

  • ASP.NET Core Api网关Ocelot的使用初探

    概述 Ocelot面向使用.NET运行微型服务/面向服务的体系结构的人员,这些体系结构需要在系统中具有统一的入口点.特别是我想与IdentityServer参考和承载令牌轻松集成.Ocelot是按特定顺序排列的一堆中间件.Ocelot将HttpRequest对象操作到由其配置指定的状态,直到到达请求构建器中间件,在该中间件中它创建一个HttpRequestMessage对象,该对象用于向下游服务发出请求.发出请求的中间件是Ocelot管道中的最后一件事.它不会调用下一个中间件.有一块中间件可将H

  • ASP.NET Core3.1 Ocelot认证的实现

    1.认证 当客户端通过Ocelot访问下游服务的时候,为了保护下游资源服务器会进行认证鉴权,这时候需要在Ocelot添加认证服务.添加认证服务后,随后Ocelot会基于授权密钥授权每个请求可以访问的资源.用户必须像往常一样在其Startup.cs中注册身份验证服务,但是他们为每次注册提供一个方案(身份验证提供者密钥),例如: public void ConfigureServices(IServiceCollection services) { var authenticationProvide

  • .Net Core微服务网关Ocelot基础介绍及集成

    网关是什么 简单来说,网关就是暴露给外部的请求入口.就和门卫一样,外面的人想要进来,必须要经过门卫.当然,网关并不一定是必须的,后端服务通过http也可以很好的向客户端提供服务.但是对于业务复杂.规模庞大的项目来说,使用网关有很多无法舍弃的好处,比如可以进行统一的请求聚合来节省流量.降低耦合度,可以赋予项目熔断限流的能力提高可用性等等. ocelot是什么 ocelot是.net core实现的开源的api网关项目,开源地址:https://github.com/ThreeMammals/Oce

随机推荐