java学习之springcloud之服务注册与发现篇

尚硅谷springcloud学习笔记

  • 1.springcloud简介与学习版本
  • 2.微服务架构编码构建(初体验)
    • 2.1搭建一个微服务整体聚合父工程Project
    • 2.2支付模块cloud-provider-payment8001
    • 2.3消费者模块cloud-consumer-order-80(操作支付模块)
      • 2.3.1RestTemplate
    • 2.4提取两个模块的公共实体类entity
  • 3.Eureka服务注册与发现(已停更,了解一下)
    • 3.1基础知识
    • 3.2单机Eureka:cloud-eureka-server7001构建步骤
    • 3.3支付微服务8001与消费者80入驻进EurekaServer
    • 3.4搭建Eureka集群
    • 3.5将订单与支付模块注册进Eureka集群
    • 3.6支付微服务提供者8001的集群配置
    • 3.7微服务信息完善
    • 3.8服务发现Discovery
    • 3.9Eureka的自我保护机制与关闭
  • 4.zookeeper服务注册与发现
  • 5.Consul服务注册与发现
    • 5.1新建支付服务提供者8006注册进consul
    • 5.2新建服务消费者80注册进consul
  • 6.三个注册中心的异同点

参考资料:
尚硅谷springcloud教程

springcloud文档:https://cloud.spring.io/spring-cloud-static/Hoxton.SR1/reference/htmlsingle/
springboot文档:https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/htmlsingle/

1.springcloud简介与学习版本

springcloud=分布式微服务架构的一站式解决方案,是多重微服务架构落地技术的集合体,俗称微服务全家桶

springcloud所包含的技术
java学习之springcloud之服务注册与发现篇_第1张图片
下面就是我们需要掌握的技术
在这里插入图片描述
下面是学习课程是的版本选型

springboot:2.x版本,springcloud H版
下面这张图是springcloud和springboot版本号的对应

java学习之springcloud之服务注册与发现篇_第2张图片
java学习之springcloud之服务注册与发现篇_第3张图片
最终学习选择的版本:
注意:springcloud版本决定springboot版本,看可以在springcloud官网查看对应版本所推荐的springboot版本,我使用的idea是2022版本的
java学习之springcloud之服务注册与发现篇_第4张图片
查看springcloud推荐的springboot版本的方式:
java学习之springcloud之服务注册与发现篇_第5张图片
java学习之springcloud之服务注册与发现篇_第6张图片
下面是本次课程中所要学的一些技术(主要是打勾的)
java学习之springcloud之服务注册与发现篇_第7张图片

2.微服务架构编码构建(初体验)

2.1搭建一个微服务整体聚合父工程Project

a)创建一个父maven工程
java学习之springcloud之服务注册与发现篇_第8张图片
修改好字符编码
java学习之springcloud之服务注册与发现篇_第9张图片
b)父工程的pom.xml文件

DependencyManagementDependencies的区别:前者一般用于父工程,使用pom.xml 中的dependencyManagement 元素能让所有在子项目中引用一个依赖而不用显式的列出版本号
Maven 会沿着父子层次向上走,直到找到一个拥有dependencyManagement 元素的项目,然后它就会使用这个
注意:DependencyManagement只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖(报错的话把他去掉刷新一下maven引入依赖后再加上即可)
只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom
如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。



<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">
  <modelVersion>4.0.0modelVersion>

  <groupId>com.javalearn.springcloudgroupId>
  <artifactId>springcloudLearnartifactId>
  <version>1.0-SNAPSHOTversion>
  
  <packaging>pompackaging>

  
  <properties>
    <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    <maven.compiler.source>1.8maven.compiler.source>
    <maven.compiler.target>1.8maven.compiler.target>
    <junit.version>4.12junit.version>
    <log4j.version>1.2.17log4j.version>
    <lombok.version>1.16.18lombok.version>
    <mysql.version>8.0.27mysql.version>
    <druid.version>1.1.16druid.version>
    <mybatis.spring.boot.version>1.3.0mybatis.spring.boot.version>
  properties>

  
  <dependencyManagement>
    <dependencies>
      
      <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-dependenciesartifactId>
        <version>2.2.2.RELEASEversion>
        <type>pomtype>
        <scope>importscope>
      dependency>
      
      <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-dependenciesartifactId>
        <version>Hoxton.SR1version>
        <type>pomtype>
        <scope>importscope>
      dependency>
      
      <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-alibaba-dependenciesartifactId>
        <version>2.1.0.RELEASEversion>
        <type>pomtype>
        <scope>importscope>
      dependency>
      <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
        <version>${mysql.version}version>
      dependency>
      <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>druidartifactId>
        <version>${druid.version}version>
      dependency>
      <dependency>
        <groupId>org.mybatis.spring.bootgroupId>
        <artifactId>mybatis-spring-boot-starterartifactId>
        <version>${mybatis.spring.boot.version}version>
      dependency>
      <dependency>
        <groupId>junitgroupId>
        <artifactId>junitartifactId>
        <version>${junit.version}version>
      dependency>
      <dependency>
        <groupId>log4jgroupId>
        <artifactId>log4jartifactId>
        <version>${log4j.version}version>
      dependency>
      <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
        <version>${lombok.version}version>
        <optional>trueoptional>
      dependency>
    dependencies>
  dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-maven-pluginartifactId>
        <configuration>
          <fork>truefork>
          <addResources>trueaddResources>
        configuration>
      plugin>
    plugins>
  build>

project>

2.2支付模块cloud-provider-payment8001

1、建模块
在我们原来的父工程下新建一个模块
java学习之springcloud之服务注册与发现篇_第10张图片
查看父工程的pom,我们发现多出了一个模块
java学习之springcloud之服务注册与发现篇_第11张图片

2、改pom
引入依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
        dependency>
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druid-spring-boot-starterartifactId>
            <version>1.1.10version>
        dependency>
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-jdbcartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>

3、改yml
在resources文件夹中创建一个application.yml文件

server:
  port: 8001

spring:
  application:
    name: cloud-payment-service
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driver-class-name: com.mysql.cj.jdbc.Driver              # mysql驱动包
    url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 


mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.javalearn.springcloud.entities    # 所有Entity别名类所在包

4、主启动
即springboot的主启动类,我们在springboot中已经学习过了
java学习之springcloud之服务注册与发现篇_第12张图片

5、业务类

vue->controller->service->dao->mysql

a)建表sql
java学习之springcloud之服务注册与发现篇_第13张图片

b)创建实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Payment implements Serializable {
    private long id;
    private String serial;
}

下面是返回给前端的实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonResult <T>{
    private Integer code;//状态码
    private String message;
    private T data;
    
    public CommonResult(Integer code,String message){
        this(code,message,null);
    }
}

c)dao(Mapper)

@Mapper
public interface PaymentDao {
    public int create(Payment payment);

    public Payment getPaymentById(@Param("id")Long id);
}

同时创建他的映射文件
在这里插入图片描述


DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.javalearn.springcloud.dao.PaymentDao">
    
    <insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
        insert into payment (serial) values (#{serial})
    insert>
    
    <resultMap id="BaseResultMap" type="Payment">
        <id column="id" property="id" jdbcType="BIGINT"/>
        <id column="serial" property="serial" jdbcType="VARCHAR"/>
    resultMap>
    
    
    <select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">
        select * from payment where id=#{id}
    select>
mapper>

d)service

public interface PaymentService {
    public int create(Payment payment);

    public Payment getPaymentById(@Param("id")Long id);
}

以及他的实现类

@Service
public class PaymentServiceImpl implements PaymentService {
    
    @Resource
    PaymentDao paymentDao;

    @Override
    public int create(Payment payment) {
        return paymentDao.create(payment);
    }

    @Override
    public Payment getPaymentById(Long id) {
        return paymentDao.getPaymentById(id);
    }
}

e)controller

@Slf4j
@RestController
public class PaymentController {
    @Resource
    private PaymentService paymentService;

    @PostMapping("/payment/create")
    public CommonResult createPayment(Payment payment){
        int result = paymentService.create(payment);
        log.info("****插入结果"+result);

        //返回给前端的数据
        if (result>0){
            return new CommonResult(200,"插入数据苦成功",result);
        }else{
            return new CommonResult(444,"插入数据库失败",null);
        }
    }

    @GetMapping ("/payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id") Long id){
        Payment payment = paymentService.getPaymentById(id);

        if (payment!=null){
            return new CommonResult(200,"查询成功",payment);
        }else{
            return new CommonResult(444,"查询失败,查询id:"+id,null);
        }
    }
}

六、测试
经过测试,由于我的idea版本过高,所以用周阳老师的lombok版本会报错,修改了一下版本

    <lombok.version>1.18.20lombok.version>

java学习之springcloud之服务注册与发现篇_第14张图片
测试查询的时候,由于需要post请求,所以这里使用postman,结果插入成功
java学习之springcloud之服务注册与发现篇_第15张图片
总结:业务模块的步骤
1.建module
2.改pom
3.写yml
4.写run
5.写业务

2.3消费者模块cloud-consumer-order-80(操作支付模块)

1、建模块
java学习之springcloud之服务注册与发现篇_第16张图片
2、改pom

 <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>

3、写yml
使用8080端口

server:
  port: 80

4、主启动
在这里插入图片描述

5、写业务

我们使用消费者模块来操作我们刚刚写的支付模块,所以只需要有controller即可

消费者模块也需要用到Payment的实体类,所以我们先复制一份实体类
java学习之springcloud之服务注册与发现篇_第17张图片

2.3.1RestTemplate

接下来写我们的controller类,去调用我们之前写的支付模块,这里就要使用RestTemplate了:是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集

官网:https://docs.spring.io/spring-framework/docs/5.2.2.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html

使用
使用restTemplate访问restful接口非常的简单粗暴无脑。
(url, requestMap, ResponseBean.class)这三个参数分别代表
REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。

a)配置类,注入RestTemplate

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

b)controller

@Slf4j
@RestController
public class OrderController {
    public static final String PAYMENT_URL = "http://localhost:8001";//这个是我们需要转发到的端口
    @Resource
    private RestTemplate restTemplate;
    
    @GetMapping("/consumer/payment/create")
    public CommonResult<Payment> create(Payment payment){
        //调用restTemplate的这个方法
        return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class);
    }

    @GetMapping("/consumer/payment/get/{id}")
    public  CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
        return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    }
}

接下来分别启动80和8001的主启动类,进行测试,启动后idea会弹出一个选项,勾选使用
java学习之springcloud之服务注册与发现篇_第18张图片
这样我们就可以方便的看每一个服务了
java学习之springcloud之服务注册与发现篇_第19张图片
经过测试,我们可以使用consumer模块调用payment模块的查询方法
java学习之springcloud之服务注册与发现篇_第20张图片
但是当我们要调用增加方法时,由于我们的consumer传递给payment模块的是一个json数据,所以我们需要增加一个@RequestBody注解用于接受json字符串,所以要修改8001的代码
java学习之springcloud之服务注册与发现篇_第21张图片

2.4提取两个模块的公共实体类entity

在我们的8001和80两个模块中,他们有重复部分,也就是entities实体类,这就会造成代码的冗余,那么接下来我们就要抽取公共部分了。

还是通过maven抽取,通过新建一个cloud-api-commons模块来抽取

1、建模块(不演示了)

2、改pom

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>cn.hutoolgroupId>
            <artifactId>hutool-allartifactId>
            <version>5.1.0version>
        dependency>
    dependencies>

3、复制前两个工程的实体类
java学习之springcloud之服务注册与发现篇_第22张图片

4、使用maven命令:clean->install

5、删除原来模块中的entities内容,并引入这个自己定义的jar包

        <dependency>
            <groupId>com.javalearn.springcloudgroupId>
            <artifactId>cloud-api-commonsartifactId>
            <version>${project.version}version>
        dependency>

到这里,我们的基础构件入门就完成了

3.Eureka服务注册与发现(已停更,了解一下)

3.1基础知识

虽然Eureka目前已经停止更新,但是许多老项目还是在使用的,我们需要先来了解下面的一些概念

1、服务治理

在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册

2、服务注册与发现
Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行下图是工作原理。

java学习之springcloud之服务注册与发现篇_第23张图片
其包括两个组件:
Eureka Server提供服务注册服务: 各个微服务节点通过配置启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。
EurekaClient通过注册中心进行访问: 是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)

3.2单机Eureka:cloud-eureka-server7001构建步骤

1、建立一个module:cloud-eureka-server7001

2、改pom

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
        dependency>
        
        <dependency>
            <groupId>com.javalearn.springcloudgroupId>
            <artifactId>cloud-api-commonsartifactId>
            <version>${project.version}version>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
        dependency>
    dependencies>

3、写yml

server:
  port: 7001

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

4、创建springboot主启动类
java学习之springcloud之服务注册与发现篇_第24张图片
5、测试
运行主启动类,在浏览器中输入对应网址,进入成功
java学习之springcloud之服务注册与发现篇_第25张图片

3.3支付微服务8001与消费者80入驻进EurekaServer

修改8001模块

1、改pom
注意这里引入的是client,而7001注册中心是sever

        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>

2、写yml

eureka:
  client:
    #表示是否将自己注册进EurekaServer默认为true。
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetchRegistry: true
    service-url:
      #入驻哪个主机的哪个端口
      defaultZone: http://localhost:7001/eureka

3、主启动
java学习之springcloud之服务注册与发现篇_第26张图片
4、测试
a)注意要先启动7001注册中心

b)如果启动报错
修改一下client依赖

        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
            
            <exclusions>
                <exclusion>
                    <groupId>com.sun.jerseygroupId>
                    <artifactId>jersey-clientartifactId>
                exclusion>
                <exclusion>
                    <groupId>com.sun.jerseygroupId>
                    <artifactId>jersey-coreartifactId>
                exclusion>
                <exclusion>
                    <groupId>com.sun.jersey.contribsgroupId>
                    <artifactId>jersey-apache-client4artifactId>
                exclusion>
            exclusions>
        dependency>

c)刷新Eureka界面,发现服务已经注册进来了
在这里插入图片描述
d)发现微服务注册到名称与我们yml文件中的一致
java学习之springcloud之服务注册与发现篇_第27张图片

5、消费者模块80也是一样的流程,直接到测试环节
a)先启动7001,和8001,然后启动80

b)发现80也被注册成功了
在这里插入图片描述

c)到现在为止的工作原理
java学习之springcloud之服务注册与发现篇_第28张图片

3.4搭建Eureka集群

1、集群原理
如果说注册中心只有一台,那么如果他除了故障,整个服务环境就不可用了,所以我们需要搭建集群,下图是到目前为止的工作原理,来保证高可用
集群原理:相互注册,相互守望,并且对外暴露出一个整体,下面是搭建的步骤
java学习之springcloud之服务注册与发现篇_第29张图片
2、建module,参考7001创建cloud-eureka-server7002

3、改pom

   <dependencies>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
        dependency>
        
        <dependency>
            <groupId>com.javalearn.springcloudgroupId>
            <artifactId>cloud-api-commonsartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
        dependency>
        
        <dependency>
            <groupId>com.thoughtworks.xstreamgroupId>
            <artifactId>xstreamartifactId>
            <version>1.4.15version>
        dependency>
    dependencies>

4、修改映射配置
找到C:\Windows\System32\drivers\etc路径下的hosts文件
修改映射配置添加进hosts文件,添加如下内容,方便区分两台sever
在这里插入图片描述

5、写yml
先改7001
java学习之springcloud之服务注册与发现篇_第30张图片

再写7002
java学习之springcloud之服务注册与发现篇_第31张图片

6、创建7002的主启动类,与7001一样,别忘了加注解

7、测试,分别运行7001和7002的主启动类,启动服务
1、经过测试,曾经的localhost还可以访问到Eureka主页

2、访问域名,我们发现1指着2,2指着1,自此集群搭建成功
java学习之springcloud之服务注册与发现篇_第32张图片
java学习之springcloud之服务注册与发现篇_第33张图片

3.5将订单与支付模块注册进Eureka集群

1、注册8001,修改yml
java学习之springcloud之服务注册与发现篇_第34张图片
2、注册80,修改yml
java学习之springcloud之服务注册与发现篇_第35张图片
3、测试
1、启动7001和7002集群,然后启动服务提供者8001,最后启动80

3.6支付微服务提供者8001的集群配置

我们工程目前的架构图是80是消费者,8001是服务的提供者,为了保持高可用,我们微服务的提供者也需要进行集群配置

1、参考8001新建8002

2、改pom
直接复制8001的即可

3、写yml
复制粘贴8001的yml,修改端口为8002即可,此时8001和8002对外暴露的服务名其实是一样的
java学习之springcloud之服务注册与发现篇_第36张图片

4、主启动

5、业务类
也是直接从8001粘贴

6、修改8001和8002的ontroller(重点)
以8001为例,8002也是一样的修改,获取端口号,来获取是哪台服务器执行的请求
java学习之springcloud之服务注册与发现篇_第37张图片
7、测试
启动顺序:7001-7002-8001-8002-80
观察Eureka界面,我们发现支付服务有两台服务器了
java学习之springcloud之服务注册与发现篇_第38张图片
8、修改80的controller

在之前的项目中,我们的80是使用了RestTemplate,所以请求只会转发给8001,达不到集群的效果,所以我们需要修改。

a)在原先的配置类中,使用 @LoadBalanced注解赋予RestTemplate负载均衡能力
java学习之springcloud之服务注册与发现篇_第39张图片
b)修改地址,80controller中的地址,不再写死8001
java学习之springcloud之服务注册与发现篇_第40张图片
这样我们就完成了微服务集群的配置,注意,访问集群的方式默认是轮询,即:你一次我一次

3.7微服务信息完善

目前存在的问题
在这里插入图片描述
a)主机名修改
(1)需要的依赖

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>

(2)修改部分
java学习之springcloud之服务注册与发现篇_第41张图片
在这里插入图片描述
b)显示ip
修改部分:在8001和8002的yml中加入
在这里插入图片描述
这样就可以显示ip了

3.8服务发现Discovery

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

1、修改8001的controller,8002也是一样的,就不演示了
首先注入DiscoveryClient

    @Resource
    private DiscoveryClient discoveryClient;

然后写一个用于获取信息的方法
通过这个discoveryClient就可以获取微服务信息了

    @GetMapping("/payment/discovery")
    public Object discovery(){
        List<String> services = discoveryClient.getServices();//获取服务列表的信息
        for (String service : services) {
            log.info("****element"+service);
        }

        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 discoveryClient;
    }

2、在8001的主启动类上添加注解@EnableDiscoveryClient
java学习之springcloud之服务注册与发现篇_第42张图片

3.9Eureka的自我保护机制与关闭

概念:一句话:某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的信息进行保存,属于CAP里面的AP分支,防止了因为网络分区发生故障而去住注销掉一个健康的微服务。
AP:当发生网络分区时,最大努力保证可用性

如果在Eureka Server的首页看到以下这段提示,则说明Eureka进入了保护模式:
在这里插入图片描述
综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留)也不盲目注销任何健康的微服务。 使用自我保护模式,可以让Eureka集群更加的健壮、稳定。

那么怎么关闭自我保护机制?

此次演示以7001服务器和8001客户端为例

(1)修改7001的yml文件,关闭自我保护机制
java学习之springcloud之服务注册与发现篇_第43张图片
在运行7001,发现系统提示我们自我保护机制已经关闭了
在这里插入图片描述

(2)修改8001的yml
java学习之springcloud之服务注册与发现篇_第44张图片

4.zookeeper服务注册与发现

在写这篇文章的时候,博主本人之前并未学习过zookeeper,所以这里暂时先跳过,后续学习后回来补。

5.Consul服务注册与发现

官网:https://www.consul.io/intro/index.html
中文文档:https://www.springcloud.cc/spring-cloud-consul.html
安装说明:https://learn.hashicorp.com/consul/getting-started/install.html
下载地址:https://www.consul.io/downloads.html

Consul 是一套开源的分布式服务发现和配置管理系统,由 HashiCorp 公司用 Go 语言开发。
提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全方位的服务网格,总之Consul提供了一种完整的服务网格解决方案。

可以干的事情:
java学习之springcloud之服务注册与发现篇_第45张图片
文件下载解压后:
java学习之springcloud之服务注册与发现篇_第46张图片
在这个文件夹可以直接用cmd命令运行
java学习之springcloud之服务注册与发现篇_第47张图片
启动以后,在浏览器中输入 http://localhost:8500就可以访问web界面了,还是很漂亮的
java学习之springcloud之服务注册与发现篇_第48张图片

5.1新建支付服务提供者8006注册进consul

1、建module:cloud-providerconsul-payment8006

2、改pom

   <dependencies>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-consul-discoveryartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>

3.写yml

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

spring:
  application:
    name: consul-provider-payment
  ####consul注册中心地址
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        #hostname: 127.0.0.1
        service-name: ${spring.application.name}

4、主启动

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

5、业务类controller

@RestController
@Slf4j
public class PaymentController {
    @Value("${server.port}")
    private String serverPort;

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

6、测试
运行我们的主启动类,然后去consul的web界面观察
java学习之springcloud之服务注册与发现篇_第49张图片
程序访问也通过
java学习之springcloud之服务注册与发现篇_第50张图片

5.2新建服务消费者80注册进consul

1、新建一个module:cloud-consumerconsul-order80

2、改pom

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-consul-discoveryartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>

3、写yml

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

spring:
  application:
    name: cloud-consumer-order
####consul注册中心地址
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        #hostname: 127.0.0.1
        #注册进去的名字
        service-name: ${spring.application.name}

4、主启动

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

5、业务类

这里的业务类和我们之前的Eureka下的那个80消费者很相似,也是使用RestTemplate,所以我们拷贝原来的配置类就行
java学习之springcloud之服务注册与发现篇_第51张图片
然后写一个controller

@RestController
@Slf4j
public class OrderConsulController {
    public static final String INVOKE_URL = "http://consul-provider-payment"; //与Eureka类似,我们要转发的服务的注册名字

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping(value = "/consumer/payment/consul")
    public String paymentInfo()
    {
        String result = restTemplate.getForObject(INVOKE_URL+"/payment/consul", String.class);
        System.out.println("消费者调用支付服务(consule)--->result:" + result);
        return result;
    }
}

6、测试
启动顺序:8006->80
java学习之springcloud之服务注册与发现篇_第52张图片
测试访问,发现一切正常
java学习之springcloud之服务注册与发现篇_第53张图片

6.三个注册中心的异同点

1、CAP是什么?
C:Consistency(数据一致性
A:Availability(可用性
P:Partition tolerance(分区容错性

最多只能同时较好的满足两个。
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求
因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:
CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
CP - 满足一致性,分区容忍必的系统,通常性能不是特别高。
java学习之springcloud之服务注册与发现篇_第54张图片

AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
java学习之springcloud之服务注册与发现篇_第55张图片
三种注册中心的对比图

java学习之springcloud之服务注册与发现篇_第56张图片

你可能感兴趣的:(java零基础学习笔记,java,spring,cloud,学习)