版本
sporingboot:2.0.5springcloud: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