Consul使用方法与作用

Consul作用;

1.服务注册发现

2.服务健康检查

3.负载均衡

 

使用步骤:

1.下载并解压(得到一个exe文件)

2.在解压目录,cmd,使用命令 Consul.exe  agent  -dev

这样便启动了Consul服务,打开浏览器输入localhost:8500    (默认端口8500)

 

那么,怎么注册发现服务呢。需要在要调用的服务里面注册Consul的地址,并告知Consul自己的ip,端口号,服务名等(需要支持命令行参数)

代码如下:

public static void ConsulRegister(this IConfiguration configuration)
        {
            ConsulClient client = new ConsulClient(c =>
              {
                  c.Address = new Uri("http://localhost:8500/");
                  c.Datacenter = "dcl";
              });

            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 = "AduService",
                Address = 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}");
        }

这些参数都是可以自定义的,要引用包Consul,

Consul地址也不一定要8500,

有一点需要注意,必须添加HealthController!写什么都好,不然Consul检查不到这些服务(困扰了我几天,噗)

代码加上

 

private readonly ILogger<HealthController> _logger;
        private readonly IConfiguration _configuration;
        public HealthController(ILogger<HealthController> logger, IConfiguration configuration)
        {
            _logger = logger;
            _configuration = configuration;
        }
        [HttpGet]
        [Route("Index")]
        public IActionResult Index()
        {
            _logger.LogWarning($"This is HealthController {_configuration["port"]}");
            return Ok();
        }

 

 

 

 

注意,需要在服务的StartUp.cs中的Configure方法中注册:

#region 注册Consul
            this.Configuration.ConsulRegister();   //启动时注册,且只注册一次
            #endregion

 在主项目中调用:

string url = "http://AduService/api/user/all";

            ConsulClient client = new ConsulClient(c =>
            {
                c.Address = new Uri("http://localhost:8500/");
                c.Datacenter = "dcl";
            });

var response = client.Agent.Services().Result.Response;

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; url = $"{uri.Scheme}://{agentService.Address}:{agentService.Port}{uri.PathAndQuery}";

通过向Consul的服务地址发送请求,遍历服务,找到和AduService同名的服务下面的实例,获取url,然后获取数据

 

上述代码是默认请求第一个服务实例。这显然不够,我想要动态改变请求实例,并按照权重的形式来访问》

需要将上面的

agentService = serviceDictionary[0].Value;

 修改一下:

//权重,不同服务器的处理能力不同
                List<KeyValuePair<string,AgentService >> pairsList = new List<KeyValuePair<string,AgentService>>();
                foreach(var pair in serviceDictionary)
                {
                    int count = int.Parse(pair.Value.Tags?[0]);
                    for(int i = 0; i < count; i++)
                    {
                        pairsList.Add(pair);
                    }
                }
                agentService = pairsList.ToArray()[new Random(iIndex++).Next(0, pairsList.Count())].Value;

其中iIndex是声明的全局变量:

private static int iIndex = 0;

 

posted @ 2020-11-18 23:23  RookieCoderAdu  阅读(1381)  评论(0编辑  收藏  举报