Day182.分布式注册中心[Eureka、Zookeeper、Consul] -SpringCloud

SpringCloud

五、Eureka服务注册与发现

Eureka基础知识

服务治理

在这里插入图片描述

服务注册

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

Eureka两组件

在这里插入图片描述


单机Eureka构建步骤

IDEA生成eurekaServer端服务注册中心

1. 建module

cloud-eureka-server7001

2. 改pom

server端依赖对比:

在这里插入图片描述

在pom中添加

<dependencies>
    <!-- eureka-server -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    <!--引入自定义的api通用包,可以使用Payment支付bean-->
    <dependency>
        <groupId>com.achang.springcloud</groupId>
        <artifactId>cloud-api-common</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--监控-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!-- 一般通用配置 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
3. 写yml

在resources目录下新建application.yml文件

server:
  port: 7001

eureka:
  instance:
    hostname: localhost #eureka服务端的实例名称
  client:
    #false表示不向注册中心注册自己(想注册也可以,不过没必要)
    register-with-eureka: false
    #false表示自己端就是注册中心,职责就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
      #设置与eurekaServer交互的地址查询服务和注册服务都需要依赖这个地址
      defaultZone: http://${
    
    eureka.instance.hostname}:${
    
    server.port}/eureka/
4. 主启动

在java包下新建com.achang.springcloud.EurekaMain7001

@SpringBootApplication
@EnableEurekaServer //表示此项目是eureka的服务注册中心
public class EurekaMain7001 {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(EurekaMain7001.class,args);
    }
}
5. 测试

启动项目,在浏览器输入http://localhost:7001/

在这里插入图片描述

扫描二维码关注公众号,回复: 12647476 查看本文章

将EurekaClient端8001注册进EurekaServer成为服务提供者provider

client端依赖对比

在这里插入图片描述

  1. 引入依赖

     <!-- eureka-client -->
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
     </dependency>
    
  2. 在yml文件中添加

eureka:
  client:
    #true表示向注册中心注册自己,默认为true
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka

3.在主配置类上加上@EnableEurekaClient注解,表示这个项目是eureka的客户端。

@SpringBootApplication
@EnableEurekaClient
public class PaymentMain8001 {
    
    
    // 主启动类
    public static void main(String[] args) {
    
    
        SpringApplication.run(PaymentMain8001.class,args);
    }
    
}

4.启动项目,然后刷新页面,成功注册进注册中心。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ovh9Vnij-1612353080792)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203113739718.png)]

在yml文件中application.name就是注册进注册中心时的应用名。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-87KZOLm1-1612353080797)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203113812896.png)]


将EurekaClient端80注册进EurekaServer成为服务消费者consumer

1、引入依赖

 <!-- eureka-client -->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>

2、在yml文件中添加

spring:
  application:
    name: cloud-order-service

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka

3、在主配置类上加上@EnableEurekaClient注解。

@SpringBootApplication
@EnableEurekaClient
public class OrderMain80 {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(OrderMain80.class,args);
    }
}

4、启动项目,刷新页面

启动7001-8001-80

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pPlHxh5e-1612353080803)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203121050694.png)]

http://localhost/consumer/payment/add?serial=%E5%88%98%E9%A3%9E

http://localhost/consumer/payment/get/1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QxFLojaC-1612353080807)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203121433004.png)]


集群Eureka构建步骤

原理说明

在这里插入图片描述
搭建Eureka注册中心集群,实现负载均衡+故障容错。

Eureka集群:相互注册,相互守望
在这里插入图片描述


构建eurekaServer集群环境

1、参照cloud-eureka-server7001新建cloud-eureka-server7002和cloud-eureka-server7003。

2、Windows系统的兄弟就跟着老师修改hosts文件,C:\Windows\System32\drivers\etc

在最后一行加入:保存退出

127.0.0.1       eureka7001.com
127.0.0.1       eureka7002.com
127.0.0.1       eureka7003.com

3、修改7001的yml文件

server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com  #eureka服务端的实例名称
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
#      单机
#      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

      #集群版  相互注册,相互守望
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ 
      
#    defaultZone是固定写法,如果想自定义,需要按以下写法才行:
#    region: eureka-server
#    availability-zones:
#      eureka-server: server1,server2
#    service-url:
#      server1: http://eureka7002.com:7002/eureka/
#      server2: http://eureka7003.com:7003/eureka/

4、修改7002的yml文件

server:
  port: 7002

eureka:
  instance:
    hostname: eureka7002.com  #eureka服务端的实例名称
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      #集群版  相互注册,相互守望
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/ #相互注册,相互守望

5、修改7003的yml文件

server:
  port: 7003

eureka:
  instance:
    hostname: eureka7003.com  #eureka服务端的实例名称
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      #集群版  相互注册,相互守望
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ #相互注册,相互守望

6、然后启动这三个项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cVmWsA9A-1612353080810)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203130158610.png)]

通过域名逐个测试访问:

http://eureka7001.com:7001/
http://eureka7002.com:7002/
http://eureka7003.com:7003/

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


将支付服务8001和订单服务80微服务发布到集群配置中

把两个项目的yml文件中的defaultZone改为:

      #集群版
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka

启动5个项目进行测试:(先启动集群,再启动8001,最后启动80)
集群后台截图:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


构建支付服务提供者集群环境

  1. 按照8001新建8002(只多建了一个提供者,建多了怕电脑受不了)。(除了要yml文件中需要改端口号和主配置类,其他直接复制8001的,yml文件中的应用名不需要改,因为是集群,所以应用名需要一致)
  2. 分别在所有的提供者的PaymentController中加入:(这个@Value是spring的注解

在这里插入图片描述

@RestController
@Slf4j //日志
public class PaymentController {
    
    

    @Resource
    private PaymentService paymentService;

    @Value("${server.port}")
    private String serverPort;

    //前后端分离,所以不能直接返回对象,数据要先经过CommonResult封装再返回
    @PostMapping(value = "/payment/add")
    public CommonResult add(@RequestBody Payment payment){
    
    
        int result = paymentService.add(payment);
        log.info("-----插入结果----: "+ result);

        if (result > 0){
    
    
            //插入成功
            return new CommonResult(200,"插入数据库成功 serverPort="+serverPort,result);
        }else {
    
    
            return new CommonResult(444,"插入数据库失败 serverPort="+serverPort,null);
        }
    }


    @GetMapping(value = "/payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id")Long id){
    
    
        Payment result = paymentService.getPaymentById(id);
        log.info("-----查询结果----: "+ result);
        if (result != null){
    
    
            //查询成功
            return new CommonResult(200,"查询成功 serverPort="+serverPort,result);
        }else {
    
    
            return new CommonResult(444,"没有对应记录,查询id: "+id+" ,serverPort="+serverPort,null);
        }
    }

}

3、修改消费者的OrderController,把写死的url改为服务名称:

public static final String PAYMENT_URL ="http://CLOUD-PAYMENT-SERVICE";
@RestController
@Slf4j
public class OrderController {
    
    

//    public static final String PAYMENT_URL ="http://localhost:8001";
    public static final String PAYMENT_URL ="http://CLOUD-PAYMENT-SERVICE";

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/payment/add")
    public CommonResult<Payment> add(Payment payment){
    
    
        log.info("********插入的数据:" + payment);
        return restTemplate.postForObject(PAYMENT_URL+"/payment/add",payment,CommonResult.class);
    }

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id")Long id){
    
    
        log.info("********查询的id:" + id);
        return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    }
}

4、然后在消费者的ApplicationContextConfig里的restTemplate方法上加上@LoadBalanced,开启负载均衡功能。

@Configuration
public class ApplicationContextConfig {
    
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
    
    
        return new RestTemplate();
    }
    
}

注:不加@LoadBalanced,80不知道要去调用哪个CLOUD-PAYMENT-SERVICE,没有一种默认的机制,通过这个注解,给他一个默认的机制


5、启动eurekaServer集群,启动提供者集群,启动消费者。
如果启动提供者后出现,这个错误:Public Key Retrieval is not allowed
请在yml文件中的datasource.datasource.url后加上&allowPublicKeyRetrieval=true即可解决。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GaQbRMkl-1612353080812)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203134202229.png)]

另外两个eurekaserver也一样,就不截图。
在浏览器中输入http://localhost/consumer/payment/get/1,多次刷新可以看到,提供服务的应用在不同的切换,实现负载均衡的效果。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mRXi96p0-1612353080814)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203140126691.png)]

自动实现的切换端口,负载均衡


actuator微服务信息完善

修改三个微服务的yml文件:

#######8001#######
# client:	
#	 ...	instance要和client对齐
  instance:
    instance-id: payment8001  # 修改显示的主机名
    prefer-ip-address: true   # 访问路径可以显示ip地址

#######8002#######
  instance:
    instance-id: payment8002  # 修改显示的主机名
    prefer-ip-address: true   # 访问路径可以显示ip地址
    
#######80#######
  instance:
    instance-id: consumer80   # 修改显示的主机名
    prefer-ip-address: true   # 访问路径可以显示ip地址

修改前:

在这里插入图片描述

修改后:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kP42DobH-1612353080815)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203141528691.png)]


服务发现Discovery

对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息。

修改提供者集群的controller

1、在主配置类上加上@EnableDiscoveryClient注解,启用发现客户端。

@SpringBootApplication
@EnableEurekaClient
=========================
@EnableDiscoveryClient
=========================
public class PaymentMain8001 {
    
    
    // 主启动类
    public static void main(String[] args) {
    
    
        SpringApplication.run(PaymentMain8001.class,args);
    }

}

2、在两个提供者的PaymentController中加入:

@RestController
@Slf4j //日志
public class PaymentController {
    
    

===================================================
    //springframework的DiscoveryClient(不要导错包了)
    @Resource
    private DiscoveryClient discoveryClient;
==================================================
    

    @GetMapping(value = "/payment/discovery")
    public Object discovery(){
    
    
        //遍历具体注册的微服务
        List<String> services = discoveryClient.getServices();
        for (String service:services){
    
    
            log.info("**********service****: "+service);
        }

        //获取具体 CLOUD-PAYMENT-SERVICE 微服务的具体实例
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        
        //getServiceId服务器id getHost主机名称 getPort端口号  getUri地址
        for (ServiceInstance s:instances){
    
    
            log.info(s.getServiceId()+"\t"+s.getHost()+"\t"+s.getPort()+"\t"+s.getUri());
        }
        return this.discoveryClient;
    }

}

测试

对8001进行测试
,在浏览器输入:http://localhost:8001/payment/discovery

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TVky1RD6-1612353080817)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203144158561.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qJ37MKQg-1612353080818)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203144408085.png)]

左边:具体注册的微服务

右边:具体某个微服务的具体实例


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lUKLfBjE-1612353080820)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203144541455.png)]


Eureka自我保护

概述

在这里插入图片描述

导致原因

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
只有在一定时间内丢失大量服务的心跳才开启自我保护模式。


禁止自我保护

先把cloud-eureka-server7001和cloud-provider-payment8001都切回单机版测试禁止自我保护。

cloud-eureka-server7001的yml文件:

server:
  port: 7001
  
eureka:
  instance:
    hostname: eureka7001.com  #eureka服务端的实例名称
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      #单机
     defaultZone: http://${
    
    eureka.instance.hostname}:${
    
    server.port}/eureka/

      #集群版  相互注册,相互守望
#      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

  server:
    #关闭自我保护,默认为true
    enable-self-preservation: false
    #心跳的间隔时间,单位毫秒
    eviction-interval-timer-in-ms: 2000

cloud-provider-payment8001的yml文件:

eureka:
  instance:
    #Eureka客户端向服务端发送心跳的时间间隔,单位秒(默认30秒)
    lease-renewal-interval-in-seconds: 1
    #Eureka服务端在收到最后一次心跳后等待的时间上限,单位秒(默认90秒),超时剔除服务
    lease-expiration-duration-in-seconds: 2

启动注册中心和提供者:

在这里插入图片描述

然后关闭提供者(模拟网络延时),提供者直接被剔除。

在这里插入图片描述


六、Zookeeper服务注册与发现

注册中心Zookeeper

在这里插入图片描述

关闭linux的防火墙:

systemctl stop firewalld
systemctl status firewalld

在这里插入图片描述

进入到zookeeper的bin目录下启动zkServer.sh

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WY0jlSfw-1612353080821)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203160432500.png)]


或者通过docker来启动zookeeper

#拉取Zookeeper镜像
docker pull zookeeper

#启动Zookeeper
docker run --name zk01 -p 2181:2181 --restart always -d zookeeper

服务节点是临时节点还是持久节点?

zookeeper也是有心跳机制,在一定时间能如果一直没心跳返回,Zookeeper就会把服务节点剔除掉。所以在Zookeeper上的服务节点是临时节点。

服务提供者

为了区分,中间空个8003。

1、新建工程cloud-provider-payment8004

2、pom

<!--因为接下来不会用到数据库,所以不导入数据库相关的依赖(防止没配置而报错)-->

        <!--替换掉eureka依赖,其他直接复制8001-->
        <!--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.4.10版本(引入对应版本的依赖)-->
                <dependency>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                    <version>3.4.10</version>
                    <exclusions>
                        <exclusion>
                            <groupId>org.slf4j</groupId>
                            <artifactId>slf4j-log4j12</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>

3、yml

#端口号
server:
  port: 8004


spring:
  application:
    #服务别名——注册到zookeeper注册中心的名称
    name: cloud-provider-payment
  cloud:
    zookeeper:
      connect-string: 192.168.109.101:2181 #linux的ip加暴露的端口号

4、主启动类

@EnableDiscoveryClient	//该注解用于向使用consul或者Zookeeper作为注册中心时注册服务
@SpringBootApplication
public class PaymentMain8004 {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(PaymentMain8004.class, args);
    }
}

5、controller
新建controller.PaymentController

@Slf4j
@RestController
public class PaymentController {
    
    

    @Value("${server.port}")        //获取端口号
    private String serverPort;

    @RequestMapping("/payment/zk")
    public String paymentzk(){
    
    
        return "springcloud with zookeeper:" + serverPort + "\t" + UUID.randomUUID().toString();
    }

}
12345678910111213

6、Zookeeper容器-------【docker的方式】
默认已经帮我们启动了服务端和客户端,如果想进去容器的话,使用下面的命令。

#查看正在运行的容器(查看Zookeeper容器的id)
docker ps

#进入zookeeper容器
docker exec -it 容器ID /bin/bash

#退出容器(或者按快捷键ctrl+P+Q退出)
exit
#启动容器
docker start 容器ID
#关闭容器
docker stop 容器ID

方式跟上面一样,进入到bin目录,通过./zkServer.sh start启动每台的zookeeper服务,然后通过./zkCli.sh来启动客户端

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uba0q1Pu-1612353080823)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203174520946.png)]


7、启动8004项目,浏览器输入http://localhost:8004/payment/zk

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FqsNRUgG-1612353080824)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210203165646198.png)]

8、进入Zookeeper容器(成功注册进注册中心)
在这里插入图片描述
在这里插入图片描述
https://tool.lu/json/
在这里插入图片描述


服务消费者

  1. 新建消费者模块cloud-consumerzk-order80。

  2. pom和yml直接复制8004。(yml中端口号改为80,应用名改为cloud-consumer-order,其他都相同)

  3. 主启动类。(与8004相同)

    @SpringBootApplication
    @EnableDiscoveryClient
    public class OrderZKMain80 {
          
          
        public static void main(String[] args) {
          
          
            SpringApplication.run(OrderZKMain80.class,args);
        }
    }
    
  4. 在springcloud包下新建config.ApplicationContextConfig

    @Configuration
    public class ApplicationContextConfig {
          
          
        @Bean
        @LoadBalanced //负载均衡
        public RestTemplate getRestTemplate(){
          
          
            return new RestTemplate();
        }
    
    }
    
  5. 新建controller.OrderZKController

    @RestController
    @Slf4j
    public class ZKController {
          
          
        public static final String INVOKE_URL="http://cloud-provider-payment";
    
        @Resource
        private RestTemplate restTemplate;
    
        @GetMapping("/consumer/payment/zk")
        public String paymentInfo(){
          
          
            String result = restTemplate.getForObject(INVOKE_URL + "/payment/zk", String.class);
            return result;
        }
    
    }
    
  6. 启动项目
    在这里插入图片描述
    http://localhost/consumer/payment/zk
    在这里插入图片描述


七、Consul服务注册与发现

Consul官网:https://www.consul.io/
Consul中文文档:https://www.springcloud.cc/spring-cloud-consul.html

简介

Consul是一种服务网格解决方案,提供具有服务发现,配置和分段功能的全功能控制平面。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建完整的服务网格。Consul需要一个数据平面,并支持代理和本机集成模型。Consul附带了一个简单的内置代理,因此一切都可以直接使用,还支持Envoy等第三方代理集成。
在这里插入图片描述

主要特点

  • 服务发现:Consul的客户端可以注册服务,例如 api或mysql,其他客户端可以使用Consul来发现给定服务的提供者。使用DNS或HTTP,应用程序可以轻松找到它们依赖的服务。
  • 健康检测:领事客户端可以提供任意数量的运行状况检查,这些检查可以与给定服务(“ Web服务器是否返回200 OK”)或本地节点(“内存利用率低于90%”)相关。操作员可以使用此信息来监视群集的运行状况,服务发现组件可以使用此信息将流量从不正常的主机发送出去。
  • KV存储:应用程序可以将Consul的分层键/值存储用于多种目的,包括动态配置,功能标记,协调,领导者选举等。简单的HTTP API使其易于使用。
  • 安全的服务通信:领事可以为服务生成并分发TLS证书,以建立相互TLS连接。 意图 可用于定义允许哪些服务进行通信。可以使用可以实时更改的意图轻松管理服务分段,而不必使用复杂的网络拓扑和静态防火墙规则。
  • 多数据中心:Consul开箱即用地支持多个数据中心。这意味着Consul的用户不必担心会构建其他抽象层以扩展到多个区域。

Consul旨在对DevOps社区和应用程序开发人员友好,使其非常适合现代,灵活的基础架构。

在docker上安装启动consul

#拉取consul镜像
docker pull consul

#启动consul
docker run -d  -p 8500:8500/tcp --name myConsul  consul agent -server -ui -bootstrap-expect=1 -client=0.0.0.0

然后在浏览器输入ttp://30.211.53.17/:8500(linux的IP地址加上冒号8500)

在这里插入图片描述


服务提供者

1、新建服务提供者cloud-provider-consul-payment8006。
2、pom复制8004。(用下面的依赖替换Zookeeper的依赖)

 <!--SpringCloud consul-server-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-consul-discovery</artifactId>
  </dependency>

3、yml

# consul服务端口号
server:
  port: 8005

spring:
  application:
    name: consul-provider-payment

  cloud:
    # consul注册地址
    consul:
      host: 47.110.247.184 #用linux的ip地址(consul在本机就填localhost)
      port: 8500
      discovery:
        service-name: ${
    
    spring.application.name}
        
        # 出掉去前端页面查看时爆红叉
        heartbeat:
         enabled: true 

4、主启动类(与8004相同)

@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain8005 {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(PaymentMain8005.class,args);
    }
}

5、controller

@RestController
@Slf4j
public class PaymentController {
    
    
 @Value("${server.port}")        //获取端口号
 private String serverPort;

 @RequestMapping("/payment/consul")
 public String paymentConsul(){
    
    
     return "springcloud with zookeeper:" + serverPort + "\t" + UUID.randomUUID().toString();
 }

}

6、启动项目
在这里插入图片描述
http://localhost:8005/payment/consul
在这里插入图片描述


服务消费者

  1. 新建模块cloud-consumer-consul-order80

  2. pom(与8006相同)

    <dependencies>
        <!--SpringCloud consul-server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
    
        <!--引入自定义的api通用包,可以使用Payment支付bean-->
        <dependency>
            <groupId>com.achang.springcloud</groupId>
            <artifactId>cloud-api-common</artifactId>
            <version>${project.version}</version>
    
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- 一般通用配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    
    </dependencies>
    
  3. yml(端口号为80,应用名为consul-consumer-order,其他和8006相同)

    server:
      port: 80
    
    spring:
      application:
        name: cloud-consuml-order
    
      cloud:
        # consul注册地址
        consul:
          host: 47.110.247.184
          port: 8500
          discovery:
            service-name: ${
          
          spring.application.name}
            # 出掉去前端页面查看时爆红叉
            heartbeat:
              enabled: true
    
  4. 主启动类(与8006相同)

    @SpringBootApplication
    @EnableDiscoveryClient
    public class OrderConsulMain80 {
          
          
        public static void main(String[] args) {
          
          
            SpringApplication.run(OrderConsulMain80.class,args);
        }
    }
    
  5. config(和zk的消费者相同)

    @Configuration
    public class ApplicationContextConfig {
          
          
        @Bean
        @LoadBalanced
        public RestTemplate getRestTemplate(){
          
          
            return new RestTemplate();
        }
        
    }
    
  6. controller.OrderConsulController

    @RestController
    @Slf4j
    public class OrderController {
          
          
        public static final String INVOKE_URL="http://consul-provider-payment";
        @Resource
        RestTemplate restTemplate;
    
        @GetMapping(value = "/consumer/payment/consul")
        public String paymentInfo(){
          
          
            String result = restTemplate.getForObject(INVOKE_URL+"/payment/consul",String.class);
            return result;
        }
    
    }
    
  7. 启动项目
    在这里插入图片描述
    http://localhost/consumer/payment/consul
    在这里插入图片描述


三者的异同点

在这里插入图片描述

CAP:(只能二选一)
A:可用性
C:一致性
P:分区容错性(微服务架构必须保证有P)

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


感谢尚硅谷
https://www.bilibili.com/video/BV18E411x7eT?p=36&spm_id_from=pageDriver
P15-P35内容

猜你喜欢

转载自blog.csdn.net/qq_43284469/article/details/113618322
今日推荐