Spring Cloud之(十)服务注册中心Consul

十、服务注册中心Consul

在 Spring Cloud 体系中,几乎每个角色都会有两个及以上的产品来提供选择。比如微服务注册中心有:Eureka、Consul、zookeeper、etcd 等;网关的产品有 Zuul、Spring Cloud Gateway 等。在注册中心产品中,最常使用的就是 Eureka 和 Consul,两者各有特点,我们可以根据自述项目情况来选择。

前面我们已经学习了如何使用eureka注册中心来进行服务注册和服务发现,这篇文章主要就是讲述另一个微服务注册中心Consul。

10.1 Consul的概述

  • 什么是Consul?

    Consul 是 HashiCorp 公司推出的开源产品,用于实现分布式系统的服务发现、服务隔离、服务配置,这些功能中的每一个都可以根据需要单独使用,也可以同时使用所有功能。Consul 官网目前主要推 Consul 在服务网格中的使用。

    与其它分布式服务注册与发现的方案相比,Consul 的方案更“一站式”——内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其它工具。Consul 本身使用 go 语言开发,具有跨平台、运行高效等特点,也非常方便和 Docker 配合使用。

  • Consul 的优势:

    1. 使用 Raft 算法来保证一致性, 比复杂的 Paxos 算法更直接. 相比较而言, zookeeper 采用的是 Paxos, 而 etcd 使用的则是 Raft。
    2. 支持多数据中心,内外网的服务采用不同的端口进行监听。 多数据中心集群可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟, 分片等情况等。 zookeeper 和 etcd 均不提供多数据中心功能的支持。
    3. 支持健康检查。 etcd 不提供此功能。
    4. 支持 http 和 dns 协议接口。 zookeeper 的集成较为复杂, etcd 只支持 http 协议。
    5. 官方提供 web 管理界面, etcd 无此功能。

    综合比较, Consul 作为服务注册和配置管理的新星, 还是比较值得关注和研究的。

Consul 客户端、服务端还支持夸中心的使用,更加提高了它的高可用性。
在这里插入图片描述

10.2 Consul的调用过程

在这里插入图片描述

1、当 Producer 启动的时候,会向 Consul 发送一个 post 请求,告诉 Consul 自己的 IP 和 Port;

2、Consul 接收到 Producer 的注册后,每隔 10s(默认)会向 Producer 发送一个健康检查的请求,检验 Producer 是否健康;

3、当 Consumer 发送 GET 方式请求 /api/address 到 Producer 时,会先从 Consul 中拿到一个存储服务 IP 和 Port 的临时表,从表中拿到 Producer 的 IP 和 Port 后再发送 GET 方式请求 /api/address;

4、该临时表每隔 10s 会更新,只包含有通过了健康检查的 Producer。

Spring Cloud Consul 项目是针对 Consul 的服务治理实现。Consul 是一个分布式高可用的系统,它包含多个组件,但是作为一个整体,在微服务架构中,为我们的基础设施提供服务发现和服务配置的工具。

10.3 安装Consul

与eureka不同,Consul是用go语言来编写的,因此必须安装后才可以使用。

打开Consul官网可以查看不同系统的版本,根据不同的系统类型选择不同的安装包, Consul 支持所有主流系统,大家根据自己电脑系统选择合适的版本进行下载即可。

  • 下载解压

    下载后是一个压缩包(这里以windows版本为例),自行解压即可:
    在这里插入图片描述
    在这里插入图片描述

  • 启动Consul

    win+R进入解压目录,输入命令启动:

    consul agent -dev -client=0.0.0.0
    

    在这里插入图片描述
    启动成功之后访问:http://localhost:8500,可以看到 Consul 的管理界面:
    在这里插入图片描述
    此时Consul就已经安装成功啦!

10.4 基于Consul注册中心的服务注册与发现

  • Consul服务端(服务注册)

    引入Consul相关依赖:pom.xml

    <!--SpringCloud提供的基于Consul的服务发现-->
    <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-consul-discovery</artifactId>
     </dependency>
     <!--actuator用于心跳检查-->
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-actuator</artifactId>
     </dependency>
    

    配置文件application.yml

    server:
      port: 9011 #端口号
    
    spring:
      application:
        name: ebuy-product #服务名称
      datasource:
        driver-class-name: com.mysql.jdbc.Driver  #mysql驱动
        url: jdbc:mysql://127.0.0.1:3306/ebuy?useUnicode=true&characterEncoding=utf8
        username: root #连接数据库用户名
        password: root #连接数据库密码
      #配置consul
      cloud:
        consul:
          host: 127.0.0.1 #ConsulServer请求地址
          port: 8500 #ConsulServer端口号(默认8500)
          discovery:
            register: true #是否注册
            instance-id: ${spring.application.name}-2  #实例id
            service-name: ${spring.application.name}  #服务实例的名称
            port: ${server.port}  #服务实例的端口号
            health-check-path: /actuator/health #健康检查路径
            health-check-interval: 15s  #健康检查时间间隔(默认10s)
            prefer-agent-address: true  #开启ip地址注册
            ip-address: ${spring.cloud.client.ip-address} #当前微服务请求的ip
    
    mybatis:
      type-aliases-package: cn.ebuy.product.pojo #实体类映射
      mapper-locations: cn/ebuy/product/mapper/*.xml #mybatis扫描xml文件地址
    logging:
      level:
        cn.ebuy: DEBUG
    
  • Consul客户端(服务发现)

    引入Consul相关依赖:pom.xml

    <!--SpringCloud提供的基于Consul的服务发现-->
    <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-consul-discovery</artifactId>
     </dependency>
     <!--actuator用于心跳检查-->
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-actuator</artifactId>
     </dependency>
    

    配置文件application.yml

    server:
      port: 9021 #端口
    spring:
      application:
        name: ebuy-order #服务名称
      #配置consul
      cloud:
        consul:
          host: 127.0.0.1 #ConsulServer请求地址
          port: 8500 #ConsulServer端口号(默认8500)
          discovery:
            register: true #是否注册
            instance-id: ${spring.application.name}-1  #实例id
            service-name: ${spring.application.name}  #服务实例的名称
            port: ${server.port}  #服务实例的端口号
            health-check-path: /actuator/health #健康检查路径
            health-check-interval: 15s  #健康检查时间间隔(默认10s)
            prefer-agent-address: true  #开启ip地址注册
            ip-address: ${spring.cloud.client.ip-address} #当前微服务请求的ip
    
    logging:
      level:
        cn.ebuy: DEBUG
    
    ##需要调用的微服务名称
    ebuy-product:
      ribbon:
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #负载均衡策略
    

    Controller.java

    package cn.ebuy.order.controller;
    import cn.ebuy.order.pojo.EasybuyProduct;
    import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.cloud.client.discovery.DiscoveryClient;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.List;
    
    @RestController
    @RequestMapping("/order")
    @SuppressWarnings("all")
    public class OrderController {
        @Autowired
        RestTemplate restTemplate;
        @Autowired
        private DiscoveryClient discoveryClient;
    
    
        /**
         * 这里的地址是没有做集群时的写法,只有一个地址
         * @param id
         * @return
         */
        @RequestMapping(value = "/{id}",method = RequestMethod.GET)
        public EasybuyProduct findById(@PathVariable Long id) {
            EasybuyProduct easybuyProduct=new EasybuyProduct();
            // 这里是调用product里的服务,端口号是:9011
    //        easybuyProduct=restTemplate.getForObject("http://127.0.0.1:9011/product/"+id,EasybuyProduct.class);
            // 这里直接调用负载均衡策略上配置的需要调用的微服务名称
            easybuyProduct = restTemplate.getForObject("http://ebuy-product/product/"+id,EasybuyProduct.class);
            return easybuyProduct;
        }
    

    注:使用Consul注册中心进行服务注册和服务发现时,只是yml配置文件中需要做Consul的相关配置,在Controller层调用时,与eureka的调用完全相同。
    同时,Consul 依赖已经包含了 Ribbon,所以无需导入 Ribbon即可实现负载均衡。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值