xiaodu2660 发表于 2021-7-22 15:05

.Net Core之Ocelot+consul+polly 使用

最近学习下.Net Core 记录使用consul进行服务注册,通过ocelot 作为网关,进行服务发现与调用,使用polly 进行限流处理。

1、consult 使用与说明

.net core使用consul步骤如下

1. 到官网下载consul,地址:[官网](https://www.consul.io/downloads)

2. 安装consul与运行consul

3. 新建.net core Webapi项目

4. 下载consul依赖并配置consul

5. 通过consul简单的接口调用

### 运行启动consul

1. 从官网下载下载后解压文件夹,得到consul.exe,我们需要将consul运行起来,输入命令

   consult agent -dev       //-dev 表示默认

2. 启动成功后,在浏览器输入http://127.0.0.1:8500 看到界面代表运行起来了





创建.NetCore WebApi项目

1. 创建好项目名为:ConsulWepApi,然后使用Nuget安装Consul依赖

2. 在appsettings.json 添加consul关联配置文件信息

"ConsulData": {

    "ConsulAddress": "http://127.0.0.1:8500",

    "Datacenter": "dc1",

    "ServiceIP": "127.0.0.1",

    "ServicePort": 5500,

    "ServiceName": "ServiceFirst",

    "ServiceHealthCheck": "api/health",

    "ServiceHttpType": "http"

}

3. 新建项目启动时进行consul注册,这里我们创建一个中间件如下

/// <summary>

    /// 启动Consul

    /// </summary>

    public static class ConsulExtendMildd

    {

      public static void UseConsulExtendMildd(this IApplicationBuilder app, IConfiguration configuration, string contentPath)

      {

            if (app == null) throw new ArgumentNullException(nameof(app));



            try

            {

                string ip = configuration["ip"];                //获取到ip地址

                string port = configuration["port"];    //获取到端口号



                if (ip == null)

                {

                  ip = configuration["ConsulData:ServiceIP"];

                }

                if (port == null)

                {

                  port = configuration["ConsulData:ServicePort"];

                }



                var client = new ConsulClient(x =>

                {

                  x.Address = new Uri(configuration["ConsulData:ConsulAddress"]);

                  x.Datacenter = configuration["ConsulData:Datacenter"];

                });



                var result = client.Agent.ServiceRegister(new AgentServiceRegistration()

                {

                  ID = "ServerNameFirst" + Guid.NewGuid(),      //服务编号保证不重复

                  Name = configuration["ConsulData:ServiceName"],

                  Address = ip,   //服务ip地址

                  Port = int.Parse(port),      //服务端口

                  Check = new AgentServiceCheck   //健康检查

                  {

                        DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),   //服务启动多久后反注册

                        Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔

                        HTTP = $"{configuration["ConsulData:ServiceHttpType"]}://{ip}:{port}/{configuration["ConsulData:ServiceHealthCheck"]}",//健康检查地址

                        Timeout = TimeSpan.FromSeconds(5)   //服务的的注册时间

                  }

                });

            }

            catch (Exception ex)

            {

                Console.WriteLine($"Error Consul Started.\n{ex.Message}");

                throw;

            }

      }

    }

4. 然后在startup.cs 添加consul注册

//配置consul

            app.UseConsulExtendMildd(Configuration, env.ContentRootPath);

```

5. 配置心跳健康检查,新建一个简单webapi

")]

   

    public class HealthController : ControllerBase

    {

      /// <summary>

      /// 健康检查

      /// </summary>

      /// <returns></returns>

      

      public IActionResult Get()

      {

            return Ok();

      }

    }

6. 我们再创建一个测试的webApi接口



    ")]

    public class TestController : ControllerBase

    {

      private readonly ILogger<TestController> _logger;





      public TestController(ILogger<TestController> logger)

      {

            _logger = logger;

      }



      

      public string Get()

      {

            string str = (Request.HttpContext.Connection.LocalIpAddress.MapToIPv4().ToString() + ":" + Request.HttpContext.Connection.LocalPort);

            return str;

      }

    }

7. 打开生成的debug,然后通过命令运行起来,启动两个实例

    dotnet ConsulWepApi.dll --urls="http://*:5726" --ip="127.0.0.1" --port=5726

    dotnet ConsulWepApi.dll --urls="http://*:5727" --ip="127.0.0.1" --port=5727


ocelot 使用

### 操作步骤

1. 创建一个.Net core WebApi 项目

2. 安装Nuget包,Ocelot,Ocelot.Provider.Consul,Ocelot.Provider.Polly

3. 在根目录创建configuration.json

4. 在Program 加载configuration.json

5. 在startup.cs 配置Ocelot,代码如下



public void ConfigureServices(IServiceCollection services)

    {

      services.AddOcelot().AddConsul().AddPolly();

    }



      // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

    {

      app.UseOcelot();

    }

//Program.cs

public static IHostBuilder CreateHostBuilder(string[] args) =>

            Host.CreateDefaultBuilder(args)

               .ConfigureAppConfiguration(c =>

               {

                     c.AddJsonFile("configuration.json", optional: false, reloadOnChange: true);

               })

                .ConfigureWebHostDefaults(webBuilder =>

                {

                  webBuilder.UseStartup<Startup>();

                });

//配置文件

configuration.json

////*****************************单地址/多地址********************************

//{

//"Routes": [

//    {

//      "DownstreamPathTemplate": "/api/{everything}",

//      "DownstreamScheme": "http",

//      "DownstreamHostAndPorts": [

//      {

//          "Host": "localhost",

//          "Port": 5726

//      }

//      ],

//      "UpstreamPathTemplate": "/s5726/{everything}",

//      "UpstreamHttpMethod": [ "Get", "Post" ]

//    },

//    {

//      "DownstreamPathTemplate": "/api/{everything}",

//      "DownstreamScheme": "http",

//      "DownstreamHostAndPorts": [

//      {

//          "Host": "localhost",

//          "Port": 5727

//      }

//      ],

//      "UpstreamPathTemplate": "/s5727/{everything}",

//      "UpstreamHttpMethod": [ "Get", "Post" ]

//    }

//]

//}



////*****************************单地址多实例负载均衡********************************

//{

//"Routes": [

//    {

//      "DownstreamPathTemplate": "/api/{everything}",

//      "DownstreamScheme": "http",

//      "DownstreamHostAndPorts": [

//      {

//          "Host": "localhost",

//          "Port": 5726

//      },

//      {

//          "Host": "localhost",

//          "Port": 5727

//      }

//      ],

//      "UpstreamPathTemplate": "/s5/{everything}",

//      "UpstreamHttpMethod": [ "Get", "Post" ],

//      "LoadBalancerOptions": {

//      "Type": "RoundRobin" //轮询      LeastConnection-最少连接数的服务器   NoLoadBalance不负载均衡

//      }

//    }

//]

//}

////*****************************单地址多实例负载均衡+Consul********************************

//{

//"Routes": [

//    {

//      "DownstreamPathTemplate": "/api/{everything}",

//      "DownstreamScheme": "http",

//      "UpstreamPathTemplate": "/sConsul/{everything}",

//      "UpstreamHttpMethod": [ "Get", "Post" ],

//      "LoadBalancerOptions": {

//      "Type": "RoundRobin" //轮询      LeastConnection-最少连接数的服务器   NoLoadBalance不负载均衡

//      },

//      "ServiceName": "ServiceFirst", //consul服务名称

//      "UseServiceDiscovery": true

//    }

//],

//"GlobalConfiguration": {

//    "ServiceDiscoveryProvider": {

//      "Host": "localhost",

//      "Port": 8500,

//      "Type": "Consul" //由Consul提供服务发现

//    }

//}

//}



//*****************************单地址多实例负载均衡+Consul+Polly********************************

{

"Routes": [

    {

      "DownstreamPathTemplate": "/api/{everything}",

      "DownstreamScheme": "http",

      "UpstreamPathTemplate": "/sConsul/{everything}",

      "UpstreamHttpMethod": [ "Get", "Post" ],

      "LoadBalancerOptions": {

      "Type": "RoundRobin" //轮询      LeastConnection-最少连接数的服务器   NoLoadBalance不负载均衡

      },

      "ServiceName": "ServiceFirst", //consul服务名称

      "UseServiceDiscovery": true,

      //"QoSOptions": {

      //"ExceptionsAllowedBeforeBreaking": 3, //允许多少个异常请求

      //"DurationOfBreak": 10000, // 熔断的时间,单位为ms

      //"TimeoutValue": 10000 //如果下游请求的处理时间超过多少则自如将请求设置为超时 默认90秒

      //},

      //"FileCacheOptions": {

      //"TtlSeconds": 10

      //}, //"缓存"

      "RateLimitOptions": {

      "ClientWhitelist": [], //白名单

      "EnableRateLimiting": true,

      "Period": "5m", //1s, 5m, 1h, 1djeffzhang

      "PeriodTimespan": 5, //多少秒之后客户端可以重试

      "Limit": 5 //统计时间段内允许的最大请求数量

      }

    }

],

"GlobalConfiguration": {

    "ServiceDiscoveryProvider": {

      "Host": "localhost",

      "Port": 8500,

      "Type": "Consul" //由Consul提供服务发现

    },

    "RateLimitOptions": {

      "QuotaExceededMessage": "Too many requests,Please try again ", // 当请求过载被截断时返回的消息

      "HttpStatusCode": 503 // 当请求过载被截断时返回的http status

    }

}

}

----调用-------------

先启动程序,到生成目录下,cmd,启动项目

dotnet OcelotGateway.dll --urls="http://*:6299" --ip="127.0.0.1" --port=6299

//页面调用

浏览器输入:http://127.0.0.1:6299/sConsul/test

这样就用调用5726,5727两个实例返回的数据

帅的惊动党 发表于 2021-7-22 15:26

建议注册时传入lifetime,程序停止时下线注册
实际项目,consoul配置需要持久化到数据库

dummyking 发表于 2021-7-22 19:48

帅的惊动党 发表于 2021-7-22 15:26
建议注册时传入lifetime,程序停止时下线注册
实际项目,consoul配置需要持久化到数据库

请问目前ocelot和kong这俩对比,哪个相对配置更简单?

xiaodu2660 发表于 2021-7-23 17:09

帅的惊动党 发表于 2021-7-22 15:26
建议注册时传入lifetime,程序停止时下线注册
实际项目,consoul配置需要持久化到数据库

好的,谢谢,这个我也是初试用。下次实际使用处理下

xiaodu2660 发表于 2021-7-23 17:11

dummyking 发表于 2021-7-22 19:48
请问目前ocelot和kong这俩对比,哪个相对配置更简单?

这个,我还真的不是很了解,不过在网上看的,kong应该比较好
页: [1]
查看完整版本: .Net Core之Ocelot+consul+polly 使用