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

 

posted @   昵称已存在嘿  阅读(316)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
欢迎阅读『Ocelot和Consul 实现网关API 服务注册和负载均衡』
欢迎阅读『Ocelot和Consul 实现网关API 服务注册和负载均衡』
点击右上角即可分享
微信分享提示