c#:Ocelot集成Consul初体验

环境:

  • window10 x64
  • vs2019 企业版 16.7.4
  • asp.net core 3.1
  • consul_1.8.4_windows_amd64.zip
  • Consul 1.6.1.1
  • Ocelot.Provider.Consul 16.0.1

关于Consul和Ocelot:
Consul参照:c#:Consul初步体验
Ocelot参照:c#:Ocelot初体验

实验代码下载:https://download.csdn.net/download/u010476739/13008990

一、实验概述和架构图

Consul是用来做服务注册和发现的,我们写的WebApi项目运行起来后需要向Consul注册服务名称和访问地址。

Ocelot是用来做网关的,所有客户端的请求都应该发送到Ocelot,然后由Ocelot内部转发(非http重定向)到具体的WebApi项目。

Ocelot集成Consul后,我们开发的项目就只管向Consul注册服务,而浏览器只管向Ocelot发送请求,Ocelot会自动向Consul查询请求的服务地址,然后将请求内部转发到具体的WebApi服务上。

下面是本地实现的架构图:
在这里插入图片描述

二、准备WebApi项目并向Consul注册

2.1 启动Consul

在这里插入图片描述
启动后,浏览器观察:http://localhost:8500/
在这里插入图片描述

2.2 准备WebApi项目

我们先新建空白解决方案ocelot-consul-trial,然后新建两个WebApi项目:ocelot-consul-trialOrderApi

ocelot-consul-trialocelot网关项目,负责接收客户端请求。
OrderApi是正常的WebApi项目,启动时向Consul注册。这个项目编译后,使用命令行参数指定端口启动两个实例。

新建后如下:
在这里插入图片描述
操作OrderApi项目

引入Consul包:

<ItemGroup>
    <PackageReference Include="Consul" Version="1.6.1.1" />
  </ItemGroup>

修改Startup.cs代码,加入向Consul注册的代码:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });

     #region 向Consul注册服务
     //获取命令行指定的参数( --urls="http://localhost:5001/")
     var urls = Configuration["urls"];
     var client = new ConsulClient(_ => _.Address = new Uri("http://localhost:8500"));
     var httpCheck = new AgentServiceCheck()
     {
         DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册
         Interval = TimeSpan.FromSeconds(10),//间隔固定的时间访问一次
         HTTP = $"{urls}/api/Health",//
         Timeout = TimeSpan.FromSeconds(5)
     };

     var port = int.Parse(urls.Split(":")[2].Trim('/'));
     AgentServiceRegistration registration = new AgentServiceRegistration()
     {
         Checks = new[] { httpCheck },
         ID = Guid.NewGuid().ToString(),
         Name = "OrderApi",
         Address = "localhost",//注意:这里不要写成 http://localhost形式
         Port = port
     };
     client.Agent.ServiceRegister(registration).Wait();
     #endregion
}

添加健康检查控制器HealthController.cs

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace OrderApi.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class HealthController : ControllerBase
    {
        [HttpGet]
        public string Get() => "ok";
    }
}

添加测试api接口DemoController.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace OrderApi.Controllers
{
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class DemoController : ControllerBase
    {
        private readonly IConfiguration configuration;

        public DemoController(IConfiguration configuration)
        {
            this.configuration = configuration;
        }
        public string GetHello() => "来自: " + configuration["urls"] + "的应答";
    }
}

编译OrderApi项目,并用如下命令启动两个实例:

.\OrderApi.exe --urls="http://localhost:5001"
.\OrderApi.exe --urls="http://localhost:5002"

此时观察Consul管理页面:
在这里插入图片描述
在这里插入图片描述

三、准备网关项目

操作 ocelot-consul-trial项目:

引入Ocelot.Provider.Consul包:

  <ItemGroup>
    <PackageReference Include="Ocelot.Provider.Consul" Version="16.0.1" />
  </ItemGroup>

添加ocelot.json的配置文件:

{
  "Routes": [
    {
      //GeteWay转发=>Downstream
      "DownstreamPathTemplate": "/{url}", //服务地址--url变量
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/order/{url}", //网关地址--url变量 冲突的还可以加权重Priority
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "UseServiceDiscovery": true, //使用服务发现
      "ServiceName": "OrderApi", //Consul服务名称
      "LoadBalancerOptions": {
        "Type": "RoundRobin" //轮询  //"LeastConnection":最少连接数服务器   "NoloadBalance":不负载均衡     "CookieStickySession":会话粘滞
      }
    }
  ],
  "GlobalConfiguration": {
    "ServiceDiscoveryProvider": {
      "Host": "127.0.0.1",
      "Port": 8500,
      "Type": "Consul" //由Consul提供服务发现,每次请求去Consul
    }
  }
}

修改Program.cs文件载入ocelot.json配置文件:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace ocelot_consul_trial
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration(conf =>
                {
                    conf.AddJsonFile("ocelot.json", true, true);
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

修改Startup.cs文件,启用 Ocelot并去掉其他的功能:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Provider.Consul;

namespace ocelot_consul_trial
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOcelot().AddConsul();
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseHttpsRedirection();
            app.UseOcelot().Wait();
        }
    }
}

编译ocelot-consul-trial项目并用如下命令启动:

.\ocelot-consul-trial.exe --urls="https://localhost:5000/" 

四、测试整体效果

在浏览器中输入:https://localhost:5000/order/api/demo/gethello,效果如下:
在这里插入图片描述
刷新网页,显示如下:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackletter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值