为了更好的浏览体验,欢迎光顾勤奋的凯尔森同学个人博客http://www.huerpu.cc:7000
如有错误恳请大家批评指正,与大家共同学习、一起成长,万分感谢。
Spring Cloud的构建工具可以使用Maven或Gradle,但Maven任然是主流。本文档所使用的开发环境如下:
| 环境参数 | 版本 |
|---|---|
JDK | 8 |
Maven | 3.9.4 |
Spring Cloud | Finchley |
| IDE | idea2023.1.1 U |
| OS | Windows11专业版 |
Spring Cloud相关模块
| 模块 | 说明 |
|---|---|
| Eureka | 服务注册中心,用于服务管理 |
| Ribbon | 基于客户端的负载均衡组件 |
| Hystrix | 容错框架,能够防止服务的雪崩效应 |
| Feign | Web服务客户端,能够简化HTTP接口的调用 |
| Zuul | API网关,提供路由转发、请求过滤等功能 |
| Config | 分布式配置管理 |
| Sleuth | 服务跟踪 |
| Stream | 构建消息驱动的微服务应用程序的框架 |
| Bus | 消息代理的集群消息总线 |
但Spring Cloud主要有5大组件,分别为服务发现组件Eureka、Feign、Ribbon、Zuul、Hystrix。但很多都弃用了,比如Ribbon等。
注:SpringCloud版本说明
| 英文 | 中文 | boot大版本 | boot代表 |
|---|---|---|---|
| Angel | 安吉尔 | 1.2.X | 1.2.8 |
| Brixton | 布里克斯顿 | 1.3.X | 1.3.8 |
| Camden | 卡梅登 | 1.4.X | 1.4.2 |
| Dalston | 达斯顿 | 1.5.X | 1.5.0 |
| Edgware | 艾奇韦尔 | 1.5.X | 1.5.19 |
| Finchley | 芬奇利 | 2.0.X | 2.0.8 |
| Greenwich | 格林威治 | 2.1.X | 2.1.2 |
| Hoxton | 霍克斯顿 | 2.2.X | 2.2.6 |
| 2020.0.6-aka Ilford | 埃福的 | 2.5.7 | 2.5.7 |
| 2021.0.6 Jubilee | 朱比利 | 2.6.x | 2.6.1 |
| 2022.0.0 Kilburn | 基尔伯恩 | 3.0.x | 3.0.5 |
Spring Cloud提供了很多服务发现组件,比如:Eureka、Consul、ZooKeeper等。而Eureka是Netflix开源的服务发现组件,它包含Server和Client两部分。Eureka Server提供服务发现的能力,每个微服务启动时,都会向Eureka Server注册自己的信息(IP、端口、微服务名称等),Eureka Server存储记录每个微服务的这些信息。Eureka Client是用于简化与Eureka Server交互的Java客户端。微服务启动后,会周期性地(默认30s)向Eureka Server发送心跳以续约自己的可用时间。如果Eureka Server在规定的时间内没有接收到微服务实例的心跳,Eureka Server则会将该实例注销(默认90s)。
常见的注册中心
| 组件名 | 语言 | CAP | 一致性算法 | 服务健康检查 | 对外暴露接口 |
|---|---|---|---|---|---|
| Eureka | Java | AP | 无 | 可配支持 | HTTP |
| Consul | Go | CP | Raft | 支持 | HTTP/DNS |
| Zookeeper | Java | CP | Paxos | 支持 | 客户端 |
| Nacos | Java | AP | Raft | 支持 | HTTP |
EurekaServer在idea中,创建一个名称为eurekaServer的Maven工程。




pom.xml文件增加Eureka依赖,修改SpringCloud版本为Finchley.SR2,修改SpringBoot版本为2.0.6.RELEASE。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.6.RELEASEversion>
<relativePath/>
parent>
<groupId>cc.huerpugroupId>
<artifactId>eurekaServerartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>eurekaServername>
<description>eurekaServerdescription>
<properties>
<java.version>1.8java.version>
<spring-cloud.version>Finchley.SR2spring-cloud.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>Finchley.SR2version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
修改EurekaServerApplication启动类,增加@EnableEurekaServer注解。
package cc.huerpu.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
创建application.yml文件
server:
port: 8761 # 端口号
spring:
application:
name: eurekaServer # Eureka名称
eureka:
instance:
prefer-ip-address: false
hostname: eurekaServer
client:
fetch-registry: false # 表示是否从EurekaServer获取注册信息,默认为true。因为本应用是一个单点的EurekaServer,不需要同步其他的EurekaServer节点的数据,因此设为false。
register-with-eureka: false # 是否将自己注册到EurekaServer,默认为true。由于当前应用就是EurekaServer,因此设为false。
service-url:
defaultZone: http://eurekaServer:8761/eureka/
修改系统的hosts,Windows11的hosts文件路径为:C:\Windows\System32\drivers\etc\hosts。Linux和macOS的文件路径为/etc/hosts。增加一行:127.0.0.1 eurekaServer。
启动项目,并测试访问
点击idea的项目启动按钮,并访问http://eurekaserver:8761/查看Eureka首页。

EurekaClient,并让它注册到EurekaServer上。复制eurekaServer项目,修改artifactId为EurekaClient。修改application.yml文件,端口号为8000,应用名称为eurekaClient。
server:
port: 8000 # 端口号
spring:
application:
name: eurekaClient # Eureka名称
management:
info:
env:
enabled: true
endpoints:
web:
exposure:
include: "*"
enabled-by-default: true
eureka:
instance:
prefer-ip-address: false
hostname: eurekaClient
client:
healthcheck:
enabled: true
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://eurekaServer:8761/eureka/
修改启动类,增加@EnableDiscoveryClient注解。
package cc.huerpu.eurekaclient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
编写一个测试接口,最简单的那种就好。
@RestController
public class UserController {
@RequestMapping("/getUserById")
public String getUserById(){
return "{id:1,name:jason,age:23}";
}
}
修改pom.xml文件,把几处地方改为eurekaClient,另外增加了一个actuator包。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.6.RELEASEversion>
<relativePath/>
parent>
<groupId>cc.huerpugroupId>
<artifactId>eurekaClientartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>eurekaClientname>
<description>eurekaClientdescription>
<properties>
<java.version>1.8java.version>
<spring-cloud.version>Finchley.SR2spring-cloud.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>Finchley.SR2version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
启动项目,刷新http://eurekaClient:8761/会看到EurekaClient注册上来了。

EurekaServer用户认证在实际应用中,资源的访问都是需要认证的,接下来我们把EurekaServer 改造为需要认证的服务。
EurekaServer 添加security依赖:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
修改EurekaServer的application.yml文件,增加security认证,增加spring.security.user.name和spring.security.user.password。并修改defaultZone为http://eurekaha:eurekapwd@eurekaServer:8761/eureka/。
server:
port: 8761 # 端口号
spring:
security:
user:
name: eureka
password: eurekapwd
application:
name: eurekaServer # Eureka名称
eureka:
instance:
prefer-ip-address: false
hostname: eurekaServer
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://eureka:eurekapwd@eurekaServer:8761/eureka/
在EurekaServer的cc.huerpu.eurekaserver.security包路径下创建WebSecurityConfig类,关闭csrf,并开启httpBasic认证。
package cc.huerpu.eurekaserver.security;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
}
重新启动项目,访问时需要认证登录。

输入配置文件里的账号/密码:eureka/eurekapwd进行登录。

如果你的没有注册上来,耐心等一分钟就可以了。
对于创建Eureka的注册中心集群,请参考文章:http://www.huerpu.cc:7000/?p=607。这里就不做过多的介绍了。
复制eurekaClient项目,修改artifactId为eurekaClientConsumer。修改application.yml文件,端口号为8001,应用名称为eurekaClientConsumer(本机host中也增加这一个)。
127.0.0.1 localhost
127.0.0.1 eurekaServer
127.0.0.1 eurekaClient
127.0.0.1 eurekaclientconsumer
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.6.RELEASEversion>
<relativePath/>
parent>
<groupId>cc.huerpugroupId>
<artifactId>eurekaClientConsumerartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>eurekaClientConsumername>
<description>eurekaClientConsumerdescription>
<properties>
<java.version>1.8java.version>
<spring-cloud.version>Finchley.SR2spring-cloud.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>Finchley.SR2version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
application.yml
server:
port: 8001 # 端口号
spring:
application:
name: eurekaClientConsumer # Eureka名称
management:
info:
env:
enabled: true
endpoints:
web:
exposure:
include: "*"
enabled-by-default: true
eureka:
instance:
prefer-ip-address: false
hostname: eurekaClientConsumer
client:
healthcheck:
enabled: true
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://eureka:eurekapwd@eurekaServer:8761/eureka/
修改启动类名称为EurekaClientConsumerApplication,并增加注入一个restTemplate。
package cc.huerpu.eurekaclient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientConsumerApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
在controller包下创建一个ConsumerController类,注入restTemplate、eurekaClient、discoveryClient。
package cc.huerpu.eurekaclient.controller;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private EurekaClient eurekaClient;
@Autowired
private DiscoveryClient discoveryClient;
//获得eurekaClient的url
@RequestMapping("/eurekaClientServiceUrl")
private String eurekaClientServiceUrl() {
InstanceInfo instance = eurekaClient.getNextServerFromEureka("eurekaClient", false);
return instance.getHomePageUrl();
}
@RequestMapping("/consumerEurekaClient")
public String consumerEurekaClient(){
String eurekaClientURL = eurekaClientServiceUrl();
String res = restTemplate.getForObject(eurekaClientURL + "/getUserById",String.class);
return "consumerEurekaClient:" + res;
}
@RequestMapping("/eurekaClient-instance")
public List<ServiceInstance> showInfo() {
return this.discoveryClient.getInstances("eurekaClient");
}
}
在没有服务注册中心的时候,eurekaClientConsumer服务调用eurekaClient服务,需要在eurekaClientConsumer服务代码里显式通过硬编码IP地址和端口号进行调用,也可以通过@Value注入配置的方式进行配置,但被调用方方的IP和端口号变化之后,调用方就必须进行修改,针对千千万万的接口来说,维护这些信息简直是场噩梦。
@RestController
public class ConsumerController {
@RequestMapping("/consumerEurekaClient")
public String consumerEurekaClient(){
String res = restTemplate.getForObject("http://localhost:8000/getUserById", String.class);
return "consumerEurekaClient:" + res;
}
}
@RestController
public class ConsumerController {
//通过配置文件中的hep.eurekaclient.userservice.url值进行配置
@Value("${hep.eurekaclient.userservice.url}")
private String eurekaClient;
@RequestMapping("/consumerEurekaClient")
public String consumerEurekaClient(){
String res = restTemplate.getForObject("http://localhost:8000/getUserById", String.class);
return "consumerEurekaClient:" + res;
}
}
但现在我们通过eureka就没有这个烦恼啦,只需要eurekaClient.getNextServerFromEureka("eurekaClient", false),就可以获得服务的调用地址,其中"eurekaClient"是由spring.application.name指定的,即使被调用方的IP和端口号变化,对我们来说都是无感的,调用方这边完全不用做任何修改,是不是很开心?
访问http://eurekaclientconsumer:8001/consumerEurekaClient,就可以得到consumerEurekaClient:{id:1,name:jason,age:23},证明我们的消费方consumerEurekaClient调用被消费方eurekaClient成功了。

Eureka 的元数据有两种,标准元数据和自定义元数据。标准元数据有主机名、IP地址、端口号、状态页和健康检查等信息,这些信息都会被发布在服务注册表中,用于服务之间的调用。自定义元数据可以使用eureka.instance.metadata-map配置。
可以通过http://eurekaserver:8761/eureka/apps来查看eureka中有哪些应用。
<applications>
<versions__delta>1versions__delta>
<apps__hashcode>UP_3_apps__hashcode>
<application>
<name>EUREKASERVERname>
<instance>
<instanceId>localhost:eurekaServer:8761instanceId>
<hostName>eurekaServerhostName>
<app>EUREKASERVERapp>
<ipAddr>192.168.75.1ipAddr>
<status>UPstatus>
<overriddenstatus>UNKNOWNoverriddenstatus>
<port enabled="true">8761port>
<securePort enabled="false">443securePort>
<countryId>1countryId>
<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwnname>
dataCenterInfo>
<leaseInfo>
<renewalIntervalInSecs>30renewalIntervalInSecs>
<durationInSecs>90durationInSecs>
<registrationTimestamp>1693982763311registrationTimestamp>
<lastRenewalTimestamp>1693984895889lastRenewalTimestamp>
<evictionTimestamp>0evictionTimestamp>
<serviceUpTimestamp>1693982734094serviceUpTimestamp>
leaseInfo>
<metadata>
<management.port>8761management.port>
metadata>
<homePageUrl>http://eurekaServer:8761/homePageUrl>
<statusPageUrl>http://eurekaServer:8761/actuator/infostatusPageUrl>
<healthCheckUrl>http://eurekaServer:8761/actuator/healthhealthCheckUrl>
<vipAddress>eurekaServervipAddress>
<secureVipAddress>eurekaServersecureVipAddress>
<isCoordinatingDiscoveryServer>trueisCoordinatingDiscoveryServer>
<lastUpdatedTimestamp>1693982763311lastUpdatedTimestamp>
<lastDirtyTimestamp>1693982733236lastDirtyTimestamp>
<actionType>ADDEDactionType>
instance>
application>
<application>
<name>EUREKACLIENTname>
<instance>
<instanceId>localhost:eurekaClient:8000instanceId>
<hostName>eurekaClienthostName>
<app>EUREKACLIENTapp>
<ipAddr>192.168.75.1ipAddr>
<status>UPstatus>
<overriddenstatus>UNKNOWNoverriddenstatus>
<port enabled="true">8000port>
<securePort enabled="false">443securePort>
<countryId>1countryId>
<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwnname>
dataCenterInfo>
<leaseInfo>
<renewalIntervalInSecs>30renewalIntervalInSecs>
<durationInSecs>90durationInSecs>
<registrationTimestamp>1693982763312registrationTimestamp>
<lastRenewalTimestamp>1693984884241lastRenewalTimestamp>
<evictionTimestamp>0evictionTimestamp>
<serviceUpTimestamp>1693982751862serviceUpTimestamp>
leaseInfo>
<metadata>
<management.port>8000management.port>
metadata>
<homePageUrl>http://eurekaClient:8000/homePageUrl>
<statusPageUrl>http://eurekaClient:8000/actuator/infostatusPageUrl>
<healthCheckUrl>http://eurekaClient:8000/actuator/healthhealthCheckUrl>
<vipAddress>eurekaClientvipAddress>
<secureVipAddress>eurekaClientsecureVipAddress>
<isCoordinatingDiscoveryServer>falseisCoordinatingDiscoveryServer>
<lastUpdatedTimestamp>1693982763312lastUpdatedTimestamp>
<lastDirtyTimestamp>1693982751816lastDirtyTimestamp>
<actionType>ADDEDactionType>
instance>
application>
<application>
<name>EUREKACLIENTCONSUMERname>
<instance>
<instanceId>localhost:eurekaClientConsumer:8001instanceId>
<hostName>eurekaClientConsumerhostName>
<app>EUREKACLIENTCONSUMERapp>
<ipAddr>192.168.75.1ipAddr>
<status>UPstatus>
<overriddenstatus>UNKNOWNoverriddenstatus>
<port enabled="true">8001port>
<securePort enabled="false">443securePort>
<countryId>1countryId>
<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwnname>
dataCenterInfo>
<leaseInfo>
<renewalIntervalInSecs>30renewalIntervalInSecs>
<durationInSecs>90durationInSecs>
<registrationTimestamp>1693984674119registrationTimestamp>
<lastRenewalTimestamp>1693984884145lastRenewalTimestamp>
<evictionTimestamp>0evictionTimestamp>
<serviceUpTimestamp>1693984674119serviceUpTimestamp>
leaseInfo>
<metadata>
<management.port>8001management.port>
metadata>
<homePageUrl>http://eurekaClientConsumer:8001/homePageUrl>
<statusPageUrl>http://eurekaClientConsumer:8001/actuator/infostatusPageUrl>
<healthCheckUrl>http://eurekaClientConsumer:8001/actuator/healthhealthCheckUrl>
<vipAddress>eurekaClientConsumervipAddress>
<secureVipAddress>eurekaClientConsumersecureVipAddress>
<isCoordinatingDiscoveryServer>falseisCoordinatingDiscoveryServer>
<lastUpdatedTimestamp>1693984674119lastUpdatedTimestamp>
<lastDirtyTimestamp>1693984674059lastDirtyTimestamp>
<actionType>ADDEDactionType>
instance>
application>
applications>
我们在上面也有写了一个接口,用来获得eurekaClient服务的相关实例。
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping("/eurekaClient-instance")
public List<ServiceInstance> showInfo() {
return this.discoveryClient.getInstances("eurekaClient");
}
<List>
<item>
<host>eurekaClienthost>
<port>8000port>
<metadata>
<management.port>8000management.port>
metadata>
<secure>falsesecure>
<uri>http://eurekaClient:8000uri>
<serviceId>EUREKACLIENTserviceId>
<instanceInfo>
<instanceId>localhost:eurekaClient:8000instanceId>
<app>EUREKACLIENTapp>
<appGroupName />
<ipAddr>192.168.75.1ipAddr>
<sid>nasid>
<homePageUrl>http://eurekaClient:8000/homePageUrl>
<statusPageUrl>http://eurekaClient:8000/actuator/infostatusPageUrl>
<healthCheckUrl>http://eurekaClient:8000/actuator/healthhealthCheckUrl>
<secureHealthCheckUrl />
<vipAddress>eurekaClientvipAddress>
<secureVipAddress>eurekaClientsecureVipAddress>
<countryId>1countryId>
<dataCenterInfo _class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwnname>
dataCenterInfo>
<hostName>eurekaClienthostName>
<status>UPstatus>
<overriddenStatus>UNKNOWNoverriddenStatus>
<leaseInfo>
<renewalIntervalInSecs>30renewalIntervalInSecs>
<durationInSecs>90durationInSecs>
<registrationTimestamp>1693982763312registrationTimestamp>
<lastRenewalTimestamp>1693984674011lastRenewalTimestamp>
<evictionTimestamp>0evictionTimestamp>
<serviceUpTimestamp>1693982751862serviceUpTimestamp>
leaseInfo>
<isCoordinatingDiscoveryServer>falseisCoordinatingDiscoveryServer>
<metadata>
<management.port>8000management.port>
metadata>
<lastUpdatedTimestamp>1693982763312lastUpdatedTimestamp>
<lastDirtyTimestamp>1693982751816lastDirtyTimestamp>
<actionType>ADDEDactionType>
<asgName />
instanceInfo>
<scheme />
item>
List>
在pom文件中引入Spring Boot Actuator,它提供了/health端点,该端点可展示应用程序的健康信息。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
引入Actuator后,在Eureka中开启健康检查。
eureka:
client:
healthcheck:
enabled: true #开启健康检查(依赖spring-boot-actuator)
访问http://localhost:8761/actuator/health可以查看Eureka的状态。
若出现下面红色警告,其实是Eureka进入自我保护模式。如果最近一分钟实际接收到的心跳值Renews除以期望的心跳阈值 Renews threshold小于等于0.85,即 Renews/Renews threshold≤0.85。
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
可以把renewal-percent-threshold调的小一些
eureka:
server:
renewal-percent-threshold: 0.49
或者暴力一点关闭自我保护模式
# 默认值是true
eureka:
server:
enable-self-preservation: false
默认情况下,服务注册到Eureka Server的过程较慢。在开发或测试时,常常希望能够加速这一过程,从而提升工作效率。
##默认是30,单位秒。设成一个更小的值,该配置用于设置Eureka Client向Eureka Server发送心跳的时间间隔
eureka:
instance:
lease-renewal-interval-in-seconds: 5
本文参考SpringCloud官方文档:
https://docs.spring.io/spring-cloud-netflix/docs/4.0.1/reference/html/
每次都启动eureka的项目,太繁琐了,我们把eureka部署到Ubuntu,就可以愉快的玩耍了。最好部署到一台可以远程访问的服务器,这样在任何地方都可以注册服务和消费服务了。
这里为了演示,我们准备好了一台 ubuntu22.04,IP地址为192.168.169.128 。
在eurekaserver项目,创建application-text.yml文件,内容如下
server:
port: 8761 # 端口号
spring:
security:
user:
name: eureka
password: eurekapwd
application:
name: eurekaServer # Eureka名称
eureka:
server:
enable-self-preservation: true
instance:
prefer-ip-address: ture
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://eureka:eurekapwd@192.168.169.128:8761/eureka/
application.properties中增加让test生效配置。
spring.profiles.active=test
生成eurekaserver的jar包:

sudo su -
apt update
apt upgrade -y
apt install openjdk-8-jre-headless
java -version
我们把eurekaServer-0.0.1-SNAPSHOT.jar包 放在/usr/software目录下,根据个人喜好目录存放即可。使用MobaXterm等SSH工具上传即可。
cd /usr
#创建software文件夹,在此文件夹下有我们的eurekaServer-0.0.1-SNAPSHOT.jar包,可以通过上传工具上传过来
mkdir software
#赋予权限
chmod -R 777 software
#进入到software目录
cd software
#运行jar包
nohup java -jar eurekaServer-0.0.1-SNAPSHOT.jar > log.txt &
#开放8761端口
ufw allow 8761
ufw enable
打开http://192.168.169.128:8761/查看,Eureka已经启动了。

把eurekaClient项目修改defaultZone为http://eureka:eurekapwd@192.168.169.128:8761/eureka/,prefer-ip-address改为true
defaultZone: http://eureka:eurekapwd@192.168.169.128:8761/eureka/
prefer-ip-address: true
重启eurekaClient项目,并刷新eurekaserver,查看服务是否注册上来。

POST /eureka/apps/{appId} 注册新的实例
DELETE /eureka/apps/{appId}/{instanceId} 注销应用实例
PUT /eureka/apps/{appId}/{instanceId} 应用实例发送心跳
GET /eureka/apps 查询所有的实例
GET /eureka/apps/{appId} 查询指定appId的实例
GET /eureka/apps/{appId}/{instanceId} 查询指定appId和instanceId的实例
GET /eureka/instances/{instanceId} 查询指定的instanceId的实例
PUT /eureka/apps/{appId}/{instanceId}/status?value=OUT_OF_SERVICE 暂停应用实例
PUT /eureka/apps/{appId}/{instanceId}/status?value=UP 恢复应用实例
PUT /eureka/apps/{appId}/{instanceId}/metadata?key=value 更新元数据信息
GET /eureka/vips/{vipAddress} 根据vip地址查询
GET /eureka/svips/{svipAddress} 根据svip地址查询
eureka.client.register-with-eureka: true 是否注册自己到Eureka Server上面
eureka.client.fetch-registry: true 是否从Eureka Server上面拉取服务信息
eureka.client.enable: true 是否启用Eureka客户端,不启用则不注册到Eureka Server
eureka.client.healthcheck.enable: true 是否启用Eureka健康检查
eureka.client.availability-zones: new HashMap<>() 告诉client有哪些可用的region和zone
eureka.client.filter-only-up-instances: true 是否过滤出InstanceStatus为UP的实例
eureka.client.region: us-east-1 指定该应用实例所在的region,AWS datacenters适用
eureka.client.prefer-same-zone-eureka: true 是否优先使用与该应用相同Zone的Eureka Server
eureka.client.cache-refresh-executor-thread-pool-size: 2 缓存刷新线程池CacheRefreshThread的初始化线程数
eureka.client.registry-fetch-interval-seconds: 30 Eureka client拉取服务注册信息间隔时间(s)
eureka.client.instance-info-replication-interval-seconds: 30 复制实例变化信息到Eureka服务器所需要的时间间隔(s)
eureka.client.eureka-service-url-poll-interval-seconds: 300 轮询Eureka服务端地址更改的间隔时间(s)
eureka.client.eureka-server-read-timeout-seconds: 8 读取Eureka Server信息的超时时间(s)
eureka.client.eureka-server-connect-timeout-seconds: 5 连接Eureka Server的超时时间(s)
eureka.client.eureka-server-total-connections: 200 从Eureka客户端到所有Eureka服务端的连接总数
eureka.client.eureka-server-total-connections-per-host: 50 从Eureka客户端到每个Eureka服务端主机的连接总数
eureka.client.eureka-connection-idle-timeout-seconds: 30 Eureka服务端连接的空闲关闭时间(s)
eureka.instance.metadata-map: new HashMap<>() 指定应用实例的元数据信息
eureka.instance.prefer-ip-address: false 是否优先使用ip地址来替代hostname作为实例hostname字段值
eureka.instance.lease-expiration-duration-in-seconds: 90 Eureka clent最后一次心跳后,Eureka Server剔除需要等待时间(s)
eureka.instance.lease-renewal-interval-in-seconds: 30 客户端向Eureka Server发送心跳周期(s)
eureka.server.enable-self-preservation: true Eureka Server是否开启自我保护模式
eureka.server.renewal-percent-threshold: 0.85 指定每分钟需要收到的续约次数的阙值,如果阈值比最小值大,则自我保护模式开启
eureka.server.eviction-interval-timer-in-ms: 60*1000 指定EvictionTask定时任务的调度频率,用于剔除过期的实例
eureka.server.wait-time-in-ms-when-sync-empty: 1000*60*5 在Eureka服务器获取不到集群里对等服务器上的实例时,需要等待的时间
代码共享地址:
http://www.huerpu.cc:2080/root/springcloud-finchley