写点什么

Consul 的基本使用与集群搭建

作者:神秘码农
  • 2022 年 5 月 07 日
  • 本文字数:7316 字

    阅读完需:约 24 分钟

@[toc]

一、注册中心的概念

  • 概念能够注册微服务地址【ip:端口】的组件就是注册中心。如图:


  • 目的保证微服务的动态伸缩性。

二、注册中心的使用场景

  • 场景主要场景是在微服务中使用。如图:


三、注册中心的技术选型

  • 类型

  • zookeeper

  • consul

  • etcd

  • eureka

  • 特点


  • Consul 的三个概念

  • server:存储微服务地址【ip:端口】

  • client:连接 Consul

  • agent:后台服务

  • 应用架构集成原理如图:

四、注册中心的项目落地

  • 工具

  • Consul 网盘下载地址:链接:https://pan.baidu.com/s/1zN4PiFVuNAPysMabKdDkzg 提取码:lnk7

  • demo 项目

  • 步骤

  • Consul 运行命令


     # 在根目录下启动运行       consul.exe agent -dev   #在开发模式下启动命令      consul agent -server -bootstrap-expect [节点数据量]  -data-dir d:/consul/data  [数据存储地址]
复制代码


运行结果如下:![在这里插入图片描述](https://img-blog.csdnimg.cn/4d3b15fd85b845d19506b9c42c0cb865.png#pic_center)
复制代码



  • demo 项目

  • nuget 安装


        Consul
复制代码


- appsettings.json 添加配置信息
复制代码


        {          ......          "ConsulRegistry": {            "Name": "testService",            "RegistryAddress": "http://127.0.0.1:8500",            "HealthCheckAddress": "/HealthCheck"          }        } 
复制代码


- 新增配置实体类,通过json文件映射到实体配置类
复制代码


        public class ServiceRegistryConfig        {            /// <summary>            /// 服务ID            /// </summary>            public string Id {get;set;}            /// <summary>            /// 服务名称            /// </summary>            public string Name {get;set;}               /// <summary>            /// 服务标签            /// </summary>            public string[] Tags { get; set; }            /// <summary>            /// 服务地址            /// </summary>            public string Address { get; set; }            /// <summary>            /// 服务端口号            /// </summary>            public int Port { get; set; }            /// <summary>            /// 服务注册地址            /// </summary>            public string RegistryAddress { get; set; }            /// <summary>            /// 服务健康检查地址            /// </summary>            public string HealthCheckAddress { get; set; }           }
复制代码


- 微服务注册  - 创建服务注册实现类
复制代码


           public class ServiceRegistry : IServiceRegistry            {                public void Register(ServiceRegistryConfig serviceRegistryConfig)                {                    //1 建立consul客户端的连接                    var consulClient = new ConsulClient(configuration =>                    {                        configuration.Address = new Uri(serviceRegistryConfig.RegistryAddress);                    });                    //2 创建 consul服务注册对象                    var registration = new AgentServiceRegistration()                    {                        ID = serviceRegistryConfig.Id,                        Name = serviceRegistryConfig.Name,                        Address = serviceRegistryConfig.Address,                        Port = serviceRegistryConfig.Port,                        Tags = serviceRegistryConfig.Tags,                        //健康检查                        Check = new AgentServiceCheck()                        {                            //设置健康检查超时时间                            Timeout = TimeSpan.FromSeconds(10),                            //服务停止5秒后注销服务                            DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(50),                            //健康检查地址                            HTTP = serviceRegistryConfig.HealthCheckAddress,                            //健康检查间隔时间                            Interval = TimeSpan.FromSeconds(10)                        }                    };                    //服务注册                    consulClient.Agent.ServiceRegister(registration);                    //关闭连接释放资源                    consulClient.Dispose();                 }                 /// <summary>                 /// 注册中心注销                 /// </summary>                 /// <param name="serviceRegistryConfig"></param>                public void Deregister(ServiceRegistryConfig serviceRegistryConfig)                 {                 var consulClient = new ConsulClient(configuration => {                     configuration.Address = new Uri(serviceRegistryConfig.Address);                 });                    consulClient.Agent.ServiceDeregister(serviceRegistryConfig.Id);                }            }
复制代码


  - 创建服务注册看接口类
复制代码


            public interface IServiceRegistry            {                void Register(ServiceRegistryConfig serviceRegistryConfig);                void Deregister(ServiceRegistryConfig serviceRegistryConfig);            }
复制代码


  - 创建服务注册扩展类
复制代码


        //consul服务注册类            public static class ConsulExtensions            {               /// <summary>               /// 注册中心扩展               /// </summary>               /// <param name="services"></param>               /// <param name="Configuration"></param>               /// <returns></returns>                public static IServiceCollection AddConsul(this IServiceCollection services, IConfiguration Configuration)                 {                    //将json文件映射到实体类                    services.Configure<ServiceRegistryConfig>(Configuration.GetSection("ConsulRegistry"));                    services.AddSingleton<IServiceRegistry, ServiceRegistry>();                    return services;                 }            }           // 服务启动时注册服务           public static class ConsulApplicationBuilderExtension            {                public static IApplicationBuilder UseConsulRegistry(this IApplicationBuilder app)                {                    //获取配置信息                    var serviceNode = app.ApplicationServices.GetRequiredService<IOptions<ServiceRegistryConfig>>().Value;                    //获取生命周期                    var lifetime = app.ApplicationServices.GetRequiredService<IHostApplicationLifetime>();                    //获取服务注册实力                    var consulRegistry = app.ApplicationServices.GetRequiredService<IServiceRegistry>();                    //获取服务地址信息                    var features = app.Properties["server.Features"] as FeatureCollection;                    var address = features.Get<IServerAddressesFeature>().Addresses.First();                    var uri = new Uri(address);                    //服务注册                    serviceNode.Id = Guid.NewGuid().ToString();                    serviceNode.Address = $"{uri.Scheme}://{ uri.Host}";                    serviceNode.Port = uri.Port;                    serviceNode.HealthCheckAddress = $"{uri.Scheme}://{uri.Host}:{uri.Port}{serviceNode.HealthCheckAddress}";                    consulRegistry.Register(serviceNode);                    //服务器关闭时注销服务                    lifetime.ApplicationStopping.Register(() => {                        consulRegistry.Deregister(serviceNode);                    });                    return app;                }            }         //在startup类中ConfigureServices 方法中注册服务             services.AddConsul(Configuration);         //在startup类中Configure 方法启动服务            app.UseConsulRegistry();
复制代码


    运行结果如下:    ![在这里插入图片描述](https://img-blog.csdnimg.cn/48e399c4c1174b8aaa0d54ee1fcedffb.png#pic_center)
- 微服务发现 - 在appsettings.json 文件中新增Consul注册地址配置
复制代码


             ......                "ConsulDiscoverys": {                       "RegistryAddress": "http://127.0.0.1:8500"                      }            .....
复制代码


  - 新建配置类
复制代码


             public class ServiceDiscoveryConfig            {                public string RegistryAddress { get; set; }            }
复制代码


  - 新增服务发现接口类
复制代码


             public interface IConsulDiscovery            {                Task<List<ServiceUrl>> Discovery(string  ServiceName);            }  
复制代码


  - 新增服务发现实现类
复制代码


            public class ConsulDiscovery : IConsulDiscovery            {                private readonly IConfiguration Configuration;                public ConsulDiscovery(IConfiguration _Configuration) {                    Configuration = _Configuration;                }                /// <summary>                /// 服务发现                 /// </summary>                /// <param name="ServiceName">服务名称</param>                /// <returns>返回一个集合</returns>                public async Task<List<ServiceUrl>> Discovery(string ServiceName)                {                    List<ServiceUrl> list = new List<ServiceUrl>();                    ServiceDiscoveryConfig serviceDiscoveryConfig = new ServiceDiscoveryConfig();                    serviceDiscoveryConfig = Configuration.GetSection("ConsulDiscoverys").Get< ServiceDiscoveryConfig >();                    //1 建立连接                    var consulClient = new ConsulClient(Options => {                        Options.Address = new Uri(serviceDiscoveryConfig.RegistryAddress);                    });                    // 2 根据服务名称获取注册的服务地址                    var queryResult = await  consulClient.Catalog.Service("ServiceName");                    // 3 将注册的地址注入集合中                    foreach (var item in queryResult.Response)                    {                        list.Add(new ServiceUrl() { Url = item.Address+":"+ item.ServicePort });                    }                    return list;                }            }
复制代码


  - 在扩展类中新增发现服务的扩展
复制代码


            public static IServiceCollection AddConsulDiscovery(this IServiceCollection services)             {                services.AddSingleton<IConsulDiscovery, ConsulDiscovery>();                return services;            }
复制代码


  - 在Startup类ConfigureServices方法中进行注册
复制代码


          //服务发现          services.AddConsulDiscovery();
复制代码


  - 在控制器构造函数中注入下服务发现的接口
复制代码


            private readonly IConsulDiscovery consulDiscovery;            public HomeController(IConsulDiscovery _consulDiscovery)             {                 consulDiscovery = _consulDiscovery;            }            .....            //然后在其他方法中根据服务名称获取服务地址;注意:返回值是一个集合。
复制代码

五、注册中心 Consul 的高可用

  • 集群搭建 【最好有 3 个实例】

  • 步骤

  • 节点 1


       # 1、新建配置文件,路径:D:/Assembly/Consul/node1/basic.json       {  "datacenter": "dc1",  "data_dir": "D:/Assembly/Consul/node1",  "log_level": "INFO",  "server": true,  "node_name": "node1",  "ui": true,  "bind_addr": "127.0.0.1",  "client_addr": "127.0.0.1",  "advertise_addr": "127.0.0.1",  "bootstrap_expect": 3,  "ports":{    "http": 8500,    "dns": 8600,    "server": 8300,    "serf_lan": 8301,    "serf_wan": 8302}}       # 2、运行命令       # 2、切换到consul根目录下:       consul.exe agent -config-file=D:/Assembly/Consul/node1/basic.json
复制代码


- 节点2  
复制代码


       # 1、新建配置文件,路径:D:/Assembly/Consul/node2/basic.json       {  "datacenter": "dc1",  "data_dir": "D:/Assembly/Consul/node2",  "log_level": "INFO",  "server": true,  "node_name": "node2",  "bind_addr": "127.0.0.1",  "client_addr": "127.0.0.1",  "advertise_addr": "127.0.0.1",  "ports":{    "http": 8510,    "dns": 8610,    "server": 8310,    "serf_lan": 8311,    "serf_wan": 8312}}         # 2、切换到consul根目录下:        consul.exe agent -config-file=D:/Assembly/Consul/node2/basic.json -retry-join=127.0.0.1:8301
复制代码


- 节点3 
复制代码


       # 1、新建配置文件,路径:文件地址:D:/Assembly/Consul/node3/basic.json       {  "datacenter": "dc1",  "data_dir": "D:/Assembly/Consul/node3",  "log_level": "INFO",  "server": true,  "node_name": "node3",  "bind_addr": "127.0.0.1",  "client_addr": "127.0.0.1",  "advertise_addr": "127.0.0.1",  "ports":{    "http": 8520,    "dns": 8620,    "server": 8320,    "serf_lan": 8321,    "serf_wan": 8322}}       # 2、切换到consul根目录下:        consul.exe agent -config-file=D:/Assembly/Consul/node3/basic.json -retry-join=127.0.0.1:8301
复制代码


  运行结果如图:  ![在这里插入图片描述](https://img-blog.csdnimg.cn/0a5a693483e844ee84f1bd238ffe9a00.png#pic_center)
复制代码





  • 查看主节点


     #切换到consul根目录下     consul.exe info
复制代码


  • 集群搭建命令


        -bind:为该节点绑定一个地址        -enable-script-checks=true:设置检查服务为可用        -join:加入到已有的集群中        -server 表示当前使用的server模式        -node:指定当前节点在集群中的名称         -config-file - 要加载的配置文件        -config-dir:指定配置文件,定义服务的,默认所有以.json结尾的文件都会读        -datacenter: 数据中心没名称,不设置的话默认为dc        -client: 客户端模式        -ui: 使用consul自带的ui界面         -data-dir consul存储数据的目录        -bootstrap:用来控制一个server是否在bootstrap模式,在一个datacenter中只能有一个server处于bootstrap模式,当一个server处于bootstrap模式时,可以自己选举为raft leader。        -bootstrap-expect:在一个datacenter中期望提供的server节点数目,当该值提供的时候,consul一直等到达到指定sever数目的时候才会引导整个集群,该标记不能和bootstrap公用                这两个参数十分重要, 二选一,如果两个参数不使用的话,会出现就算你使用join将agent加入了集群仍然会报         2018/10/14 15:40:00 [ERR] agent: failed to sync remote state: No cluster leader
复制代码


  • 配置文件参数


        ui: 相当于-ui 命令行标志。        acl_token:agent会使用这个token和consul server进行请求        acl_ttl:控制TTL的cache,默认是30s        addresses:一个嵌套对象,可以设置以下key:dns、http、rpc        advertise_addr:等同于-advertise        bootstrap:等同于-bootstrap        bootstrap_expect:等同于-bootstrap-expect        bind_addr:等同于-bindca_file:提供CA文件路径,用来检查客户端或者服务端的链接        cert_file:必须和key_file一起        check_update_interval:        client_addr:等同于-client        datacenter:等同于-dc        data_dir:等同于-data-dir        disable_anonymous_signature:在进行更新检查时禁止匿名签名        enable_debug:开启debug模式        enable_syslog:等同于-syslog        encrypt:等同于-encrypt        key_file:提供私钥的路径        leave_on_terminate:默认是false,如果为true,当agent收到一个TERM信号的时候,它会发送leave信息到集群中的其他节点上。        log_level:等同于-log-level node_name:等同于-node         ports:这是一个嵌套对象,可以设置以下key:dns(dns地址:8600)、http(http api地址:8500)、rpc(rpc:8400)、serf_lan(lan port:8301)、serf_wan(wan port:8302)、server(server rpc:8300)         protocol:等同于-protocol        rejoin_after_leave:等同于-rejoin        retry_join:等同于-retry-join        retry_interval:等同于-retry-interval         server:等同于-server        syslog_facility:当enable_syslog被提供后,该参数控制哪个级别的信息被发送,默认Local0        ui_dir:等同于-ui-dir
复制代码


发布于: 刚刚阅读数: 4
用户头像

神秘码农

关注

还未添加个人签名 2022.03.14 加入

好好学习,天天向上!

评论

发布
暂无评论
Consul的基本使用与集群搭建_神秘码农_InfoQ写作社区