SpringCloud 服务注册与发现

2022-03-17 17:28:57 浏览数 (5)

本篇博客参考学习视频

一、Eureka 服务注册与发现

① Eureka 基础知识

1. 服务治理

​ SpringCloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务治理。 在传统的 RPC 远程调用框架中, 管理每个服务与服务之间依赖关系比较复杂, 所以需要使用服务治理管理服务与服务之间依赖关系, 了以实现服务调用、 负载均衡、容错等, 实现服务发现与注册 。

2. 服务注册
3.Eureka 两组件

② 单机 Eureka 构建步骤

1.IDEA 生成 EurekaServer 端服务注册中心 类似物业公司

建 Module

改 POM

代码语言:javascript复制
<dependencies>
    <!--eureka-server-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    <dependency>
        <groupId>com.atguigu.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>

1.X 和 2.X 的对比说明

写 YML

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

eureka:
  instance:
    hostname: localhost #eureka服务端的实例名称
  client:
    register-with-eureka: false #false表示不向注册中心注册自己。
    fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

主启动

代码语言:javascript复制
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
     public static void main(String[] args) {
           SpringApplication.run(EurekaMain7001.class, args);
      }
}

注意:需要在启动类上配置注解 @EnableEurekaServer,开启注册中心

测试

http://localhost:7001/ ,效果页面

2.EurekaClient 端 cloud-provider-payment8001 将注册进 EurekaServer 成为服务提供者 provider

改 POM ( cloud-provider-payment8001)

代码语言:javascript复制
<!--https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

1.X 和 2.X 的对比说明

写 YML

代码语言:javascript复制
eureka:
  client:
    # 表示是否将自己注册进eurekaServer 默认为 true。
    register-with-eureka: true
    # 是否从EureaServer 抓取已有的注册信息,默认为true.单节点无所谓,集群必须设置true才能配合ribbon使用负载均衡
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:7001/eureka

主启动

代码语言:javascript复制
@EnableEurekaClient
@SpringBootApplication
public class PaymentMain8001 {
     public static void main(String[] args) {
           SpringApplication.run(PaymentMain8001.class, args);
      }
}

添加:注解 @EnableEurekaClient

测试

  • 先启动 EurekaServer http://localhost:7001/
  • 微服务配置说明
  • 自我保护机制
3.EurekaClient 端 cloud-consumer-order80 将注册进 EurekaServer 成为服务消费者 consumer

改 POM

代码语言:javascript复制
<!--https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

写 YML

代码语言:javascript复制
spring:
  application:
    name: cloud-order-service
eureka:
  client:
    register-with-eureka: true
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:7001/eureka

主启动 @EnableEurekaClient

代码语言:javascript复制
@SpringBootApplication
@EnableEurekaClient
public class OrderMain80 {
     public static void main(String[] args) {
           SpringApplication.run(OrderMain80.class, args);
      }
}

测试

  • 先启动 EurekaServer, 7001 服务,在启动服务提供者 provider 8001 服务,在启动消费者 consumer 80
  • http://localhost/consumer/payment/get/1

BUG

③ Eureka 构建步骤

1.Eureka 集群原理说明

**微服务 RPC 远程服务调用最核心的是什么 **

代码语言:javascript复制
高可用

解决办法:搭建 Eureka 注册中心集群,实现负载均衡 故障容错

2.EurekaServer 集群环境构建步骤

新建 cloud-eureka-server7002 和 POM

​ 参考 cloud-eureka-server7001 项目工程

修改映射配置

找到 C:WindowsSystem32driversetc 路径下的 hosts 文件

修改映射配置添加进 hosts 文件

  • 127.0.0.1 eureka7001.com
  • 127.0.0.1 eureka7002.com

写 YML

  • 以前单机
  • 7001
代码语言:javascript复制
server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com #eureka服务端的实例名称
  client:
    register-with-eureka: false #false表示不向注册中心注册自己。
    fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone: http://eureka7002.com:7002/eureka/ #设置与 eureka server 交互的地址查询服务和注册服务都需要依赖这个地址
  • 7002
代码语言:javascript复制
server:
  port: 7002

eureka:
  instance:
    hostname: eureka7002.com #eureka服务端的实例名称
  client:
    register-with-eureka: false #false表示不向注册中心注册自己。
    fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/ #设置与 eureka server 交互的地址查询服务和注册服务都需要依赖这个地址

主启动类 (参考 cloud-eureka-server7001 的主启动类 )

代码语言:javascript复制
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7002 {
     public static void main(String[] args) {
           SpringApplication.run(EurekaMain7002.class, args);
      }
}
3.将支付服务 8001 微服务发布到上面 2 台 Eureka 集群配置中

YML

代码语言:javascript复制
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
4.将订单服务 80 微服务发布到上面 2 台 Eureka 集群配置中

YML

代码语言:javascript复制
eureka:
  client:
    register-with-eureka: true
    fetchRegistry: true
    service-url:
      #      defaultZone: http://localhost:7001/eureka
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版
5.测试 01
  • 先要启动 EurekaServer, 7001/7002 服务,再要启动服务提供者 provider, 8001 服务,再要启动消费者, 80
  • http://localhost/consumer/payment/get/1
6.支付服务提供者 8001 集群环境构建

新建 cloud-provider-payment8002 和 POM

​ 参考 cloud-provider-payment8001

写 YML

代码语言:javascript复制
server:
  port: 8002
spring:
  application:
    name: cloud-payment-service
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    username: root
    password: 6090
mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.oy.springcloud.entities # 所有Entity别名类所在包

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      # 集群版
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

主启动

代码语言:javascript复制
@EnableEurekaClient
@SpringBootApplication
public class PaymentMain8002 {
     public static void main(String[] args) {
           SpringApplication.run(PaymentMain8002.class, args);
      }
}

业务类 直接从 8001 粘贴

修改 8001/8002 的 controller

代码语言:javascript复制
@Value("${server.port}")
private String serverPort;
  • 8001 和 8002
7.负载均衡

Bug: 订单服务访问地址不能写死

原本:(cloud-consumer-order80

更改:

代码语言:javascript复制
public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";

使用@LoadBalanced 注解赋予 RestTemplate 负载均衡的能力 (cloud-consumer-order80

8.测试 02
  • 先要启动 EurekaServer, 7001/7002 服务
  • 再要启动服务提供者 provider, 8001/8002 服务
  • 在启动 consumer 80 服务
  • http://localhost/consumer/payment/get/1 **负载均衡生效, 8001/8002 端口交替出现 **

④ actuator 微服务信息完善

1.主机名称:服务名称修改

修改 YML (cloud-provider-payment8001) 部分

代码语言:javascript复制
instance:
  instance-id: payment8001
2.访问信息有 ip 信息提示

​ 当前问题:没有 ip 提示

修改 cloud-provider-payment8001 YML 部分

代码语言:javascript复制
prefer-ip-address: true

_效果_:

⑤ 服务发现 Discovery

1.对于注册进 eureka 里面的微服务,可以通过服务发现来获取服务的信息
2.修改 cloud-provider-payment8001 的 Controller
代码语言:javascript复制
@Resource
private DiscoveryClient discoveryClient;

@GetMapping(value = "/payment/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.8001 主启动类

@EnableDiscoveryClient

代码语言:javascript复制
@EnableEurekaClient
@EnableDiscoveryClient // 服务发现
@SpringBootApplication
public class PaymentMain8001 {
     public static void main(String[] args) {
           SpringApplication.run(PaymentMain8001.class, args);
      }
}
4.测试
  • 先启动 EurekaServer, 7001/7002 服务,再启动 8001 主启动类,需要稍等一会 http://localhost:8001/payment/discovery

⑥ Eureka 自我保护

1.故障现象
2.导致原因

总结某时刻某一个微服务不可用了,Eureka 不会立即清理,依旧会对该服务的信息进行保存,属于 CAP 里的 AP 分支

3.怎么禁止自我保护(一般生产环境中不会禁止自我保护)

注册中心 eureakeServer 端 7001: 出 厂 默 认 , 自 我 保 护 机 制 是 开 启的:eureka.server.enable-self-preservation = true

  • 使用 eureka.server.enable-self-preservation = false 可以禁用自我保护模式
  • 在 eurekaServer 端 7001 处设置关闭自我保护机制

效果图:

生产者客户端 eureakeClient 端 8001

默认:

代码语言:javascript复制
eureka.instance.lease-renewal-interval-in-seconds=30 单位为秒( 默认是 30 秒)
eureka.instance.lease-expiration-duration-in-seconds=90 单 位 为 秒( 默认是 90 秒)

配置:

代码语言:javascript复制
instance:
  instance-id: payment8001
  prefer-ip-address: true
  #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
  lease-renewal-interval-in-seconds: 1
  #Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
  lease-expiration-duration-in-seconds: 2
4.测试
  • 7001 和 8001 都配置完成
  • 先启动 7001 再启动 8001 ,先关闭 8001 ,马上被删除了

二、Zookeeper 服务注册与发现

① Eukeka 停止更新了怎么办

​ https://github.com/Netflix/eureka/wiki

② SpringCloud 整合 Zookeeper 代替 Eureka

1.注册中心 zookeeper
  • zookeeper 是一个分布式协调工具,可以实现注册中心功能

使用 docker 快速创建 zookeeper 容器

  • 关闭 Linux 服务器防火墙后启动 zookeeper 服务器

CentOS 7 关闭防火墙指令

代码语言:javascript复制
// 查看当前防火墙状态如果防火墙处于开启状态,firewalld.service前面的点是高亮的,Active:active(开启))
systemctl status firewalld.service

//关闭当前的防火墙(仅对本次开机有效,重启后防火墙会再次启用)
systemctl stop firewalld.service

//永久关闭防火墙(重启后防火墙依然关闭)
systemctl disable firewalld.service

// 启动防火墙
 systemctl start firewalld
  • zookeeper 服务器取代 Eureka 服务器,zk 作为服务器注册中心
2.服务提供者

新建 cloud-provider-payment8004

POM

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>clould</artifactId>
        <groupId>com.oy</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-provider-payment8004</artifactId>
    <description>Zookeeper服务提供者</description>

    <dependencies>
        <dependency>
            <groupId>com.oy</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--SpringBoot整合Zookeeper客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</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>

</project>

YML

代码语言:javascript复制
server:
  # 8004表示注册到zookeeper服务器的支付服务提供者端口号
  port: 8004

spring:
  application:
    # 服务别名---注册zookeeper到注册中心的名称
    name: cloud-provider-payment
  cloud:
    zookeeper:
      connect-string: 116.63.177.72:2181

主启动类

代码语言:javascript复制
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;


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

Controller

代码语言:javascript复制
@RestController
@Slf4j
public class PaymentController {

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

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

启动 8004 注册进 zookeeper

注意:启动后问题存在下面问题

Why:

  • 解决 zookeeper 版本 jar 包冲突问题:
  • 排出 zk 冲突后的新 POM:
代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-provider-payment8004</artifactId>
    <description>Zookeeper服务提供者</description>

    <dependencies>
        <!--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.9版本-->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.9</version>
        </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>

</project>

测试

  • 在 Linux 上查询 和 浏览器上(http://localhost:8004/payment/zk )
  • 获得 json 串后用在线工具查看试试 (dokcer 容器) 具体详细的操作参考:https://blog.csdn.net/qq_45738810/article/details/109002435

思考: 服务节点是临时节点还是持久节点——是临时节点

3.服务消费者

新建 cloud-consumerzk-order80

POM

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-consumerzk-order80</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.atguigu.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>
        <!--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.9版本-->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.9</version>
        </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>

</project>

YML

代码语言:javascript复制
server:
  port: 80
spring:
  application:
    # 服务别名
    name: cloud-consumer-order
  cloud:
    zookeeper:
      # 注册到zookeeper地址
      connect-string: localhost:2181

主启动

代码语言:javascript复制
@SpringBootApplication
@EnableDiscoveryClient
public class OrderZkMain80 {
     public static void main(String[] args) {
           SpringApplication.run(OrderZkMain80.class, args);
      }
}

主业务类

  • bean
代码语言:javascript复制
package com.springcloud.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @Author OY
 * @Date 2020/10/10
 */
@Configuration
public class ApplicationContextConfig {

    @Bean
    public RestTemplate restTemplate(){
        return restTemplate();
    }
}
  • controller
代码语言:javascript复制
package com.springcloud.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * @Author OY
 * @Date 2020/10/10
 */

@RestController
@Slf4j
public class OrderZkController {

    @Resource
    private RestTemplate restTemplate;

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

    @GetMapping("/consumer/payment/zk")
    public String paymentInfo() {
        return restTemplate.getForObject(INVOKE_URL   "/payment/zk", String.class);

    }
}

验证测试

访问测试地址

​ http://localhost/consumer/payment/zk

三、Consul 服务注册与发现

① Consul 简介

1.是什么:https://www.consul.io/intro/index.html
2.能干嘛:
  • 服务发现: 提供 HTTP 和 DNS 两种发现方式
  • 健康检查: 支持多种协议,HTTP、TCP、Docker、Shell 脚本定制化
  • KV 存储: Key,Value 的存储方式
  • 多数据中心: Consul 支持多数据中心
  • 可视化 Web 界面
3.下载

https://www.consul.io/downloads.html

4.怎么玩

https://www.springcloud.cc/spring-cloud-consul.html

② 安装并运行 Consul

1.官网安装说明

https://learn.hashicorp.com/consul/getting-started/install.html

2.下载完成后只有一个 consul.exe 文件,硬盘路径下双击运行,查看版本信息
3.使用开发者模式启动
代码语言:javascript复制
consul agent -dev

通过以下地址可以访问 Consul 的首页:http://localhost:8500/

③ 服务提供者

新 建 Module 支 付 服 务 provider8006

cloud-providerconsul-payment8006

POM

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>clould</artifactId>
        <groupId>com.oy</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-providerconsul-payment8006</artifactId>

    <dependencies>
        <!--https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-consul-discovery -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.oy</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

YML

代码语言:javascript复制
server:
  port: 8006
spring:
  application:
    name: consul-provider-payment
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}

主启动类

代码语言:javascript复制
@EnableDiscoveryClient
@SpringBootApplication
public class PaymentMain8006 {
     public static void main(String[] args) {
           SpringApplication.run(PaymentMain8006.class, args);
      }
}

主业务类 Controller

代码语言:javascript复制
@RestController
@Slf4j
public class PaymentController {

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

    @GetMapping(value = "/payment/consul")
    public String paymentConsul(){
        return "SpringCloud with consul:"   serverPort   "t"  UUID.randomUUID().toString();
    }
}

验证测试

​ http://localhost:8006/payment/consul

④ 服务消费者

新 建 Module 消 费 服 务 order8006

​ cloud-consumerconsul-order80

POM

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>clould</artifactId>
        <groupId>com.oy</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-consumerconsul-order80</artifactId>

    <dependencies>
        <!--https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-consul-discovery -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.oy</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope></dependency>
    </dependencies>
</project>

YML

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

spring:
  application:
    name: consul-consumer-order
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}

主启动类

代码语言:javascript复制
package com.oy.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

配置 Bean

代码语言:javascript复制
package com.oy.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ApplicationConfig {

    @LoadBalanced // 负载均衡
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

Controller

代码语言:javascript复制
package com.oy.springcloud.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * @Author OY
 * @Date 2020/10/11
 */
@RestController
@Slf4j
public class OrderConsulController {

    public static final String INVOME_URL = "http://consul-provider-payment";

    @Resource
    public RestTemplate restTemplate;

    @GetMapping("/consumer/payment/consul")
    public String payment(){
        String result = restTemplate.getForObject(INVOME_URL "/payment/consul",String.class );
        return result;
    }
}

验证测试

访问测试地址:http://localhost/consumer/payment/consul

⑤ 三个注册中心异同点

1.CAP
  • C: Consistency (强一致性)
  • A: Availability (可用性)
  • P: Partition tolerance (分区容错)

CAP 理论关注粒度是数据, 而不是整体系统设计的策略

2.经典 CAP 图

AP(Eureka) 架构

当网络分区出现后,为了保证可用性,系统 B可以返回值,保证系统的可用性。

结论:违背了一致性 C 的要求,只满足可用性和分区容错,即 AP

CP(Zookeeper/Consul) 架构

0 人点赞