Spring Cloud(Finchley版本)系列教程(一) 服务注册与发现(eureka)
为了更好的浏览体验,欢迎光顾勤奋的凯尔森同学个人博客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 |
2.1 创建EurekaServer
在idea中,创建一个名称为eurekaServer
的Maven
工程。
pom.xml
文件增加Eureka
依赖,修改SpringCloud
版本为Finchley.SR2
,修改SpringBoot
版本为2.0.6.RELEASE
。
<?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 https://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.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cc.huerpu</groupId>
<artifactId>eurekaServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eurekaServer</name>
<description>eurekaServer</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>
<dependencies>
<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>Finchley.SR2</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>
修改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首页。
2.2 创建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
包。
<?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 https://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.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cc.huerpu</groupId>
<artifactId>eurekaClient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eurekaClient</name>
<description>eurekaClient</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>
<dependencies>
<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-actuator</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>Finchley.SR2</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>
启动项目,刷新http://eurekaClient:8761/
会看到EurekaClient
注册上来了。
2.3 添加EurekaServer
用户认证
在实际应用中,资源的访问都是需要认证的,接下来我们把EurekaServer
改造为需要认证的服务。
EurekaServer
添加security
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</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。这里就不做过多的介绍了。
三、创建一个eurekaClientConsumer调用eurekaClient服务
复制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
<?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 https://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.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cc.huerpu</groupId>
<artifactId>eurekaClientConsumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eurekaClientConsumer</name>
<description>eurekaClientConsumer</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>
<dependencies>
<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-actuator</artifactId>
</dependency>
<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>Finchley.SR2</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
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 的元数据
Eureka 的元数据有两种,标准元数据和自定义元数据。标准元数据有主机名、IP地址、端口号、状态页和健康检查等信息,这些信息都会被发布在服务注册表中,用于服务之间的调用。自定义元数据可以使用eureka.instance.metadata-map
配置。
可以通过http://eurekaserver:8761/eureka/apps
来查看eureka
中有哪些应用。
<applications>
<versions__delta>1</versions__delta>
<apps__hashcode>UP_3_</apps__hashcode>
<application>
<name>EUREKASERVER</name>
<instance>
<instanceId>localhost:eurekaServer:8761</instanceId>
<hostName>eurekaServer</hostName>
<app>EUREKASERVER</app>
<ipAddr>192.168.75.1</ipAddr>
<status>UP</status>
<overriddenstatus>UNKNOWN</overriddenstatus>
<port enabled="true">8761</port>
<securePort enabled="false">443</securePort>
<countryId>1</countryId>
<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwn</name>
</dataCenterInfo>
<leaseInfo>
<renewalIntervalInSecs>30</renewalIntervalInSecs>
<durationInSecs>90</durationInSecs>
<registrationTimestamp>1693982763311</registrationTimestamp>
<lastRenewalTimestamp>1693984895889</lastRenewalTimestamp>
<evictionTimestamp>0</evictionTimestamp>
<serviceUpTimestamp>1693982734094</serviceUpTimestamp>
</leaseInfo>
<metadata>
<management.port>8761</management.port>
</metadata>
<homePageUrl>http://eurekaServer:8761/</homePageUrl>
<statusPageUrl>http://eurekaServer:8761/actuator/info</statusPageUrl>
<healthCheckUrl>http://eurekaServer:8761/actuator/health</healthCheckUrl>
<vipAddress>eurekaServer</vipAddress>
<secureVipAddress>eurekaServer</secureVipAddress>
<isCoordinatingDiscoveryServer>true</isCoordinatingDiscoveryServer>
<lastUpdatedTimestamp>1693982763311</lastUpdatedTimestamp>
<lastDirtyTimestamp>1693982733236</lastDirtyTimestamp>
<actionType>ADDED</actionType>
</instance>
</application>
<application>
<name>EUREKACLIENT</name>
<instance>
<instanceId>localhost:eurekaClient:8000</instanceId>
<hostName>eurekaClient</hostName>
<app>EUREKACLIENT</app>
<ipAddr>192.168.75.1</ipAddr>
<status>UP</status>
<overriddenstatus>UNKNOWN</overriddenstatus>
<port enabled="true">8000</port>
<securePort enabled="false">443</securePort>
<countryId>1</countryId>
<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwn</name>
</dataCenterInfo>
<leaseInfo>
<renewalIntervalInSecs>30</renewalIntervalInSecs>
<durationInSecs>90</durationInSecs>
<registrationTimestamp>1693982763312</registrationTimestamp>
<lastRenewalTimestamp>1693984884241</lastRenewalTimestamp>
<evictionTimestamp>0</evictionTimestamp>
<serviceUpTimestamp>1693982751862</serviceUpTimestamp>
</leaseInfo>
<metadata>
<management.port>8000</management.port>
</metadata>
<homePageUrl>http://eurekaClient:8000/</homePageUrl>
<statusPageUrl>http://eurekaClient:8000/actuator/info</statusPageUrl>
<healthCheckUrl>http://eurekaClient:8000/actuator/health</healthCheckUrl>
<vipAddress>eurekaClient</vipAddress>
<secureVipAddress>eurekaClient</secureVipAddress>
<isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
<lastUpdatedTimestamp>1693982763312</lastUpdatedTimestamp>
<lastDirtyTimestamp>1693982751816</lastDirtyTimestamp>
<actionType>ADDED</actionType>
</instance>
</application>
<application>
<name>EUREKACLIENTCONSUMER</name>
<instance>
<instanceId>localhost:eurekaClientConsumer:8001</instanceId>
<hostName>eurekaClientConsumer</hostName>
<app>EUREKACLIENTCONSUMER</app>
<ipAddr>192.168.75.1</ipAddr>
<status>UP</status>
<overriddenstatus>UNKNOWN</overriddenstatus>
<port enabled="true">8001</port>
<securePort enabled="false">443</securePort>
<countryId>1</countryId>
<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwn</name>
</dataCenterInfo>
<leaseInfo>
<renewalIntervalInSecs>30</renewalIntervalInSecs>
<durationInSecs>90</durationInSecs>
<registrationTimestamp>1693984674119</registrationTimestamp>
<lastRenewalTimestamp>1693984884145</lastRenewalTimestamp>
<evictionTimestamp>0</evictionTimestamp>
<serviceUpTimestamp>1693984674119</serviceUpTimestamp>
</leaseInfo>
<metadata>
<management.port>8001</management.port>
</metadata>
<homePageUrl>http://eurekaClientConsumer:8001/</homePageUrl>
<statusPageUrl>http://eurekaClientConsumer:8001/actuator/info</statusPageUrl>
<healthCheckUrl>http://eurekaClientConsumer:8001/actuator/health</healthCheckUrl>
<vipAddress>eurekaClientConsumer</vipAddress>
<secureVipAddress>eurekaClientConsumer</secureVipAddress>
<isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
<lastUpdatedTimestamp>1693984674119</lastUpdatedTimestamp>
<lastDirtyTimestamp>1693984674059</lastDirtyTimestamp>
<actionType>ADDED</actionType>
</instance>
</application>
</applications>
我们在上面也有写了一个接口,用来获得eurekaClient服务
的相关实例。
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping("/eurekaClient-instance")
public List<ServiceInstance> showInfo() {
return this.discoveryClient.getInstances("eurekaClient");
}
<List>
<item>
<host>eurekaClient</host>
<port>8000</port>
<metadata>
<management.port>8000</management.port>
</metadata>
<secure>false</secure>
<uri>http://eurekaClient:8000</uri>
<serviceId>EUREKACLIENT</serviceId>
<instanceInfo>
<instanceId>localhost:eurekaClient:8000</instanceId>
<app>EUREKACLIENT</app>
<appGroupName />
<ipAddr>192.168.75.1</ipAddr>
<sid>na</sid>
<homePageUrl>http://eurekaClient:8000/</homePageUrl>
<statusPageUrl>http://eurekaClient:8000/actuator/info</statusPageUrl>
<healthCheckUrl>http://eurekaClient:8000/actuator/health</healthCheckUrl>
<secureHealthCheckUrl />
<vipAddress>eurekaClient</vipAddress>
<secureVipAddress>eurekaClient</secureVipAddress>
<countryId>1</countryId>
<dataCenterInfo _class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwn</name>
</dataCenterInfo>
<hostName>eurekaClient</hostName>
<status>UP</status>
<overriddenStatus>UNKNOWN</overriddenStatus>
<leaseInfo>
<renewalIntervalInSecs>30</renewalIntervalInSecs>
<durationInSecs>90</durationInSecs>
<registrationTimestamp>1693982763312</registrationTimestamp>
<lastRenewalTimestamp>1693984674011</lastRenewalTimestamp>
<evictionTimestamp>0</evictionTimestamp>
<serviceUpTimestamp>1693982751862</serviceUpTimestamp>
</leaseInfo>
<isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
<metadata>
<management.port>8000</management.port>
</metadata>
<lastUpdatedTimestamp>1693982763312</lastUpdatedTimestamp>
<lastDirtyTimestamp>1693982751816</lastDirtyTimestamp>
<actionType>ADDED</actionType>
<asgName />
</instanceInfo>
<scheme />
</item>
</List>
五、Eureka的健康检查
在pom文件中引入Spring Boot Actuator,它提供了/health端点,该端点可展示应用程序的健康信息。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</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/
六、部署eurekaserver到ubuntu22.04服务器
每次都启动eureka的项目,太繁琐了,我们把eureka部署到Ubuntu,就可以愉快的玩耍了。最好部署到一台可以远程访问的服务器,这样在任何地方都可以注册服务和消费服务了。
6.1 配置文件设置
这里为了演示,我们准备好了一台 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
6.2 生成eurekaserver的jar包
生成eurekaserver的jar包:
6.3 ubuntu安装jdk1.8
sudo su -
apt update
apt upgrade -y
apt install openjdk-8-jre-headless
java -version
6.4 运行eurekaServer-0.0.1-SNAPSHOT.jar包
我们把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
6.5 验证eurekaserver服务
打开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,查看服务是否注册上来。
文章来源:https://www.toymoban.com/news/detail-704379.html
七、eureka相关说明
7.1 EurekaServer REST API接口
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地址查询
7.2 Client端参数
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)
7.3 Server端参数
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
文章来源地址https://www.toymoban.com/news/detail-704379.html
到了这里,关于Spring Cloud(Finchley版本)系列教程(一) 服务注册与发现(eureka)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!