zoukankan      html  css  js  c++  java
  • 五分钟了解Consul

      Hi,大家好,我叫consul,翻译成中文叫做“领事”,其实我更喜欢叫自己为中介,因为我觉得自己做的事情和房产中介非常像。比如说想要卖房的房东到我这边登记,我将房屋信息登录到我的表格中(服务注册),有买家来咨询时,我再查询表格将符合条件的房子返回给买家(服务发现),平时我也要做点房源的维护工作,比如每隔一天就打电话问下房东:“你的房子还卖么?(服务健康检查)”。

      我的诞生也和现在互联网项目的开发模式有关,从之前的三层架构衍化成现在有微服务架构,把原来BLL和DAL层做事按业务拆成独立的分布式服务(其实很多人就是把CURD放到单独的服务中而已),为了高可用&高扩展,又把这些服务(进程)集群化,就出现一堆的地址和端口。客户端由原来的进程内调用变成跨进程或跨网络调用服务,把这些一堆地址和端口放到配置文件中。这样做其实没什么问题,但维护起来比较麻烦,比如说增加一个服务,就要修改配置文件并重启客户端,同理,删掉一个服务也要同样的操作。

      我的作用主要是管理这些集群服务的配置,整体流程是这样子的:服务(进程)启动的时候把服务名和自己的IP、端口通过HTTP告诉我,我将这些信息记到自己的内存表格中,客户端调用时带上要查询的服务名通过HTTP发送给我,我再自己的内存表中找到叫这服务名的所有配置发送给客户端。

      平时我还要做一些服务健康检查的事儿,在上面服务启动的时候,服务还要给我配置一个检查接口和检查频率等一些参数,我会按这些参数每隔一段时间,比如10秒钟去请求一下这个接口,如果不通,我就隔5秒再重试下,如果重试3次还不通,我就认定这个服务挂掉了,就从内存表格中删掉这个服务配置,不然客户端要请求到这个不通服务,我就罪过了。

    说了这么多,还是看下我的整个流程图吧,一图胜千言:

    image.png

     

    最后,再用代码实现下吧,语言是C#,其实语言类似,反正都有现成的sdk。

    1、VS中建个控制台应用,并通过nuget安装consul包

    image.png

     

    2、注册几个服务

     1 static void Main(string[] args)
     2         {
     3             string serviceName = "OrderService";
     4 
     5             // 注册服务
     6             RegisteService(serviceName, new DnsEndPoint("127.0.0.1", 16005));
     7             RegisteService(serviceName, new DnsEndPoint("127.0.0.1", 16007));
     8             RegisteService(serviceName, new DnsEndPoint("127.0.0.1", 16008));
     9             Console.ReadKey();
    10         }
    11 
    12        static bool RegisteService(string serviceName, DnsEndPoint dnsEndPoint)
    13         {
    14             var serviceId = GenServiceId(serviceName, dnsEndPoint);
    15             var checkId = GenCheckId(serviceName, dnsEndPoint);
    16             var checkName = GenCheckName(serviceName, dnsEndPoint);
    17             var check = new AgentCheckRegistration
    18             {
    19                 ID = checkId,
    20                 Name = checkName,
    21                 TCP = $"{dnsEndPoint.Host}:{dnsEndPoint.Port}",
    22                 Interval = TimeSpan.FromSeconds(10),
    23                 Status = HealthStatus.Passing,
    24                 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(20),
    25             };
    26             var service = new AgentServiceRegistration
    27             {
    28                 ID = serviceId,
    29                 Name = serviceName,
    30                 Address = dnsEndPoint.Host,
    31                 Port = dnsEndPoint.Port,
    32                 Check = check
    33             };
    34 
    35             var _client = new ConsulClient(config => 
    36             {
    37                 var uriBuilder = new UriBuilder("http://localhost:8500");
    38                 config.Address = uriBuilder.Uri;
    39             });
    40             var res = _client.Agent.ServiceRegister(service).Result;
    41             if (res.StatusCode != HttpStatusCode.OK)
    42                 return false;
    43             return true;
    44         }
     

    image.png

     

    3、服务发现

     1         static void Main(string[] args)
     2         {
     3             string serviceName = "OrderService";
     4 
     5             // 服务发现
     6             List<string> targets = FindServiceEndpoints(serviceName);
     7             foreach(var item in targets)
     8             {
     9                 Console.WriteLine(item);
    10             }
    11             Console.ReadKey();
    12         }
    13 
    14         static List<string> FindServiceEndpoints(string serviceName)
    15         {
    16             var _client = new ConsulClient(config =>
    17             {
    18                 var uriBuilder = new UriBuilder("http://localhost:8500");
    19                 config.Address = uriBuilder.Uri;
    20             });
    21 
    22             var targets = new List<string>();
    23             try
    24             {
    25                 var r = _client.Health.Service(serviceName, "", true).Result;
    26                 if (r.StatusCode != HttpStatusCode.OK)
    27                     throw new ApplicationException($"query consul server error");
    28 
    29                 targets = r.Response.Select(x => $"{x.Service.Address}:{x.Service.Port}").ToList();
    30             }
    31             catch { }
    32             return targets;
    33         }
    更多精彩请关注我的关注号:

     

     

  • 相关阅读:
    PHP基本的语法以及和Java的差别
    Linux 性能測试工具
    【Oracle 集群】Linux下Oracle RAC集群搭建之Oracle DataBase安装(八)
    【Oracle 集群】Oracle 11G RAC教程之集群安装(七)
    【Oracle 集群】11G RAC 知识图文详细教程之RAC在LINUX上使用NFS安装前准备(六)
    【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 特殊问题和实战经验(五)
    【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之缓存融合技术和主要后台进程(四)
    【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 工作原理和相关组件(三)
    Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之ORACLE集群概念和原理(二)
    【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之集群概念介绍(一)
  • 原文地址:https://www.cnblogs.com/maitian-lf/p/12377646.html
Copyright © 2011-2022 走看看