Consul在windows中的具体实现
一、什么是Consul?它是用来做什么的?
Consul是google开源的一个使用go语言开发的服务发现、配置管理中心服务。内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等),核心就一句话,服务注册发现,并且用来进行健康检查。
二、Consul代码中是如何实现的?相关代码如下:
1. 提供一个公共的helper类
public static class ConsulHelper { public static void ConsulRegist(this IConfiguration configuration) { ConsulClient client = new ConsulClient(c => { c.Address = new Uri("http://localhost:8500/"); c.Datacenter = "dc1"; }); string ip = configuration["ip"]; int port = int.Parse(configuration["port"]);//命令行参数必须传入 int weight = string.IsNullOrWhiteSpace(configuration["weight"]) ? 1 : int.Parse(configuration["weight"]); client.Agent.ServiceRegister(new AgentServiceRegistration() { ID = "service" + Guid.NewGuid(),//唯一的---奥尼尔 Name = "wjService",//组名称-Group 湖人 Address = ip,//其实应该写ip地址 Port = port,//不同实例 Tags = new string[] { weight.ToString() },//标签 Check = new AgentServiceCheck() { Interval = TimeSpan.FromSeconds(12),//间隔12s一次 HTTP = $"http://{ip}:{port}/Api/Health/Index", Timeout = TimeSpan.FromSeconds(5),//检测等待时间 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(20)//失败后多久移除 } }); //命令行参数获取 Console.WriteLine($"{ip}:{port}--weight:{weight}"); } }
2. 在configure中进行注册:
//启动时注册,且只注册一次 this.Configuration.ConsulRegist();
三、是如何进行健康检查的呢?
第一步:服务控制器中提供一个公共的接口:
[Route("api/[controller]")] [ApiController] public class HealthController : ControllerBase { private IConfiguration _iConfiguration; public HealthController(IConfiguration configuration) { this._iConfiguration = configuration; } [HttpGet] [Route("Index")] public IActionResult Index() { Console.WriteLine($"This is HealthController {this._iConfiguration["port"]} Invoke"); return Ok();//只是个200 省事儿 } }
第二步:在上面的helper中定义检查的方法地址:
Check = new AgentServiceCheck() { Interval = TimeSpan.FromSeconds(12),//间隔12s一次 HTTP = $"http://{ip}:{port}/Api/Health/Index", Timeout = TimeSpan.FromSeconds(5),//检测等待时间 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(20)//失败后多久移除 }
四、启动consul:找到存放consul的地址启动如下
consul.exe agent -dev
五、web层中掉用consul中的对象代码如下:
#region Consul url = "http://ZhaoxiService/api/users/all";//客户端得知道调用啥服务,啥名字---consul就是个DNS ConsulClient client = new ConsulClient(c => { c.Address = new Uri("http://localhost:8500/"); c.Datacenter = "dc1"; }); var response = client.Agent.Services().Result.Response; //foreach (var item in response) //{ // Console.WriteLine("***************************************"); // Console.WriteLine(item.Key); // var service = item.Value; // Console.WriteLine($"{service.Address}--{service.Port}--{service.Service}"); // Console.WriteLine("***************************************"); //} Uri uri = new Uri(url); string groupName = uri.Host; AgentService agentService = null; var serviceDictionary = response.Where(s => s.Value.Service.Equals(groupName, StringComparison.OrdinalIgnoreCase)).ToArray();//找到的全部服务 //{ // agentService = serviceDictionary[0].Value;//直接拿的第一个 // //这里有三个服务或者服务实例,只需要选择一个调用,那么这个选择的方案,就叫 负载均衡策略 //} //{ // //轮询策略 也是平均,但是太僵硬了 // agentService = serviceDictionary[iIndex++ % 3].Value; //} //{ // //平均策略--随机获取索引--相对就平均 // agentService = serviceDictionary[new Random(iIndex++).Next(0, serviceDictionary.Length)].Value; //} { //权重策略--能给不同的实例分配不同的压力---注册时提供权重 List<KeyValuePair<string, AgentService>> pairsList = new List<KeyValuePair<string, AgentService>>(); foreach (var pair in serviceDictionary) { int count = int.Parse(pair.Value.Tags?[0]);//1 5 10 for (int i = 0; i < count; i++) { pairsList.Add(pair); } } //16个 agentService = pairsList.ToArray()[new Random(iIndex++).Next(0, pairsList.Count())].Value; } url = $"{uri.Scheme}://{agentService.Address}:{agentService.Port}{uri.PathAndQuery}"; #endregion string content = InvokeApi(url); base.ViewBag.Users = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<User>>(content);
以上就是consul的大致用法,谢谢学习!!!