导航目录

  • 一、微服务架构概述
    • 1.什么是微服务架构
    • 2.SpringCloud简介
      • 2.1是什么
      • 2.2 SpringCloud技术栈
  • 二、微服务架构编码构建
    • 2.1 创建父工程cloud2020
    • 2.2 设置项目字符编码为UTF-8
    • 2.3 注解生效激活
    • 2.4 Java编译版本选择8
    • 2.5 导入父工程依赖
      • 2.5.1 dependencyManagement
    • 2.6 支付模块构建
      • 2.6.1 建module
      • 2.6.2 引pom
      • 2.6.3 写yml
      • 2.6.4 主启动
      • 2.6.5 创建表
      • 2.6.6 主实体Payment
      • 2.6.7 JSON封装体
      • 2.6.8 Dao
      • 2.6.9 Mapper文件
      • 2.6.10 Service
      • 2.6.11 ServiceImpl
      • 2.6.12 Controller
    • 2.7 热部署
      • 2.7.1 子工程添加依赖
      • 2.7.2 添加插件到父工程的pom.xml文件中
      • 2.7.3 开启自动编译
      • 2.7.4 开启更新值
      • 2.7.5 重启IDEA
    • 2.8 RestTemplate
      • 2.8.1 是什么
      • 2.8.2 客户端使用RestTemplate调用服务端的服务
    • 2.9 工程重构
      • 2.9.1 提取公共模块
      • 2.9.2 把这个公共模块做成依赖被其他模块导入
      • 2.9.3 在要用到的模块中引入
  • 三、Eureka服务注册和发现
    • 3.1 Eureka基础知识
      • 3.1.1 什么是服务治理
      • 3.1.2 什么是服务注册与发现
      • 3.1.3 Eureka两组件
    • 3.2 单机Eureka构建步骤
      • 3.2.1 IDEA生成eurekaServer端服务注册中心
      • 3.2.2 EurekaClient端cloud-provider-payment8001将注册进EurekaServer成为服务提供者provider,对外提供服务
      • 3.2.3 EurekaClient端cloud-consumer-order80将注册进EurekaServer成为服务消费者consumer,类似消费者
    • 3.3 集群Eureka构建步骤
      • 3.3.1 Eureka集群原理
      • 3.3.2 EurekaServer集群环境构建步骤
      • 3.3.3 服务发现
    • 3.4 actuator微服务信息完善
      • 3.4.1 主机名称:服务名称修改
      • 3.4.2 访问信息有IP信息提示
    • 3.5 服务发现Discovery
      • 3.5.1 功能
      • 3.5.2 实现
    • 3.6 Eureka自我保护
      • 3.6.1 概述
      • 3.6.2 导致的原因
      • 3.6.3 什么是自我保护模式?
      • 3.6.4 怎么关闭自我保护机制
    • 3.7 Eureka停更说明
  • 四、Zookeeper服务注册与发现
    • 4.1 Zookeeper的安装
    • 4.2 使用Zookeeper进行服务注册的步骤
    • 4.3 一些细节
  • 五、Consul服务注册与发现
    • 5.1 简介
      • 5.1.1 是什么
      • 5.1.2 能干嘛
      • 5.1.3 去哪下
      • 5.1.4 怎么玩
    • 5.2 安装并运行
    • 5.3 服务提供者
    • 5.4 服务消费者
    • 5.5 三个注册中心的区别

一、微服务架构概述

1.什么是微服务架构

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务于服务之间采用轻量级的通信机制互相协作(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

2.SpringCloud简介

2.1是什么

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

2.2 SpringCloud技术栈

二、微服务架构编码构建

2.1 创建父工程cloud2020

2.2 设置项目字符编码为UTF-8

2.3 注解生效激活

File–>Build–>Compiler–>Annotation Processors

2.4 Java编译版本选择8

File–>Build–>Compiler–>Java Compiler

2.5 导入父工程依赖

<?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"><modelVersion>4.0.0</modelVersion><groupId>com.jg.springcloud</groupId><artifactId>cloud2020</artifactId><version>1.0-SNAPSHOT</version><!--  表示是一个pom总的父工程 --><packaging>pom</packaging><modules><module>cloud-provider-payment8001</module></modules><!-- 统一管理jar包版本 --><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><junit.version>4.12</junit.version><lombok.version>1.16.18</lombok.version><log4j.version>1.2.17</log4j.version><mysql.version>5.1.47</mysql.version><druid.version>1.1.16</druid.version><mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version></properties><!-- 子模块继承之后,提供作用:锁定版本+子module不用写groupId和version --><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.2.2.RELEASE</version><type>pom</type><scope>import</scope></dependency><!--spring cloud Hoxton.SR1--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Hoxton.SR1</version><type>pom</type><scope>import</scope></dependency><!--spring cloud alibaba--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.1.0.RELEASE</version><type>pom</type><scope>import</scope></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version><scope>runtime</scope></dependency><!-- druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>${druid.version}</version></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.spring.boot.version}</version></dependency><!--junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version></dependency><!--log4j--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>${log4j.version}</version></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><fork>true</fork><addResources>true</addResources></configuration><version>2.2.2.RELEASE</version></plugin></plugins></build></project>

2.5.1 dependencyManagement

Maven使用dependencyManagement元素来提供了一种管理依赖版本号的方式

通常会在一个组织或者项目的最顶层的父POM中看到dependencyManagement元素。

使用pom.xml中的dependencyManagement元素能让所有在子项目中引用一个依赖而不用显式的列出版本号。

Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用这个dependencyManagement元素中指定的版本号。

这样做的好处就是:如果有多个子项目都引用同一样依赖,则可以避免在每个使用的子项目中都声明一个版本号,这样当想升级或切换到另一个版本时,只需要在顶层容器里更新,而不需要一个一个子项目的修改;另外如果某个子项目需要另外的一个版本,只需要声明version即可。

2.6 支付模块构建

2.6.1 建module

2.6.2 引pom

<dependencies><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.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.10</version></dependency><!--mysql-connector-java--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</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>

2.6.3 写yml

# 端口号信息
server:port: 8001spring:application:name: cloud-payment-servicedatasource:type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=falseusername: rootpassword: 123456mybatis:mapperLocations: classpath:mapper/*.xmltype-aliases-package: com.atguigu.springcloud.entities    # 所有Entity别名类所在包

2.6.4 主启动

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

2.6.5 创建表

CREATE TABLE `payment`(`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',`serial` varchar(200) DEFAULT '',PRIMARY KEY(`id`)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

2.6.6 主实体Payment

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment {private Long id;private String serial;
}

2.6.7 JSON封装体

@Data
@AllArgsConstructor
@NoArgsConstructorpublic class CommonResult<T> {    private Integer code;    private String message;    private T data;    public CommonResult(Integer code,String message){        this(code,message,null);    }
}

2.6.8 Dao

@Mapper
public interface PaymentDao {    int create(Payment payment);    Payment getPaymentByID(@Param("id") Long id);
}

2.6.9 Mapper文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.jg.springcloud.dao.PaymentDao"><resultMap id="BaseResultMap" type="com.jg.springcloud.entities.Payment"><id column="id" property="id" jdbcType="BIGINT"/><id column="serial" property="serial" jdbcType="VARCHAR"/></resultMap><insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">insert into payment(serial) values(#{serial});</insert><select id="getPaymentByID" parameterType="Long" resultMap="BaseResultMap">select * from payment where id=#{id};</select>
</mapper>

2.6.10 Service

public interface PaymentService {    int create(Payment payment);    Payment getPaymentByID(Long id);
}

2.6.11 ServiceImpl

@Service
public class PaymentServiceImpl implements PaymentService {    @Autowired    private PaymentDao paymentDao;    @Override    public int create(Payment payment) {        return paymentDao.create(payment);    }    @Override    public Payment getPaymentByID(Long id) {        return paymentDao.getPaymentByID(id);    }
}

2.6.12 Controller

@RestController
@Slf4j
public class PaymentController {    @Autowired    private PaymentService paymentService;    //返回给前端的结果集    @PostMapping(value = "/payment/create")    public CommonResult create(Payment payment) {        Integer result = paymentService.create(payment);        log.info("******插入结果:" + result);        if (result > 0) {           return new CommonResult(200, "插入数据库成功",result);        } else {            return new CommonResult(444, "插入数据库失败", null);       }   }    @GetMapping(value = "/payment/get/{id}")   public CommonResult getPaymentByID(@PathVariable("id") Long id) {       Payment payment = paymentService.getPaymentByID(id);        log.info("******插入结果:" + payment);        if (payment != null) {            return new CommonResult(200, "查询成功", payment);        } else {            return new CommonResult(444, "没有查询记录", null);        }    }
}

2.7 热部署

2.7.1 子工程添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional>
</dependency>

2.7.2 添加插件到父工程的pom.xml文件中

<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><fork>true</fork><addResources>true</addResources></configuration>
</plugin>

2.7.3 开启自动编译

2.7.4 开启更新值

使用快捷键Ctrl+Alt+Shift+/打开更新值设置

2.7.5 重启IDEA

2.8 RestTemplate

2.8.1 是什么

RestTemplate提供了多种便携访问远程Http服务的方法,是一种简单便携的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集。

2.8.2 客户端使用RestTemplate调用服务端的服务

配置

@Configuration
public class ApplicationContextConfig {@Bean //@Bean相当于applicationContext.xml文件中的bean标签public RestTemplate getRestTemplate(){return new RestTemplate();}
}

controller层

@RestController
@Slf4j
public class OrderController {//定义服务端URLpublic static final String PAYMENT_URL = "http://localhost:8001";//客户端通过RestTemplate调用服务端@Autowiredprivate RestTemplate restTemplate;@GetMapping("/consumer/payment/create")public CommonResult<Payment> create(Payment payment) {return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class);}@GetMapping("consumer/payment/get/{id}")public CommonResult<Payment> getPayment(@PathVariable("id") Long id){return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);}
}

前端返回给后端json类型的数据实体在接收的时候,参数前应该加@RequestBody注解

2.9 工程重构

2.9.1 提取公共模块

把服务间公共部分提取出来抽象成一个公共的模块,这个模块不对外暴露接口

在cloud-provider-payment8001和cloud-consumer-order80服务里面均用到了CommonResult和Payment,所以把它们提取出来,放在一个公共模块中,这个模块不对外暴露端口号。

2.9.2 把这个公共模块做成依赖被其他模块导入

maven-clean AND maven-install

2.9.3 在要用到的模块中引入

<dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><groupId>com.jg.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version>
</dependency>

三、Eureka服务注册和发现

3.1 Eureka基础知识

3.1.1 什么是服务治理

Spring Cloud封装了Netflix公司开发的Eureka模块来实现服务治理

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

3.1.2 什么是服务注册与发现

Eureka采用了CS的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心。而系统中的其它微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行。

在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息,比如服务地址通讯地址等以别名方式注册到注册中心上。另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务于服务之间的一个依赖关系(服务治理概念)。在任何RPC远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))。

3.1.3 Eureka两组件

3.2 单机Eureka构建步骤

3.2.1 IDEA生成eurekaServer端服务注册中心

经典五步

  1. 建module

  2. 改pom

    <dependencies><!-- eureka-server--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId><version>2.2.2.RELEASE</version></dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><dependency><groupId>com.jg.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></dependency><!--boot web actuator--><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></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency>
    </dependencies>
    
  3. 写yml

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

    @SpringBootApplication
    //表示这个服务是Eureka的注册中心
    @EnableEurekaServer
    public class EurekaMain7001{public static void main(String[] args) {SpringApplication.run(EurekaMain7001.class,args);}
    }
    
  5. 业务类

Eureka注册中心Web页面

3.2.2 EurekaClient端cloud-provider-payment8001将注册进EurekaServer成为服务提供者provider,对外提供服务

导入依赖

<!-- EurekaClient作为服务提供者需要引入的jar包-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

application.xml修改配置

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

修改主启动类

@EnabkeEurekaClient //在主启动类上添加注解

如此配置,启动服务,该服务就可以注册到EurekaServer中

3.2.3 EurekaClient端cloud-consumer-order80将注册进EurekaServer成为服务消费者consumer,类似消费者

跟上面步骤相同

3.3 集群Eureka构建步骤

3.3.1 Eureka集群原理

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

高可用,试想你的注册中心只有一个only one,它出故障了那就全都完了,会导致整个微服务环境不可用,所以解决办法是需要搭建Eureka注册中心集群,实现负载均衡和故障容错。

集群注册的原理是互相注册,相互守望

3.3.2 EurekaServer集群环境构建步骤

  1. 参考cloud-eureka-server7001,新建一个cloud-eureka-server7002

  2. 修改系统的映射文件–>hosts

    #SpringCloud
    127.0.0.1 eureka7001.com
    127.0.0.1 eureka7002.com
    
  3. 集群环境下,EurekaServer的配置

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

    修改配置文件

       service-url:#defaultZone: http://localhost:7001/eurekadefaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
    
  5. 支付服务的集群环境搭建

    直接复制cloud-provider-payment8001即可,只有一些小的细节需要完善。

3.3.3 服务发现

微服务提供方如果有多节点集群环境,需要配置才能被服务调用方正常发现并调用

具体实现

在配置类对应方法上添加@LoadBalanced注解,用于实现RestTemplate的负载均衡能力

服务调用方在的请求URL不是像以前那样写死,而是直接写服务提供方的应用名(服务提供方已经做了集群环境)

后续可以使用Ribbon整合Eureka实现负载均衡,可以直接调用服务而不用在关心地址和端口号

3.4 actuator微服务信息完善

3.4.1 主机名称:服务名称修改

解决方案:修改cloud-provider-payment8001的application.yml的中关于Eureka的配置

添加如下内容

instance:instance-id: payment8002

修改之后的效果**

3.4.2 访问信息有IP信息提示

  instance:instance-id: payment8002#此配置是为了让访问路径可以显示IP地址prefer-ip-address: true

3.5 服务发现Discovery

3.5.1 功能

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

3.5.2 实现

修改服务提供方的Controller和主启动类

Controller上的修改

主启动类上的修改

主启动类上添加@EnableDiscoveryClient注解

效果

后台发现的服务

3.6 Eureka自我保护

3.6.1 概述

保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不在删除服务注册表中的数据,也就是不会注销任何微服务。

如果在Eureka Server的首页看到以下这段提示,则说明Eureka进入了保护模式

3.6.2 导致的原因

某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的信息进行保存。

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

3.6.3 什么是自我保护模式?

默认情况西,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生(延时、卡顿、拥挤)时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了-因为微服务本身其实是健康的,此时本不应该注销这个微服务。Eureka通过“自我保护模式”来解决这个问题----当EurekaServer节点在短时间内丢失过多客户端是(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。

3.6.4 怎么关闭自我保护机制

在EurekaServer服务端的application.yml中配置

server:#关闭自我保护机制,保证不可用服务被及时剔除enable-self-preservation: false  eviction-interval-timer-in-ms: 2000

在服务端设置心跳检测和续约时间application.yml

#心跳检测与续约时间
#开发时设置小些,保证服务关闭后注册中心及时剔除服务
instance:#Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)lease-renewal-interval-in-seconds: 1#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务lease-expiration-duration-in-seconds: 2

3.7 Eureka停更说明

SpringCloud整合Zookeeper代替Eureka

四、Zookeeper服务注册与发现

4.1 Zookeeper的安装

  1. 解压Zookeeper的安装包到指定目录
  2. 创建Zookeeper的存放数据的文件夹(一般在解压之后的目录下)
  3. 修改Zookeeper的配置文件,加上刚才创建的文件夹的路径
  4. 安装完毕,启动

4.2 使用Zookeeper进行服务注册的步骤

经典五步

  1. 建module

  2. 引pom

    <dependencies><groupId>com.jg.springcloud</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客户端,这里不再使用Eureka进行服务注册,所以这里导入的是Zookeeper的相关依赖 -->
    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zookeeper-discovery</artifactId><!--先排除自带的zookeeper3.5.3--><exclusions><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>
    </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

    #8004表示注册到Zookeeper服务器的支付服务提供者端口号
    server:port: 8004#服务别名----注册到Zookeeper到注册中心名称
    spring:application:name: cloud-provider-paymentcloud:zookeeper:#Zookeeper的地址connect-string: 192.168.170.132:2181
    
  4. 主启动

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

    @RestController
    @Slf4j
    public class PaymentController {@Value("${server.port}")private String serverPort;@RequestMapping(value = "/payment/zk")public String paymentZK(){return "springcloud with zookeeper:"+serverPort+"\t"+ UUID.randomUUID().toString();}
    }
    

如上配置,启动服务,进入zookeeper的服务中心页面bin/zkCli.sh,就可以看到刚才启动的服务已经注册成功。

zookeeper上服务信息

4.3 一些细节

Zookeeper上面的服务节点是临时的


可以看到,当我们把注册进Zookeeper的服务关掉之后,过了一段时间,注册进Zookeeper中的服务就会被Zookeeper从节点中移除。而并不是说服务挂掉,Zookeeper还会保证这个服务一直存活在Zookeeper的节点上。

五、Consul服务注册与发现

5.1 简介

5.1.1 是什么

官网

Consul是一套开源的分布式服务发现和配置管理系统,由HashiCorp公司用Go语言开发的。

提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全方位的服务网络,总之Consul提供了一种完整的服务网格解决方案。

它具有很多优点。包括:基于raft协议,比较简洁;支持健康检查,同时支持HTTP和DNS协议,支持跨数据中心的WAN集群,提供图形界面,跨平台,支持Linux、Mac、Windows。

5.1.2 能干嘛

服务发现

提供HTTP和DNS两种发现方式。

健康监测

支持多种方式,HTTP、TCP、Docker、Shell脚本定制化

KV存储

Key、Value的存储方式

多数据中心

Consul支持多数据中心

可视化Web界面

5.1.3 去哪下

下载地址

5.1.4 怎么玩

参考文档

5.2 安装并运行

可以参考官网的安装说明进行安装

下载完成之后只有一个consul.exe文件

在consul.exe目录下运行cmd命令行窗口,输入consul --version可以查看当前安装的consul的版本

使用开发模式启动

consul agent -dev

通过以下地址可以访问Consul的首页:

5.3 服务提供者

新建Module支付服务cloud-providerconsul-payment8006

导入依赖

<dependencies><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><dependency><groupId>com.jg.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency><!--SpringCloud consul-server --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId></dependency><!-- SpringBoot整合Web组件 --><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><!--日常通用jar包配置--><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><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>RELEASE</version><scope>test</scope></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>RELEASE</version><scope>test</scope></dependency>
</dependencies>

修改application.yml文件

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

主启动

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

如此配置,服务启动之后会注册到Consul中

5.4 服务消费者

依旧是好经典五步走

pom

<dependencies><!--SpringCloud consul-server --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId></dependency><!-- SpringBoot整合Web组件 --><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><!--日常通用jar包配置--><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>
###consul服务端口号
server:port: 80spring:application:name: cloud-consumer-order####consul注册中心地址cloud:consul:host: localhostport: 8500discovery:#hostname: 127.0.0.1service-name: ${spring.application.name}

Main

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

Controller

@RestController
@Slf4j
public class OrderConsulController {public static final String INVOKE_URL = "http://consul-provider-payment";@Autowiredprivate RestTemplate restTemplate;@GetMapping("/consumer/payment/consul")public String paymentInfo(){return restTemplate.getForObject(INVOKE_URL+"/payment/consul",String.class);}
}

5.5 三个注册中心的区别

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

尚硅谷阳哥SpringCloud第二季学习笔记(一)相关推荐

  1. 尚硅谷周阳老师 SpringCloud第二季学习笔记

    前言:首先感谢尚硅谷周阳老师的讲解,让我对springcloud有了很好的理解,周阳老师的讲课风格真的很喜欢,内容充实也很幽默,随口一说就是一个段子,我也算是周阳老师的忠实粉丝啦. 先说说课程总体内容 ...

  2. 尚硅谷 SpringCloud 第二季学习笔记【已完结】

    SpringCloud 一.介绍 (一)cloud和boot之间的依赖关系 https://spring.io/projects/spring-cloud#overview Finchley 是基于 ...

  3. 尚硅谷大厂面试题第二季(上)

    尚硅谷大厂面试题第二季(上) 1. volatile关键字理解 volatile是Java提供的轻量级的同步机制,主要有三个特性: 保证内存可见性 不保证原子性 禁止指令重排序 1.1 保证内存可见性 ...

  4. (尚硅谷java零基础教程)学习笔记day7/8-数组

    1.数组的概述 1.1 定义 数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理. 1.2 数组的相关概念 数组名 元素 数组的索引 ...

  5. 尚硅谷+黑马程序员MongoDB视频学习笔记(一)

    本学习笔记是来源于学习B站上的尚硅谷和黑马的MongoDB教学视频而做的知识总结. 一.数据库(Database) 数据库是按照数据结构来组织.存在和管理数据的仓库.说白了,数据库就是存在数据的仓库. ...

  6. 尚硅谷Vue2-3(张天禹老师) 学习笔记

    这里写目录标题 (一) 基本模块 01基础模板语法 1.1插值语法 -- 解析标签体里的内容 1.2指令语法 -- 解析标签 数据绑定 条件渲染 1.2.1 **`v-bind:xxx`** 1.2. ...

  7. 《尚硅谷30天入门Java》学习笔记1

    第0天–准备工作 1.工具之印象笔记 浏览器插件.Android.Windows客户端.chrome印象笔记插件可以实现减藏页面,做笔记! 一个浏览器插件的网站 之前拖插件到拓展程序这里,显示crx_ ...

  8. 【学习笔记】尚硅谷周阳老师的Docker教程学习笔记

    本文是尚硅谷周阳老师的Docker教程的相关学习笔记,暂时还没有检查勘误过. 一.Docker简介 1. 简介 Docker的出现是为了解决代码在本机可以正常运行,而部署到其他机器不能运行的问题.这是 ...

  9. docker详解(尚硅谷阳哥)

    文章目录 1.docker为什么会出现 2.docker简介 3.传统虚拟机和容器的对比 3.1虚拟机 3.2容器虚拟化技术 3.3两者对比 4.docker的作用 6.docker的应用场景 7.d ...

最新文章

  1. ASP.NET那点不为人知的事(四)
  2. 钉钉如何调整组织架构_阿里宣布新一轮组织架构调整:明确大文娱一号位,钉钉进入阿里云...
  3. oracle spm buffer get比较过程,Oracle 11g 新特性 -- SQL Plan Management 示例
  4. NSArray、NSMutableArray和NSMutableDictionary的用法
  5. “面试不败计划”:面试题基础一
  6. 【小白学PyTorch】16.TF2读取图片的方法
  7. 03 jquery easyui 之 easyLoader 加载器
  8. winform打开cad图纸_为什么CAD图纸打开后会显示很多问号“???”,该怎么解决...
  9. 问题 1074: 数字整除
  10. 可有可无的Mysql工作技巧 2
  11. STL之stack容器
  12. java怎么写自定义布局_java-Android设置自定义首选项布局
  13. html5canvas绘制图片源码,HTML5 CANVAS:绘制图片
  14. c语言文件修改某一行,利用C语言替换文件中某一行的方法
  15. java我的世界损坏的种子,我的世界:5分钟让你通关游戏的种子,大神用这种子破了世界纪录...
  16. STM32驱动LCD1602程序(调试已成功)
  17. ubuntu 定时备份mysql,ubuntu下mysql定时备份
  18. hp 计算机如何显示在桌面上,HPDL1414 精致桌面小伴侣 显示时间日历和电脑状态(CPU温度负载...
  19. MATLAB与Excel文件的交换
  20. 【typescript】infer的理解与使用

热门文章

  1. openGL API glProgramUniform详解
  2. 武侠/玄幻/奇幻小说中出现的功法名字-整合(持续更新)
  3. google play连接超时_Google在安卓系统上推出了新的密码自动填充功能
  4. 关于ffmpeg 的一些分享
  5. 怎么用ABBYY识别文档里包含的条码
  6. 汽车点火开关的START、ON、ACC、LOCK四个挡位表示什么
  7. 全产业链内循环?碧桂园真正的“护城河”!
  8. 51Nod 2176 ProjectEuler 3 c/c++题解
  9. 基于深度学习的动物识别系统(YOLOv5清新界面版,Python代码)
  10. python写交易系统_鳄鱼线交易系统Python版 摘要 做过交易的人大概会有一种体会,有时候价格波动很有规律,但更多时候它呈现出随机游走的不稳定状态。正是这种不稳定才是市... - 雪球...