版本
sporingboot:2.0.5
springcloud:Finchley.RELEASE
创建Maven主工程
<?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.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.definesys</groupId>
<artifactId>my_cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>my_cloud</name>
<packaging>pom</packaging>
<description>Demo project for Spring Boot</description>
<modules>
<module>eurekaServer</module>
<module>sayHello</module>
</modules>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
创建model
创建两个model工程,创建model一个作为eureka server,一个是client也就是具体的服务。
- 创建eureka server
<?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>com.definesys</groupId>
<artifactId>my_cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.definesys</groupId>
<artifactId>eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-server</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置文件:
server.port=1111
eureka.instance.hostname=localhost
#这两个是表明自己是eureka Server
#是否向服务注册中心注册自己
eureka.client.register-with-eureka=false
#是否检索服务
eureka.client.fetch-registry=false
#关闭自我保护机制(生产环境建议开启)
#eureka.server.enable-self-preservation=true
#服务注册中心的配置内容,指定服务注册中心的位置
eureka.client.service-url.defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
spring.application.name: eurka-server
在启动类上添加@EnableEurekaServer
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
启动eureka server,在浏览器地址栏输入http://localhost:1111,可以看到erueka注册中心页面
- 创建服务提供者
<?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>com.definesys</groupId>
<artifactId>my_cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.definesys</groupId>
<artifactId>say-hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>say-hello</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置文件:
server.port=2222
#服务名称,服务与服务之间相互调用一般都是根据这个name
spring.application.name=say-hello
#注册中心地址
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
创建一个Controller
@RestController
public class SayHelloController {
@Value("${server.port}")
private String serverPort;
@GetMapping("/sayHello")
public String sayHelloCtr(@RequestParam("helloName")String helloName){
return "Hello "+helloName+",我的端口是: "+serverPort;
}
}
在启动类上添加@EnableEurekaClient表明自己是一个eureka client
@SpringBootApplication
@EnableEurekaClient
public class SayHelloApplication {
public static void main(String[] args) {
SpringApplication.run(SayHelloApplication.class, args);
}
}
启动服务访问http://localhost:1111,会发现服务已经注册到注册中心中去了。
Eureka自我保护机制
- 什么是自我保护
自我保护模式是一种针对网络异常波动的安全保护措施,使用自我保护模式能使Eureka集群更加的 健壮、稳定的运行。 - 工作机制
Eureka Server 如果在eureka注册中心中看见“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“这样一段话,则说明erueka进入自我保护。自我保护模式被激活的条件是:在 1 分钟后,Renews (last min)(Eureka Server 最后 1 分钟收到客户端实例续约的总数。) < Renews threshold(Eureka Server 期望每分钟收到客户端实例续约的总数。)。eureka在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期。一旦开启了保护机制,则服务注册中心维护的服务实例就不是那么准确了,在开发是可以配置eureka.server.enable-self-preservation=false关闭自我保护,这样可以确保注册中心中不可用的实例被及时的剔除 - eureka不清除已关节点问题
在开发过程中,我们常常希望Eureka Server能够迅速有效地踢出已关停的节点,但是由于Eureka自我保护模式,以及心跳周期长的原因,常常会遇到Eureka Server不踢出已关停的节点的问题
解决办法:
Eureka Server端:配置关闭自我保护,并按需配置Eureka Server清理无效节点的时间间隔。
eureka.server.enable-self-preservation # 设为false,关闭自我保护
eureka.server.eviction-interval-timer-in-ms # 清理间隔(单位毫秒,默认是60*1000)
Eureka Client端:配置开启健康检查,并按需配置续约更新时间和到期时间。
eureka.client.healthcheck.enabled # 开启健康检查(需要spring-boot-starter-actuator依赖)
eureka.instance.lease-renewal-interval-in-seconds # 续约更新时间间隔(默认30秒)
eureka.instance.lease-expiration-duration-in-seconds # 续约到期时间(默认90秒)
注:更改Eureka更新频率将打破服务器的自我保护功能,生产环境下不建议自定义这些配置。 - eureka服务端常用配置
(1)enable-self-preservation: true # 自我保护模式,当出现出现网络分区、eureka在短时间内丢失过多客户端时,会进入自我保护模式,即一个服务长时间没有发送心跳,eureka也不会将其删除,默认为true
(2)eviction-interval-timer-in-ms: 60000 #eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒
(3)renewal-percent-threshold: 0.85 #阈值因子,默认是0.85,如果阈值比最小值大,则自我保护模式开启
(4)peer-eureka-nodes-update-interval-ms: 600000 # 集群里eureka节点的变化信息更新的时间间隔,单位为毫秒,默认为10 * 60 * 1000
- eureka客户端常用配置
(1)register-with-eureka: false #是否注册到eureka
(2)registry-fetch-interval-seconds: 30 # 从eureka服务器注册表中获取注册信息的时间间隔(s),默认为30秒
(3)fetch-registry: false # 实例是否在eureka服务器上注册自己的信息以供其他服务发现,默认为true 如果是做高可用的发现服务那就要改成true
(4)instance-info-replication-interval-seconds: 30 # 复制实例变化信息到eureka服务器所需要的时间间隔(s),默认为30秒
(5)initial-instance-info-replication-interval-seconds: 40 # 最初复制实例信息到eureka服务器所需的时间(s),默认为40秒
(6)eureka-service-url-poll-interval-seconds: 300 #询问Eureka服务url信息变化的时间间隔(s),默认为300秒
(7)eureka-server-connect-timeout-seconds: 5 # eureka需要超时连接之前需要等待的时间,默认为5秒
(8)eureka-server-total-connections: 200 #eureka客户端允许所有eureka服务器连接的总数目,默认是200
(9)heartbeat-executor-thread-pool-size: 2 #心跳执行程序线程池的大小,默认为2
(10)cache-refresh-executor-thread-pool-size: 2 # 执行程序缓存刷新线程池的大小,默认为2
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。