SpringCloud02

环境搭建

# 说明
- springboot 2.2.5.RELEASE
- springcloud Hoxton.SR6
- java8
- maven 3.3.9 
- idea 2018.3.5
# 1.创建springboot项目 指定版本为 2.2.5版本
# 2.引入springcloud的版本管理

创建父项目

父项目中不做任何代码编写,因此可以直接创建一个maven项目,删除其src文件,依赖如下:

 <!--继承SpringBoot的父项目-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
    </parent>
<!--定义springcloud使用版本号-->
<properties>
  <java.version>1.8</java.version>
  <spring-cloud.version>Hoxton.SR6</spring-cloud.version>
</properties>
<!--全局管理springcloud版本,并不会引入具体依赖-->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>${spring-cloud.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
# 3.完成上述操作springboot与springcloud环境搭建完成
- 接下来就是使用到具体的springcloud组件,在项目中引入具体的组件即可

服务注册中心

概念

所谓服务注册中心就是在整个的微服务架构中单独提出一个服务,这个服务不完成系统的任何的业务功能,仅仅用来完成对整个微服务系统的服务注册和服务发现,以及对服务健康状态的监控和管理功能。

img点击并拖拽以移动

# 1.服务注册中心
- 可以对所有的微服务的信息进行存储,如微服务的名称、IP、端口等
- 可以在进行服务调用时通过服务发现查询可用的微服务列表及网络地址进行服务调用
- 可以对所有的微服务进行心跳检测,如发现某实例长时间无法访问,就会从服务注册表移除该实例。

常用的注册中心

springcloud支持的多种注册中心**Eureka(netflix)、Consul(Google_Go)、Zookeeper(java)、以及阿里巴巴推出Nacos(alibaba_java)**。这些注册中心在本质上都是用来管理服务的注册和发现以及服务状态的检查的。

Eureka服务注册中心

简介

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务。SpringCloud将它集成在其子项目spring-cloud-netflix中, 以实现SpringCloud的服务注册和发现功能。

​ Eureka包含两个组件:Eureka Server和Eureka Client。

开发Eureka Server

1.创建一个子项目

在父项目中为Eureka创建一个SpringBoot的子项目

<!--每个子项目都是一个独立的SpringBoot应用:引入springbootweb-->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>

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

2.编写配置application.properties

server.port=8761	#执行服务端口																	
spring.application.name=eurekaserver 	#指定服务名称 唯一标识  服务名不能出现下划线  推荐服务名大写
eureka.client.service-url.defaultZone=http://localhost:8761/eureka  #指定服务注册中心的地址

3.开启Eureka Server,入口类加入注解:@EnableEurekaServer

@SpringBootApplication
@EnableEurekaServer //---------开启当前应用是一个服务注册中心
public class EurekaServerApplication {
    public static void main(String[] args) {        SpringApplication.run(EurekaServerApplication.class,args);
    }
}

4.访问Eureka的服务注册页面 http://localhost:8761

Eureka管理页面:img点击并拖拽以移动

5.虽然能看到管理界面为什么项目启动控制台报错?

2021-07-25 16:24:43.425 ERROR 9080 --- [           main] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_EUREKASERVER/localhost:EUREKASERVER:8761 - was unable to refresh its cache! status = Cannot execute request on any known server

com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
	at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:112) ~[eureka-client-1.9.21.jar:1.9.21]
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134) ~[eureka-client-1.9.21.jar:1.9.21]
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6.execute(EurekaHttpClientDecorator.java:137) ~[eureka-client-1.9.21.jar:1.9.21]
	at 
    .................

出现上述问题原因:eureka组件包含 eurekaserver 和 eurekaclient。server是一个服务注册中心,用来接受客户端的注册。client的特性会让当前启动的服务把 自己 作为eureka的客户端进行服务中心的注册,当项目启动时服务注册中心还没有创建好,所以找不到服务的客户端组件就直接报错了,当启动成功服务注册中心创建好了,日后client也能进行注册,就不再报错啦!解决这个问题可以在配置文件进行如下匹配:eureka.client.register-with-eureka=false关闭客户端立即注册

6.关闭Eureka自己注册自己或让当前应用仅仅是服务服务注册中心

eureka.client.register-with-eureka=false    #不再将自己同时作为客户端进行注册 
eureka.client.register-with-eureka=false    # 让当前应用仅仅是服务服务注册中心

7.再次启动,当前应用就是一个单纯Eureka Server,控制器也不再报错

开发Eureka Client

Eureka client就是日后基于业务拆分出来的一个个微服务,在父项目中再创建一个SpringBoot的子项目

1.创建项目并引入eureka client依赖

<!--每个子项目都是一个独立的SpringBoot应用:引入springbootweb-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<!--引入eureka client-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2.编写配置application.properties

server.port=8888			#服务端口号
spring.application.name=eurekaclient8888	#服务名称唯一标识
eureka.client.service-url.defaultZone=http://localhost:8761/eureka #eureka注册中心地址

3.开启eureka客户端加入注解

@SpringBootApplication
@EnableEurekaClient  //--------------------让当前微服务作为一个eureka serve客户端 进行服务注册
public class Eurekaclient8888Application {
    public static void main(String[] args) {
        SpringApplication.run(Eurekaclient8888Application.class, args);
    }
}

4.启动Eureka Client之前先启动 之前的8761的服务注册中心,在启动eureka客户端服务

5.查看eureka server的服务注册情况

img点击并拖拽以移动

Eureka的自我保护机制

客户端频繁启动时 Eureka Server会出现如下错误信息:

img点击并拖拽以移动

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

1.自我保护机制

官网地址: https://github.com/Netflix/eureka/wiki/Server-Self-Preservation-Mode

默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护机制。Eureka Server在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期。这种设计的哲学原理就是”宁可信其有不可信其无!”。自我保护模式正是一种针对网络异常波动的安全保护措施,使用自我保护模式能使Eureka集群更加的健壮、稳定的运行。

2.在eureka server端关闭自我保护机制

eureka.server.enable-self-preservation=false  #关闭自我保护
eureka.server.eviction-interval-timer-in-ms=3000 #超时3s自动清除  默认是1分钟(一分钟内没有接收到某个微服务的心跳,则将其清除)

3.微服务修改减短服务心跳的时间

eureka.instance.lease-expiration-duration-in-seconds=10 #用来修改eureka server默认接受心跳的最大时间 默认是90s
eureka.instance.lease-renewal-interval-in-seconds=5     #指定客户端多久向eureka server发送一次心跳 默认是30s

4.尽管如此关闭自我保护机制还是会出现警告,官方并不建议关闭此机制

- THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
- `官方并不建议在生产情况下关闭

img

Eureka已停止更新
# 1.官方停止更新说明
- https://github.com/Netflix/eureka/wiki
- 在1.x版本项目还是活跃的,但是在2.x版本中停止维护,出现问题后果自负!!!
Eureka Server 集群搭建

img点击并拖拽以移动

Consul服务注册中心

官网:https://www.consul.io

consul是一个可以提供服务发现,健康检查,多数据中心,Key/Value存储等功能的分布式服务框架,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,使用起来也较为简单。Consul用Golang实现,因此具有天然可移植性(支持Linux、Windows和Mac OS X);安装包仅包含一个可执行文件,方便部署。

安装consul
# 1.下载consul(Windows版)
- https://www.consul.io/downloads
# 2.解压到一个没有汉字的文件夹中
# 3.在consul.exe的当前目录打开cmd
# 4.执行指令:
  consul agent -dev    (单节点开发者模式)
E:\Consul>consul agent -dev
==> Starting Consul agent...
           Version: 'v1.8.0'
           Node ID: '83754e25-4506-0d44-de3e-66d1cdc95e6a'
         Node name: 'Sovzn'
        Datacenter: 'dc1' (Segment: '<all>')
            Server: true (Bootstrap: false)
       Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600)
      Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)
           Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false, Auto-Encrypt-TLS: false

==> Log data will now stream in as it occurs:
.............
# 5.访问consul管理界面:
localhost:8500(默认端口)   如下:

点击并拖拽以移动 img点击并拖拽以移动

#  说明
- dc1:  数据中心,相当于保存数据的库的概念,默认为dc1,指定数据中心启动:
- consul agent -dev -datacenter=name
- services:  当前consul服务中注册的服务列表,默认在启动时consul会自己注册自己,所以会出现一个consul服务
- nodes: 用来查看consul的集群节点

为了我们能在任何目录下快速启动consul服务,建议进行环境变量配置

在环境变量Path中添加consul.exe的目录即可:

如:我的consul.exe在E:\Consul下,直接将E:\Consul添加到path即可。

开发consul客户端(微服务)

1.创建项目并引入consul客户端依赖

<!--springboot-stater-web-->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <!--引入consul client依赖-->
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-consul-discovery</artifactId>
      </dependency>
 

2.编写properties配置

server.port=8082
# 指定服务名称
spring.application.name=CONSULCLIENT

# consul server 服务注册地址
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
# 指定注册当前服务的服务名称  默认就是当前服务的服务名称(CONSULCLIENT): ${spring.application.name}
spring.cloud.consul.discovery.service-name=${spring.application.name}

3.在启动类上加入标明该服务是Consul客户端的注解

@SpringBootApplication //代表这一个springboot入口应用
@EnableDiscoveryClient  //作用:通用服务注册客户端注解(除Eureka)  可代表:consul client、zk client、nacos client
public class ConsulClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(com.sovzn.ConsulClientApplication.class,args);
    }
}

4.启动Consul服务,再启动刚写的客户端ConsulClientApplication后查看Consul服务列表信息

启动客户端服务ConsulClientApplication: img点击并拖拽以移动

查看Consul服务列表:

点击并拖拽以移动 img点击并拖拽以移动 报错是因为Consul的健康检查默认是开启的,在客户端中没有加入健康检查依赖,Consul Server无法向客户端发心跳来检查客户端是否健康。

consul 健康监控检查

# 1.consul健康监控
- 默认情况consul监控健康是开启的,但是必须依赖健康监控依赖才能正确监控健康状态所以直接启动会显示错误,引入健康监控依赖之后服务正常
<!-- 这个包是用做健康度监控的-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

加入依赖,重新启动: img点击并拖拽以移动

关闭健康检查:

只需在客户端服务配置中加入如下配置:

# 关闭健康检查 注意:了解即可,在生产情况下不要关闭健康检查
spring.cloud.consul.discovery.register-health-check=true

不同注册中心区别

1.CAP定理:

CAP定理又称CAP原则,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。

一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)

可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)

分区容忍性(P),就是高可用性,一个节点崩了,并不影响其它的节点(100个节点,挂了几个,不影响服务,越多机器越好)

2.Eureka特点:

Eureka中没有使用任何的数据强一致性算法保证不同集群间的Server的数据一致,仅通过数据拷贝的方式争取注册中心数据的最终一致性,虽然放弃数据强一致性但是换来了Server的可用性,降低了注册的代价,提高了集群运行的健壮性。

3.Consul特点:

基于Raft算法,Consul提供强一致性的注册中心服务,但是由于Leader节点承担了所有的处理工作,势必加大了注册和发现的代价,降低了服务的可用性。通过Gossip协议,Consul可以很好地监控Consul集群的运行,同时可以方便通知各类事件,如Leader选择发生、Server地址变更等。

4.zookeeper特点

基于Zab协议,Zookeeper可以用于构建具备数据强一致性的服务注册与发现中心,而与此相对地牺牲了服务的可用性和提高了注册需要的时间。

img点击并拖拽以移动