前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Cloud 系列之注册中心 Consul

Spring Cloud 系列之注册中心 Consul

作者头像
Demo_Null
发布2020-11-11 17:52:01
1.3K0
发布2020-11-11 17:52:01
举报
文章被收录于专栏:Java 学习Java 学习

1.1 简介

1.1.1 概述

  Consul 是 HashiCorp 公司推出的开源工具,Consul 由 Go 语言开发,部署起来非常容易,只需要极少的可执行程序和配置文件,具有绿色、轻量级的特点。Consul 是分布式的、高可用的、 可横向扩展的用于实现分布式系统的服务发现与配置。这些功能中的每一项都可以根据需要单独使用,也可以一起使用来构建一个完整的服务网格。Consul 分为 Client 和 Server 两种节点(所有的节点也被称为 Agent),Server 节点保存数据,Client 负责健康检查及转发数据请求到 Server。Consul 的主要功能有:  ♞ 服务发现:Consul 的客户端可以注册一个服务,比如 api 或 mysql,其他客户端可以使用 Consul 来发现特定服务的提供者。使用 DNS 或 HTTP,应用程序可以很容易地找到他们所依赖的服务。  ♞ 健康检查:Consul 客户端可以提供任何数量的健康检查,要么与给定的服务相关联(如: “webserver是否返回 200 OK”),要么与本地节点相关联(如: “内存利用率是否低于 90%”)。这些信息可以运维人员用来监控集群的健康状况,并被服务发现组件来路由流量(比如: 仅路由到健康节点)  ♞ KV存储:应用程序可以利用 Consul 的层级 K/V 存储来实现任何目的,包括动态配置、功能标记、协调、领导者选举等。Consul 提供了 HTTP API,使其非常简单以用。  ♞ 安全服务通信: Consul 可以为服务生成和分发 TLS( 传输层安全性协议) 证书,以建立相互的 TLS 连接。可以使用 Intention 来定义哪些服务被允许进行通信。服务隔离可以通过可以实时更改 Intention 策略轻松管理,而不是使用复杂的网络拓扑结构和静态防火墙规则。  ♞ 多数据中心:Consul 支持开箱即用的多数据中心。这意味着 Consul 的用户不必担心建立额外的抽象层来发展到多个区域。

在这里插入图片描述
在这里插入图片描述

1.1.2 安装

☞ Windows

♞ 首先去官网下载对应版本的 ☞ Consul ♞ Windows 中直接双击安装,黑框一闪而过就已经装好了 ♞ 使用 consul --version 查看安装的版本 ♞ 使用 sonsul agent -dev 启动开发模式

在这里插入图片描述
在这里插入图片描述

♞ 访问 http://localhost:8500 进入 consul web 界面

在这里插入图片描述
在这里插入图片描述
☞ Linux

♞ 使用 yum install -y unzip zip 命令在服务器上安装 zip 解压 ♞ 将 consul 安装 包上传至服务器 ♞ 使用 unzip xxx 解压 ♞ 使用 ./consul agent -server -bootstrap-expect 1 -data-dir=/tmp/consul -node=consul_1 -bind=127.0.0.1 -client=0.0.0.0 -ui 启动 consul,其中 -server 表示是 server 模式;-bootstrap-expect=1 表示是集群中有 1 台服务器;-bootstrap该模式 node 可以指定自己作为 leader ,如果是非 leader 可不加该参数;-data-dir=/tmp/consul 为代理存储状态提供了一个数据目录;-node=n2 该服务器节点名;-bind=127.0.0.1 节点绑定的 ip;-ui 非必须 webui 的路径,用 web 来管理 consul。☞ 其他配置详见

1.1.3 相关依赖

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>

1.2 Provider

1.2.1 配置文件

代码语言:javascript
复制
server:
  port: 8093

spring:
  application:
    name: ProviderServer
  cloud:
    consul:
      host: localhost
      port: 8500
	discovery:
		# 表示注册时使用 ip 而不是 hostname
        prefer-ip-address: true
		# 健康检查失败多长时间取消注册
		health-check-critical-timeout: 10s

1.2.2 启动类

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/10/29
 * @description 服务提供者启动类
 */
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}

1.2.3 服务类

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author gaohu9712@163.com
 * @date 2020/10/29
 * @description
 */

@RestController
@RequestMapping("/provider")
public class ProviderController {

    @GetMapping("/get")
    public Object get() {
        return "你已经消费了";
    }
}

1.2.4 启动服务

在这里插入图片描述
在这里插入图片描述

1.3 Consumer

1.3.1 配置文件

代码语言:javascript
复制
server:
  port: 80

spring:
  application:
    name: ConsumerServer
  cloud:
    consul:
      host: localhost
      port: 8500
	discovery:
		# 表示注册时使用 ip 而不是 hostname
        prefer-ip-address: true
		# 健康检查失败多长时间取消注册
		health-check-critical-timeout: 10s

1.3.2 启动类

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/10/29
 * @description 消费者启动类
 */
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}

1.3.3 服务类

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/10/29
 * @description
 */
@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    @Autowired
    private DiscoveryClient discoveryClient;


    @GetMapping("/go")
    public void go() {
        List<ServiceInstance> providerServer = discoveryClient.getInstances("ProviderServer");

        if (0 == providerServer.size()) {
            return;
        }

        ServiceInstance serviceInstance = providerServer.get(0);
        System.out.print(serviceInstance.getUri() + " --- ");
        String url = serviceInstance.getUri() + "/provider/get";


        RestTemplate restTemplate = new RestTemplate();
        String str = restTemplate.getForObject(url, String.class);
        System.out.println(str);
    }
}

1.3.4 启动服务

在这里插入图片描述
在这里插入图片描述

1.3.5 请求服务

在这里插入图片描述
在这里插入图片描述

1.4 集群

1.4.1 Consul 集群

分别启动三台服务器上的 Consul,注意此时集群没有搭建完毕,访问 web 会报错 ./consul agent -server -bootstrap-expect=3 -data-dir=/tmp/data -node=consul_1 -bind=192.168.91.131 -client=0.0.0.0 -ui ./consul agent -server -bootstrap-expect=3 -data-dir=/tmp/data -node=consul_2 -bind=192.168.91.134 -client=0.0.0.0 ./consul agent -server -bootstrap-expect=3 -data-dir=/tmp/data -node=consul_3 -bind=192.168.91.135 -client=0.0.0.0 使用 ./consul join 192.168.91.131 命令将 2号、3号加入 1号中,如果我们的服务只有 10 个左右那么至此集群搭建可以就此完毕。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

但是我们的服务有更多的话,就需要加入 client 端,正常使用 Consul 的时候还是要有 Client 才好,这也符合 Consul 的反熵设计。使用 ./consul agent -data-dir=/tmp/data -node=consul_client -bind=192.168.91.136 -client=0.0.0.0 启动 consul client 并将其加入 131 上的 1 号节点中中。此时我们一个完整的集群才算搭建完成。

1.4.2 Provider 集群

☞ 配置文件
代码语言:javascript
复制
spring:
  application:
    name: ProviderServer
  cloud:
    consul:
      host: 192.168.91.136
      port: 8500
      discovery:
        # 表示注册时使用 ip 而不是 hostname
        prefer-ip-address: true
        # 健康检查失败多长时间取消注册
        health-check-critical-timeout: 10s

  我们发现配置文件与单体时没有什么区别,那么是不是 consul 中服务注册到节点后,其他节点自动同步呢?在 web 控制台我们发现只有 client 节点有,而其他节点并没有显示。这是为什么呢?这个根本原因是服务发现的实现原理不同。

在这里插入图片描述
在这里插入图片描述

  Consul 的数据同步也是强一致性的,服务的注册信息会在 Server 节点之间同步,服务的信息还是持久化保存的,即使服务部署不可用了,仍旧可以查询到这个服务部署。但是业务服务的可用状态是由注册到的 Agent 来维护的,Agent 如果不能正常工作了,则无法确定服务的真实状态。并且 Consul 是相当稳定了,Agent 挂掉的情况下大概率服务器的状态也可能是不好的,此时屏蔽掉此节点上的服务是合理的。   Consul 也确实是这样设计的,DNS 接口会自动屏蔽挂掉节点上的服务,HTTP API 也认为挂掉节点上的服务不是 passing 的。鉴于 Consul 健康检查的这种机制,同时避免单点故障,所有的业务服务应该部署多份,并注册到不同的 Consul 节点。

☞ 服务发现原理
在这里插入图片描述
在这里插入图片描述

  首先需要有一个正常的 Consul 集群,有 Server,有 Leader。这里在服务器 Server 1、Server 2、Server 3 上分别部署了 Consul Server。假设他们选举了 Server 2 上的 Consul Server 节点为 Leader。这些服务器上最好只部署 Consul 程序,以尽量维护 Consul Server 的稳定。   然后在服务器 Server 4 和 Server 5 上通过 Consul Client 分别注册 Service A、B、C,这里每个 Service 分别部署在了两个服务器上,这样可以避免 Service 的单点问题。Consul Client 可以认为是无状态的,它将注册信息通过 RPC 转发到 Consul Server,服务信息保存在 Server 的各个节点中,并且通过 Raft 实现了强一致性。   最后在服务器 Server 6 中 Program D 需要访问 Service B,这时候 Program D 首先访问本机 Consul Client 提供的 HTTP API,本机 Client 会将请求转发到 Consul Server。Consul Server 查询到 Service B 当前的信息返回,最终 Program D 拿到了 Service B 的所有部署的 IP 和端口,然后就可以选择 Service B 的其中一个部署并向其发起请求了。   如果服务发现采用的是 DNS 方式,则 Program D 中直接使用 Service B 的服务发现域名,域名解析请求首先到达本机 DNS 代理,然后转发到本机 Consul Client,本机 Client 会将请求转发到 Consul Server。Consul Server 查询到 Service B 当前的信息返回,最终 Program D 拿到了 Service B 的某个部署的 IP 和端口。

1.4.3 测试

  为了验证其他 consul 节点是可以获取到服务信息的,咱们将 consumer 注册到其他的 consul 节点,然后看使用能后实现远程调用。

在这里插入图片描述
在这里插入图片描述

  我们可以发现确实可以获取到 provider 的相关信息并且实现远程调用,证明 consul 集群确实是将信息同步了,但是 consul 集群将服务交由注册方管理,当注册方失效时,通过其注册的服务全部失效。

在这里插入图片描述
在这里插入图片描述

☞ 源码 ☞ Consul 中文文档 ☞ 一篇文章了解Consul服务发现实现原理

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-11-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.1 简介
    • 1.1.1 概述
      • 1.1.2 安装
        • ☞ Windows
        • ☞ Linux
      • 1.1.3 相关依赖
      • 1.2 Provider
        • 1.2.1 配置文件
          • 1.2.2 启动类
            • 1.2.3 服务类
              • 1.2.4 启动服务
              • 1.3 Consumer
                • 1.3.1 配置文件
                  • 1.3.2 启动类
                    • 1.3.3 服务类
                      • 1.3.4 启动服务
                        • 1.3.5 请求服务
                        • 1.4 集群
                          • 1.4.1 Consul 集群
                            • 1.4.2 Provider 集群
                              • ☞ 配置文件
                              • ☞ 服务发现原理
                            • 1.4.3 测试
                            相关产品与服务
                            服务网格
                            服务网格(Tencent Cloud Mesh, TCM),一致、可靠、透明的云原生应用通信网络管控基础平台。全面兼容 Istio,集成腾讯云基础设施,提供全托管服务化的支撑能力保障网格生命周期管理。IaaS 组网与监控组件开箱即用,跨集群、异构应用一致发现管理加速云原生迁移。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档