微服务架构:使用Consul实现服务注册和服务发现

参考:

Consul官网  、安装步骤Consul官方指导文档 

注册中心--参考文档

微服务架构基础之注册中心 - 简书

微服务注册中心原理,看这篇就够了! - Java碎碎念 - 博客园

备注:K8S自带服务注册和发现

注册中心

注册中心是什么

注册中心可以说是微服务架构中的”通讯录“,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就到这里找到服务的地址,进行调用。

功能:

  1. 服务注册表:
    服务注册表是注册中心的核心,它用来记录各个微服务的信息,例如微服务的名称、IP、端口等。服务注册表提供查询API和管理API,查询API用于查询可用的微服务实例,管理API用于服务的注册与注销。
  2. 服务注册与发现:
    服务注册是指微服务在启动时,将自己的信息注册到注册中心的过程。服务发现是指查询可用的微服务列表及网络地址的机制。
  3. 服务检查:
    注册中心使用一定的机制定时检测已注册的服务,如发现某实例长时间无法访问,就会从服务注册表移除该实例

优点

  1. 解耦:服务消费者个服务提供者解耦,各自变化,不互相影响
  2. 扩展:服务消费者和服务提供者增加和删除新的服务,对于双方没有任何影响
  3. 中介者设计模式:这是一种多对多关系的典范

zookeeper

参考:官网   指导文档
ZooKeeper  [ˈzuːkiːpər]  是用于维护配置信息,命名,提供分布式同步和提供组服务的集中式服务。所有这些类型的服务都以某种形式被分布式应用程序使用。每次实施它们时,都会进行很多工作来修复不可避免的错误和竞争条件。由于难以实现这类服务,因此应用程序通常最初会在其上跳过,从而使它们在发生更改时变得脆弱且难以管理。即使部署正确,这些服务的不同实现也会导致管理复杂。

Consul是什么

Consul是一个用来实现分布式系统的服务发现与配置的开源工具。是由go语言开发。他主要由多个组成部分:

  • 服务发现:客户端通过Consul提供服务,类似于API,MySQL,或者其他客户端可以使用Consul发现服务的提供者。使用类似DNS或者HTTP,应用程序和可以很轻松的发现他们依赖的服务。

  • 检查健康:Consul客户端可以提供与给定服务相关的健康检查(Web服务器返回200 ok)或者本地节点(“内存利用率低于90%”)。这些信息可以监控集群的运行情况,并且使访问远离不健康的主机组件。

  • 键值对存储:应用程序可以使用Cousul的层级键值对。

  • 多数据中心:Consul有开箱及用的多数据中心。

Consul 的角色

1、server 服务端

提供存储服务
保存配置信息, 高可用集群, 在局域网内与本地客户端通讯, 通过广域网与其他数据中心通讯
server节点:负责组成 cluster 的复杂工作(选举、状态维护、转发请求到 lead),以及 consul 提供的服务(响应 RCP 请求)。考虑到容错和收敛,一般部署 3 ~ 5 个比较合适。

2、client 客户端

操作server
无状态, 将 HTTP 和 DNS 接口请求转发给局域网内的服务端集群
client 节点:负责转发所有的 RPC 到 server 节点。本身无状态,且轻量级,因此,可以部署大量的 client 节点。

3、agent 代理

进程启动 agent 守护进程
组成 consul 集群的每个成员上都要运行一个 agent,可以通过 consul agent 命令来启动。agent 可以运行在 server 状态或者 client 状态。自然的,运行在 server 状态的节点被称为 server 节点;运行在 client 状态的节点被称为 client 节点。

Consul注册中心运行流程

文字描述:server服务默认就通过agent启动=》其他服务要注册服务时先调用client客户端,client客户端再通过agent启动

下载+启动

Linux安装

参考:安装步骤

window版下载地址

启动服务端:不需要安装,命令启动

下载完解压后,不需要安装,在解压后的文件夹中打开CMD命令窗口

如果要查看consul命令,输入:consul

环境变量设置:为了方便启动,最好设置环境变量,这样就不用每次都去指定文件夹启动consul了,具体参考:consul环境变量设置

开发模式启动命令(所有数据都保存在内存中):consul.exe agent -dev

生产模式启动命令(绑定默认地址和存储数据的路径):consul agent -server -bind=127.0.0.1 -bootstrap-expect 1 -data-dir d:/consul/data 

在浏览器中输入查看地址(端口默认是8500,如果变更,在启动后命令窗口处能看到):http://localhost:8500

客户端启动

使用.NET启动客户端

项目中使用Consul

先参考文档:注册中心--文档

设计思路:

Consul服务器方法和Consul客户端方法都封装在MicroService.Core中,使用时是:例如在TeamService中调用Consul服务端方法进行服务注册,在AggregateService中调用Consul客户端方法来服务发现

Consul服务端和客户端封装在MicroService.Core(核心服务)中

  1. 包安装:NuGet包中搜索Consul且安装
  2. 注册服务端方法:在ConsulServiceRegistry类中服务注册
            /// <summary>
            /// 注册服务方法
            /// </summary>
            /// <param name="serviceNode"></param>
            public void Register(ServiceRegistryConfig serviceNode)
            {
                // 1、创建consul客户端连接
                var consulClient = new ConsulClient(configuration =>
                {
                    //1.1 建立客户端和服务端连接
                    configuration.Address = new Uri(serviceNode.RegistryAddress);
                });
    
                // 2、获取服务内部地址
    
                // 3、创建consul服务注册对象
                var registration = new AgentServiceRegistration()
                {
                    ID = serviceNode.Id,
                    Name = serviceNode.Name,
                    Address = serviceNode.Address,
                    Port = serviceNode.Port,
                    Tags = serviceNode.Tags,
                    //心跳检测
                    Check = new AgentServiceCheck
                    {
                        // 3.1、consul健康检查超时间
                        Timeout = TimeSpan.FromSeconds(10),
                        // 3.2、服务停止5秒后注销服务
                        DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                        // 3.3、consul健康检查地址
                        HTTP = serviceNode.HealthCheckAddress,
                        // 3.4 consul健康检查间隔时间
                        Interval = TimeSpan.FromSeconds(10),
                    }
                };
    
                // 4、注册服务
                consulClient.Agent.ServiceRegister(registration).Wait();
    
                // 5、关闭连接
                consulClient.Dispose();
            }
  3. 客户端方法:在ConsulHttpClient类中服务发现
            /// <summary>
            /// Get方法
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// param name="ServiceSchme">服务名称:(http/https)</param>
            /// <param name="ServiceName">服务名称</param>
            /// <param name="serviceLink">服务路径</param>
            /// <returns></returns>
            public async Task<T> GetAsync<T>(string Serviceshcme, string ServiceName,string serviceLink)
            {
                // 1、获取服务
                IList<ServiceUrl> serviceUrls = await serviceDiscovery.Discovery(ServiceName);
    
                // 2、负载均衡服务
                ServiceUrl serviceUrl = loadBalance.Select(serviceUrls);
    
                // 3、建立请求
                Console.WriteLine($"请求路径:{Serviceshcme} +'://'+{serviceUrl.Url} + {serviceLink}");
                HttpClient httpClient = httpClientFactory.CreateClient("mrico");
                // HttpResponseMessage response = await httpClient.GetAsync(serviceUrl.Url + serviceLink);
                HttpResponseMessage response = await httpClient.GetAsync(Serviceshcme +"://"+serviceUrl.Url + serviceLink);
    
                // 3.1 json转换成对象
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    string json = await response.Content.ReadAsStringAsync();
    
                    return JsonConvert.DeserializeObject<T>(json);
                } else
                {
                    // 3.2 进行自定义异常处理,这个地方进行了降级处理
                    throw new Exception($"{ServiceName}服务调用错误:{response.Content.ReadAsStringAsync()}");
                }
            }

在TeamService(团队服务)中调用Consul服务端方法

在Startup类的Configure方法中调用Consul服务端方法:

app.UseConsulRegistry() ;

在AggregateService(聚合服务)中调用Consul客户端方法

在HttpTeamServiceClient类中的GetTeams方法中调用Consul客户端方法

List<Team> teams = await consulHttpClient.GetAsync<List<Team>>(ServiceSchme, ServiceName, ServiceLink); 

posted @ 2020-05-21 18:21  日积月累码农  阅读(1703)  评论(1编辑  收藏  举报