zoukankan      html  css  js  c++  java
  • Ocelot和Consul 实现网关API 服务注册和负载均衡

    (以下代码试用vs2019创建,如果是2017请看参考文献)

    Consul 服务发现

    在Ocelot已经支持简单的负载功能,也就是当下游服务存在多个结点的时候,Ocelot能够承担起负载均衡的作用。但是它不提供健康检查,服务的注册也只能通过手动在配置文件里面添加完成。这不够灵活并且在一定程度下会有风险。这个时候我们就可以用Consul来做服务发现,它能与Ocelot完美结合。

    Consul是什么

    Consul是一个服务网格(微服务间的 TCP/IP,负责服务之间的网络调用、限流、熔断和监控)解决方案,它是一个一个分布式的,高度可用的系统,而且开发使用都很简便。它提供了一个功能齐全的控制平面,主要特点是:服务发现、健康检查、键值存储、安全服务通信、多数据中心。

    新建一个api1:nuget 添加一个consul 依赖

    startup 添加代码

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, Microsoft.AspNetCore.Hosting.IApplicationLifetime lifetime)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                //注册项目启动的方法
                lifetime.ApplicationStarted.Register(OnStart);
                //注册项目关闭的方法
                lifetime.ApplicationStarted.Register(OnStopped);
                app.UseRouting();
    
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
            }
            //关闭的时候在consul中移除
            private void OnStopped()
            {
                var client = new ConsulClient();
                //根据ID在consul中移除当前服务
                client.Agent.ServiceDeregister("servicename:93");
            }
            private void OnStart()
            {
                var client = new ConsulClient();
                //健康检查
                var httpCheck = new AgentServiceCheck()
                {
                    //服务出错一分钟后 会自动移除
                    DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1),
                    //每10秒发送一次请求到 下面的这个地址 这个地址就是当前API资源的地址
                    Interval = TimeSpan.FromSeconds(10),
                    HTTP = $"http://localhost:93/HealthCheck"
                };
    
                var agentReg = new AgentServiceRegistration()
                {
                    //这台资源服务的唯一ID
                    ID = "servicename:93",
                    Check = httpCheck,
                    Address = "localhsot",
                    Name = "servicename",
                    Port = 93
                };
                client.Agent.ServiceRegister(agentReg).ConfigureAwait(false);
            }

    添加一个健康检查接口

    新增一个控制器HealthCheck

     [Route("[controller]")]
        [ApiController]
        public class HealthCheckController : ControllerBase
        {
            // GET: api/HealthCheck
            [HttpGet]
            [HttpHead]
            public IActionResult Ping()
            {
                return Ok();
            }
        }

    修改WeatherForecastController

     [ApiController]
        [Route("api/[controller]")]
        public class WeatherForecastController : ControllerBase
        {
            private static readonly string[] Summaries = new[]
            {
                "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
            };
    
            private readonly ILogger<WeatherForecastController> _logger;
    
            public WeatherForecastController(ILogger<WeatherForecastController> logger)
            {
                _logger = logger;
            }
    
            [HttpGet]
            public string Get()
            {
                return "这个api1资源";
            }
        }

    修改启动端口,修改文件launchSettings.json

    {
      "profiles": {
        "API1": {
          "commandName": "Project",
          "launchBrowser": true,
          "launchUrl": "weatherforecast",
          "applicationUrl": "http://localhost:93",
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          }
        }
      }
    }

    然后 copy 一份api1 为api2,,我们启用端口为92 ,代码里面的93换成92(重点!!!)

    添加项目  Api.Gateway(Ocelot网关服务器) 添加Ocelot包   添加Ocelot.Json配置  Ocelot服务器端口为91

    Ocelot.Json

    {
      "ReRoutes": [
        {
          //暴露出去的地址
          "UpstreamPathTemplate": "/api/{controller}",
          "UpstreamHttpMethod": [ "Get" ],
     
          //转发到下面这个地址
          "DownstreamPathTemplate": "/api/{controller}",
          "DownstreamScheme": "http",
          //资源服务器列表
          "DownstreamHostAndPorts": [
            {
              "host": "localhost",
              "port": 92
            },
            {
              "host": "localhost",
              "port": 93
            }
          ],
          //决定负载均衡的算法
          "LoadBalancerOptions": {
            "Type": "LeastConnection"
          },
          "UseServiceDiscovery": true
        }
      ],
      //对外暴露的访问地址  也就是Ocelot所在的服务器地址
      "GlobalConfiguration": {
        "BaseUrl": "http://localhost:91"
      }
    }

    Startup 修改

    public void ConfigureServices(IServiceCollection services)
            {
                services.AddOcelot();
                services.AddControllers();
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                app.UseOcelot().Wait();
                app.UseRouting();
    
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
            }

    Program 修改

    public class Program
       {
           public static void Main(string[] args)
           {
               CreateWebHostBuilder(args).Build().Run();
           }
     
           public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
               WebHost.CreateDefaultBuilder(args)
                         .ConfigureAppConfiguration((hostingContext, builder) =>
                         {
                             builder
                             .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                             .AddJsonFile("Ocelot.json");
                         })
                 .UseUrls("http://+:91")
                 .UseStartup<Startup>();
       }

    启动 api3 和api2再启动Api.Gateway

    执行 http://localhost:91/api/weatherforecast

    再执行

    我们这里负载均衡算法是:LeastConnection

    当然还可以选择其他的:

    • RoundRobin - 轮询,挨着来
    • LeastConnection - 最小连接数,谁的任务最少谁来
    • NoLoadBalance - 不要负载均衡

    如果api1 我们关掉 ,那么就只会请求到api2 ,api1的服务自动断开

     Demo的 github地址:https://github.com/LGXQWER/OcelotAndConsulDemo

    参考文献:https://www.cnblogs.com/liaokui/p/11532115.html

  • 相关阅读:
    C语言数据结构链表
    Servlet中对上传的图片进行大小变换
    网页中有几个框架,在其中一个框架中点击超链接刷新整个页面
    来园子开博了
    学习《java编程思想》导入作者的net.mindview包
    git常用命令汇总
    安装lessloader后,编译项目报错TypeError: this.getOptions is not a function
    数组学习二
    常见文件管理命令
    (转载)Shell语法
  • 原文地址:https://www.cnblogs.com/liguix/p/12943080.html
Copyright © 2011-2022 走看看