上一节课我们在Windows平台下安装了Contul,这一节课我们说一下如何在.Net Core平台下实现基于Consul的服务注册与服务发现。
一、首先,新建两个WebApi项目,分别是Sercice1和Service2,设置两个webapi的访问端口分别是7000和8000。
二、分别在两个项目的Nuget包管理器里面安装Consul包
三、修改返回不同的值以便进行区分
namespace Service1.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public string Get()
{
return "Service1";
}
}
}
四、新建一个API控制器HealthController,用于Consul进行健康检查。
namespace Service1.Controllers
{
[Route("api/[controller]")]
public class HealthController : Controller
{
[HttpGet("/healthCheck")]
public IActionResult Check() => Ok("ok");
}
}
五、新建两个类
ConsulBuilderExtensions.cs用于服务注册
ConsulOption.cs用于配置服务注册相关的参数
代码如下:
1、ConsulBuilderExtensions.cs
namespace Service1.Consul
{
public static class ConsulBuilderExtensions
{
public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IApplicationLifetime lifetime, ConsulOption consulOption)
{
var consulClient = new ConsulClient(x =>
{
// consul 服务地址
x.Address = new Uri(consulOption.Address);
});
var registration = new AgentServiceRegistration()
{
ID = Guid.NewGuid().ToString(),
Name = consulOption.ServiceName,// 服务名
Address = consulOption.ServiceIP, // 服务绑定IP
Port = consulOption.ServicePort, // 服务绑定端口
Check = new AgentServiceCheck()
{
//服务启动多久后注册
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔
HTTP = consulOption.ServiceHealthCheck,//健康检查地址
Timeout = TimeSpan.FromSeconds(5)
}
};
// 服务注册
consulClient.Agent.ServiceRegister(registration).Wait();
// 应用程序终止时,服务取消注册
lifetime.ApplicationStopping.Register(() =>
{
consulClient.Agent.ServiceDeregister(registration.ID).Wait();
});
return app;
}
}
}
2、ConsulOption.cs
namespace Service1.Consul
{
/// <summary>
/// Consul 注册发现相关参数
/// </summary>
public class ConsulOption
{
/// <summary>
/// 服务名称
/// </summary>
public string ServiceName { get; set; }
/// <summary>
/// 服务IP
/// </summary>
public string ServiceIP { get; set; }
/// <summary>
/// 服务端口
/// </summary>
public int ServicePort { get; set; }
/// <summary>
/// 服务健康检查地址
/// </summary>
public string ServiceHealthCheck { get; set; }
/// <summary>
/// Consul 地址
/// </summary>
public string Address { get; set; }
}
}
六、在appsettings.json配置文件里添加服务注册相关参数,ConsulAddress是访问Consul的地址。
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"ServiceName": "Service1",
"ServiceIP": "localhost",
"ServicePort": 7000,
"ServiceHealthCheck": "http://localhost:7000/healthCheck",
"ConsulAddress": "http://localhost:8500"
}
七、最后,在Startup.cs的Configure方法里对Consul进行注册。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
var consulOption = new ConsulOption
{
ServiceName = Configuration["ServiceName"],
ServiceIP = Configuration["ServiceIP"],
ServicePort = Convert.ToInt32(Configuration["ServicePort"]),
ServiceHealthCheck = Configuration["ServiceHealthCheck"],
Address = Configuration["ConsulAddress"]
};
app.RegisterConsul(lifetime, consulOption);
}
Sercice1和Service2都按照上面说的分别做修改,这样的话,用于服务注册的两个项目就完成了,运行以后就可以在Consul控制台里面看到。
下面,我们新建一个WebApi项目ConsulDemo,通过Consul进行服务发现,访问已经注册的服务。
添加下面的代码,首先取出所有注册的服务列表,然后随机选出其中一台服务。
namespace ConsulDemo.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly IConfiguration _configuration;
public ValuesController(IConfiguration configuration)
{
_configuration = configuration;
}
// GET api/values
[HttpGet]
public async Task<string> Get()
{
var url = _configuration["ConsulAddress"].ToString();
using (var consulClient = new ConsulClient(a => a.Address = new Uri(url)))
{
//取出全部的MsgService服务
var services = consulClient.Agent.Services().Result.Response;
if(services.Count>0)
{
//客户端负载均衡,随机选出一台服务
Random rand = new Random();
var index = rand.Next(services.Count());
var s = services.ElementAt(index);
using (HttpClient client = new HttpClient())
{
var response = await client.GetAsync($"http://{s.Value.Address}:{s.Value.Port}/api/values");
var result = await response.Content.ReadAsStringAsync();
return result;
}
}
else
{
return "未发现服务";
}
}
}
}
}
然后修改appsettings.json配置文件,添加Consul访问服务地址
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"ConsulAddress": "http://localhost:8500"
}
这样,一个简单的基于Consul的服务注册和服务发现示例就完成了
首先修改启动项同时启动两个服务项目
然后单独运行ConsulDemo项目
就会通过Consul服务发现随机打开已经注册的两个服务中的一个。