Spring Cloud完整组件搭建之路 第一篇-Eureka
写在前面
自己在搭建SpringCloud组件时,碰到各种坑,但是网上各种文章你在都不是太详细,通过阅读大量的博客最终才出坑,所以详细记录一下我的配置细节,希望能够帮助大家
SpringCloud配置系列目录:
【Spring Cloud完整组件搭建之路 第一篇-Eureka】
【Spring Cloud完整组件搭建之路 第二篇 -OpenFeign、Ribbon整合】
【Spring Cloud完整组件搭建之路 第三篇 -OpenFeign、Hystrix整合】
【Spring Cloud完整组件搭建之路 第四篇 -Zuul】
【Spring Cloud完整组件搭建之路 第五篇 -Spring Cloud Config】
【Spring Cloud完整组件搭建之路 总结篇】
创建Eureka-Server
前奏:创建工程
使用idea,按照如下步骤创建工程:
之所以不创建空maven项目自己引入依赖,是因为这样做可能会造成有些组件功能不能正常使用,这是本人走过的坑,大家可以先试试自己引依赖,失败之后再按照步骤来即可。
【File】->【New】->【Project】
【Spring Initializr】->【选择Default】->【Next】
【按需填写工程信息】->【Next】
【选中所需依赖项】->【Next】
因为此次是对Eureka的工程搭建,只需
引入Eureka Server(Eureka服务端所需依赖)或者Eureka Discovery Client(Eureka客户端所需依赖)
即可,后期引入也会进行详细描述。
第一步:pom.xml文件展示
如果大家是按照上一步进行的工程创建,pom文件应该就是我以下的内容,如果大家最后未配置成功,再看pom文件是否有差异即可。
Eureka服务端
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
<relativePath/>
</parent>
<groupId>com.hepai.demo</groupId>
<artifactId>spring-cloud-learn</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-cloud-learn</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2021.0.0</spring-cloud.version>
</properties>
<dependencies>
<!--引入eurekaServer依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Eureka客户端
<?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.hepai.learn.eureka-client-consumer</groupId>
<artifactId>eureka-client-consumer</artifactId>
<version>1.0-SNAPSHOT</version>
<!--WKTODO 1.配置maven依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
第二步:新建并编辑application.yml文件
修改操作系统的hosts文件内容
因为我这是在单机配置的SpringCloud各种组件,所以如果是多个Eureka Server节点的话,需要的域名是不一样的,就是说,多个Eureka Server节点的hostname配置信息不能相同,所以,请按照如下配置:
创建application.yml文件
在src/mian/resource目录下创建application.yml文件即可。
编辑application.yml文件
Eureka服务端
# 服务启动端口号
server:
port: 7000
eureka:
instance:
hostname: euk-server-two.com # 服务注册中心ip地址,在hosts文件配置
# 可作为参数传递,使用http://euk-server-two.com:7000/eureka/可展示具体信息
metadataMap:
message: xiaohong server
client:
# 是否将自己注册到Eureka Server,默认是true,如果当前就一个Server,那就设置成false,
# 表明该服务不会向Eureka Server注册自己的信息
# 但如果当前有多个Server,那就设置成true,
# 表明该服务不会向其他Eureka Server注册自己的信息
registerWithEureka: true
# 是否从Eureka Server获取注册信息,如果当前就一个Server,不需要同步其他节点的数据,设置false
# 如果当前有多个Server,设置true
fetchRegistry: true
# 设置服务注册中心的URL,用于client和server端交流
serviceUrl:
defaultZone: http://euk-server-one.com:7001/eureka/
# 关闭自我保护模式
server:
enableSelfPreservation: false
# 设置Server的名称
spring:
application:
name: Eureka-Server
Eureka客户端
eureka:
client:
# 注册信息到Eureka服务端
serviceUrl:
# 使用英文逗号,注册到多个Eureka服务端
defaultZone: http://${eureka.instance.hostname}:7000/eureka/,http://euk-server-one.com:7001/eureka/
registerWithEureka: true
fetchRegistry: true
# Eureka服务端的域名信息
instance:
hostname: euk-server-two.com
# 服务启动端口号
server:
port: 7100
# 设置被Server发现后,当前Client的名称
spring:
application:
name: USER-PROVIDER
第三步:创建并编辑启动类
如果是按照上述步骤创建的工程,IDEA会为我们创建好启动类,所以大家按需创建。
创建启动类
在src/mian/java目录下创建java文件即可,包名和类名随意。
编辑启动类
Eureka服务端
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
// 注解开启Eureka-Server服务
@EnableEurekaServer
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Eureka客户端
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
// 注解开启Eureka-Client服务
@EnableEurekaClient
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Eureka配置整体结构详解
我创建了Eureka客户端和Eureka服务端一共五个节点:各Eureka服务器结构如下:
|— EUREKA-SERVER
| |— 7000(服务端1)
| | |— USER-CONSUMER
| | | |— 7400(客户端消费者)
| | |— USER-PROVIDER
| | | |— 7300(客户端生产者1)
| | | |— 7301(客户端生产者2)
| |— 7001(服务端2)
| | |— USER-CONSUMER
| | | |— 7400(客户端消费者)
| | |— USER-PROVIDER
| | | |— 7300(客户端生产者1)
| | | |— 7301(客户端生产者2)
由树结构可知
- 端口7000和7001作为服务端,我将其他端口客户端全部注册到这两个服务端之下。
- 这里面是有分组结构的,原因是application.yml中配置的spring.application.name属性。
Eureka配置界面展示
大家会发现【7000服务端】的Eureka展示界面中间多了一行明显的红字
THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
,这是为什么呢?因为我在7000服务端的配置文件中加入了
eureka.server.enableSelfPreservation: false
属性,意思就是关闭自我保护机制,那自我保护机制是什么意思呢?
自我保护机制
机制
Eureka在CAP理论当中是属于AP , 也就说当产生网络分区时,Eureka保证系统的可用性,但不保证系统里面数据的一致性
默认开启,服务器端容错的一种方式,即短时间心跳不到达仍不剔除服务列表里的节点
默认情况下,Eureka Server在一定时间内,没有接收到某个微服务心跳,会将某个微服务注销(90S)。但是当网络故障时,微服务与Server之间无法正常通信,上述行为就非常危险,因为微服务正常,不应该注销。
Eureka Server通过自我保护模式来解决整个问题,当Server在短时间内丢失过多客户端时,那么Server会进入自我保护模式,会保护注册表中的微服务不被注销掉。当网络故障恢复后,退出自我保护模式。
思想:宁可保留健康的和不健康的,也不盲目注销任何健康的服务。
自我保护触发条件
默认情况下,客户端每分钟续约数量小于客户端总数的85%时会触发保护机制
自我保护机制的触发条件:
(当每分钟心跳次数( renewsLastMin ) 小于 numberOfRenewsPerMinThreshold 时,并且开启自动保护模式开关( eureka.server.enableSelfPreservation = true ) 时,触发自我保护机制,不再自动过期租约。)
numberOfRenewsPerMinThreshold = expectedNumberOfRenewsPerMin * 续租百分比( eureka.server.renewalPercentThreshold, 默认0.85 )
expectedNumberOfRenewsPerMin = 当前注册的应用实例数 x 2
为什么乘以 2:
默认情况下,注册的应用实例每半分钟续租一次,那么一分钟心跳两次,因此 x 2 。
服务实例数:10个,期望每分钟续约数:10 * 2=20,期望阈值:20*0.85=17,自我保护少于17时 触发。