SpringCloud(2)--服务注册与发现(Eureka、Zookeeper、Consul)

系列链接:


服务注册中心

在环境搭建中,我们实现了服务模块直接通过Http的方式进行调用。而当我们的服务越来越多时就会不方便管理(服务运行状态等等),所以将这些服务在某个地方注册并进行统一的管理,这个地方就是我们的服务注册中心。

前面我们说过的几种服务注册中心:

  • Eureka
  • Zookeeper
  • Consul

Eureka

服务治理:
image-20200707150526915
而SpringCloud封装了Netflix公司开发的Eureka模块来实现服务治理。

微服务使用 Eureka 的客服端与 Eureka 服务器端维持心跳连接,维护人员就可以在服务器端监控到各个微服务(服务器信息)是否正常。

Eureka包含了两个组件:

  • Eureka Server:提供注册服务,各个微服务节点会在其中进行注册。
  • Eureka Client:一个Java客户端,用于简化与Eureka Server 的交互,同时会定时向Eureka Server发送心跳,如果Eureka Server 在多个心跳周期内没有接收到某个节点的心跳则会将该节点移除。
    在这里插入图片描述

单机版eureka

创建Module

  1. 创建名为cloud-eureka-server7001的模块

  2. 引入pom依赖

		<!-- eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
		<!-- 其他依赖 -->
  1. 配置文件
        server:
          port: 7001
        eureka:
          instance:
            # eureka服务端的实例名称
            hostname: localhost
          client:
            # 不注册自己
            register-with-eureka: false
            # 表示自己是注册中心,不用检索服务
            fetch-registry: false
            service-url: 
              defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  1. 主启动类
        @SpringBootApplication
        @EnableEurekaServer
        public class EurekaMain7001 {
            public static void main(String[] args){
                SpringApplication.run(EurekaMain7001.class,args);
            }
        }
  1. 启动当前项目,访问http://localhost:7001就可以看到如下页面,可以看到当前没有服务注册进来
    image-20200707154608108

其他服务注册到eureka

比如此时pay模块加入eureka:

  1. 修改pom,引入依赖
		<!--eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
  1. 主启动类上,加注解,表示当前是eureka客户端
        @SpringBootApplication
        @EnableEurekaClient
        public class PaymentMain8001 {
            public static void main(String[] args){
                SpringApplication.run(PaymentMain8001.class,args);
            }
        }
  1. 修改配置文件:
        eureka:
          client:
            # 不注册自己
            register-with-eureka: true
            # 表示自己是注册中心,不用检索服务
            fetch-registry: true
            service-url:
              defaultZone: http://localhost:7001/eureka
  1. 先启动EurekaServer,然后启动pay模块,就注册到eureka中了
    image-20200707155716627

  2. order模块的注册是一样的,不再赘述


集群版eureka

集群原理

在这里插入图片描述

  • pay模块与order模块启动时,会注册自己并将自身信息也放入EurekaServer
  • 当order模块调用pay模块时,会先从EurekaServer拿到pay模块的调用地址
  • 底层通过HttpClient调用并且还会缓存一份到本地,每30秒更新一次
  • 如果注册中心只有一个,出现故障就会导致整个微服务环境不可用

构建原理:
image-20200707161448863

构建新erueka项目

  1. 新建名字cloud-eureka-server7002的Module

  2. 主启动类、pom文件复制7001中的

  3. 为了更好辨认,修改Host文件,添加如下:

    127.0.0.1 eureka7001.com
    127.0.0.1 eureka7002.com
    
  4. 修改之前的7001项目的配置文件
    image-20200707162638828

7002也是一样的,只不过端口和地址改一下,多台在defaultZone用逗号隔开

  1. 然后启动7001,7002即可
    image-20200707163304322

其他服务注册到eureka集群

  1. 只需要修改配置文件即可
    在这里插入图片描述
  2. 两个模块都修改上面的都一样即可

将pay模块也配置为集群模式

  1. 新建名称为cloud-provider-payment8002的Module

  2. 主启动类、pom文件、mapper、service、controller复制8001的

  3. 配置文件复制8001的,端口修改一下,改为8002,服务名称不用改,用一样的

  4. 然后修改订单模块中的URL,使请求负载均衡到两个pay模块中

    • 首先添加注解,使RestTemplate开启负载均衡

      (可以指定负载均衡算法,默认轮询)

      @Configuration
      public class ApplicationContextConfig {
          @Bean
          @LoadBalanced
          public RestTemplate getRestTemplate(){
              return new RestTemplate();
          }
      }
      
    • 之后修改RestTemplate请求的URL地址为微服务名称
      image-20200708154508662

为了避免暴露信息以及方便管理,可以修改服务主机名和ip在eureka的web上显示,通过修改配置文件:
在这里插入图片描述


服务发现

对于注册进Eureka里面的微服务,可以通过服务发现来获取该服务的信息,此处以pay模块为例。

  1. 首先注入DiscoverClient服务发现客户端

    @Resource
    private DiscoveryClient discoveryClient;
    
  2. 这里我们便携一个查询接口

    @GetMapping("/discovery")
        public Object discovery(){
            //获取服务列表
            List<String> services = discoveryClient.getServices();
            for(String element : services){
                log.info("****element: "+element);
            }
            //获取具体服务下的实例列表
            List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
            for(ServiceInstance instance : instances){
                log.info(instance.getServiceId()+"/t"+instance.getHost()+"/t"+instance.getPort()+"/t"+instance.getUri());
            }
            return this.discoveryClient;
        }
    
  3. 在主启动类上添加一个注解
    image-20200708155902232

  4. 最后访问我们的接口
    image-20200708161015079


自我保护

为什么有自我保护机制

为了防止EurekaClient可以正常运行,但是与EurekaServer网络不同的情况下,将EurekaClient服务剔除。

**自我保护模式 **

正常情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,就会注销该实例。

而自我保护模式就是某时刻某个微服务不可用了,Eureka不会立即进行清理,依旧会对该微服务的信息进行保存,属于CAP里面的AP分支(下文补充)。当EurekaServer节点在短时间内丢失过多客户端时(网络故障),节点就会进入自我保护模式。

自我保护模式配置

默认自我保护模式是开启的,可以通过配置进行禁用:
在这里插入图片描述

也可以设置客户端接受心跳时间间隔
在这里插入图片描述

此时启动erueka和pay.此时如果直接关闭了pay,那么erueka会直接删除其注册信息

Zookeeper

linux上安装 Zookeeper

Zookeeper是一个分布式协调工具,可以实现注册中心功能,所以可以取代Eureka服务器,作为服务注册与发现中心。

为了方便我们接下来的测试,通过 Docker 方式在远程服务器上以单机形式安装 Zookeeper,并启动。
在这里插入图片描述

创建新的pay模块

  1. 创建名称为 cloud-provider-payment8004 的 Module

  2. pom依赖,相比之前的pay模块,添加如下

    		<!--SpringBoot整合Zookeeper客户端-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
                <exclusions>
                    <!--先排除自带的zookeeper3.5.3-->
                    <exclusion>
                        <groupId>org.apache.zookeeper</groupId>
                        <artifactId>zookeeper</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!--添加zookeeper3.6.1版本-->
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.6.1</version>
    
  3. 配置文件,配置端口号、微服务名称、zookeeper地址

        server:
          port: 8004
        spring:
          application:
            name: cloud-provider-payment
            cloud:
              zookeeper:
                connect-string: hw.mokespace.cn:2181
    
  4. 主启动类

            @SpringBootApplication
            @EnableDiscoveryClient
            public class PaymentMain8004 {
                public static void main(String[] args){
                    SpringApplication.run(PaymentMain8004.class,args);
                }
            }
    
  5. controller随便写一下

        @RestController
        @Slf4j
        @RequestMapping("/payment")
        public class PaymentController {
            @Value("${server.port}")
            private String serverPort;
    
            @GetMapping("/zk")
            public String paymentzk(){
                return "springcloud with zookeeper"+serverPort+"\t"+ UUID.randomUUID().toString();
            }
        }
    
  6. 然后就可以启动,此时8004就注册到zk中了
    image-20200710162629761

    注:我们在zk上注册的node是临时节点,当我们的服务一定时间内没有发送心跳那么zk就会将这个服务的node删除


创建order消费模块注册到zk

  1. 创建名称为 cloud-consumerzk-order80 的 Module

  2. pom、配置文件、RestTemplate 与8004类似

  3. controller

        @RestController
        @Slf4j
        @RequestMapping("/consumer")
        public class OrderController {

            private static final String INVOKE_URL = "http://cloud-provider-payment";

            @Resource
            private RestTemplate restTemplate;

            @GetMapping("/payment/zk")
            public String paymentInfo(){
                return restTemplate.getForObject(INVOKE_URL+"/payment/zk",String.class);
            }
        }
  1. 然后启动即可注册到zk
    image-20200710164320328

集群版zk注册

只需要修改配置文件中的connect-string参数,指定多个zk地址即可。

Consul

Consul 是一套开源的分布式服务发现和配置管理系统,它提供了一种完整的服务网格解决方案,具有如下优点:

  • 服务发现:提供HTTP和DNS两种发现方式
  • 健康检测:支持HTTP、TCP、Docker、Shell等方式
  • KV存储:key-value的存储方式
  • 多数据中心:Consul支持多数据中心
  • 可视化 Web 界面

安装与启动

官网下载一个相应的安装包,博主这里下的是 windows 版本。

exe文件的当前目录打开CMD:

# 查看consul版本

consul --version

# 开发者模式启动

consul agent -dev

访问 http://localhost:8500 即可访问可视化的 Web 页面。
image-20200710170145615


创建新的pay模块

  1. 项目名字cloud-providerconsul-payment8006

  2. pom依赖,修改如下

    		<dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-consul-discovery</artifactId>
            </dependency>
    
  3. 配置文件

            server:
              port: 8004
            spring:
              application:
                name: cloud-provider-payment
              cloud:
                consul:
                  host: localhost
                  port: 8500
                  discovery:
                    service-name: ${spring.application.name}
    
  4. 主启动类、controller 和 8004 差不多,编写好后启动
    image-20200710172538978

  5. order模块也一样,这里不再赘述

三个注册中心的异同

组件名 语言 CAP 服务健康检查 对外暴露接口 SpringCloud集成
Eureka Java AP 可配支持 HTTP 已集成
Consul Go CP 支持 HTTP/DNS 已集成
Zookeeper Java CP 支持 客户端 已集成

注:CAP 表示 Consistency、Availability、Partition tolerance,即强一致性、可用性以及分区容错性。

  • AP架构:保证可用性
    在这里插入图片描述
  • CP架构:保证一致性
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/MOKEXFDGH/article/details/107258228