Spring Cloud(Finchley版本)系列教程(一) 服務注冊與發(fā)現(xiàn)(eureka)
為了更好的瀏覽體驗,歡迎光顧勤奮的凱爾森同學個人博客http://www.huerpu.cc:7000
如有錯誤懇請大家批評指正,與大家共同學習、一起成長,萬分感謝。
一、構(gòu)建環(huán)境
Spring Cloud
的構(gòu)建工具可以使用Maven
或Gradle
,但Maven
任然是主流。本文檔所使用的開發(fā)環(huán)境如下:
環(huán)境參數(shù) | 版本 |
---|---|
JDK |
8 |
Maven |
3.9.4 |
Spring Cloud |
Finchley |
IDE | idea2023.1.1 U |
OS |
Windows11 專業(yè)版 |
Spring Cloud
相關(guān)模塊
模塊 | 說明 |
---|---|
Eureka | 服務注冊中心,用于服務管理 |
Ribbon | 基于客戶端的負載均衡組件 |
Hystrix | 容錯框架,能夠防止服務的雪崩效應 |
Feign | Web服務客戶端,能夠簡化HTTP接口的調(diào)用 |
Zuul | API網(wǎng)關(guān),提供路由轉(zhuǎn)發(fā)、請求過濾等功能 |
Config | 分布式配置管理 |
Sleuth | 服務跟蹤 |
Stream | 構(gòu)建消息驅(qū)動的微服務應用程序的框架 |
Bus | 消息代理的集群消息總線 |
但Spring Cloud
主要有5大組件,分別為服務發(fā)現(xiàn)組件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 |
二、微服務注冊與發(fā)現(xiàn)
Spring Cloud
提供了很多服務發(fā)現(xiàn)組件,比如:Eureka
、Consul
、ZooKeeper
等。而Eureka
是Netflix
開源的服務發(fā)現(xiàn)組件,它包含Server和Client兩部分。Eureka Server
提供服務發(fā)現(xiàn)的能力,每個微服務啟動時,都會向Eureka Server
注冊自己的信息(IP、端口、微服務名稱等),Eureka Server
存儲記錄每個微服務的這些信息。Eureka Client
是用于簡化與Eureka Server
交互的Java客戶端。微服務啟動后,會周期性地(默認30s)向Eureka Server
發(fā)送心跳以續(xù)約自己的可用時間。如果Eureka Server
在規(guī)定的時間內(nèi)沒有接收到微服務實例的心跳,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 創(chuàng)建EurekaServer
在idea中,創(chuàng)建一個名稱為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);
}
}
創(chuàng)建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節(jié)點的數(shù)據(jù),因此設(shè)為false。
register-with-eureka: false # 是否將自己注冊到EurekaServer,默認為true。由于當前應用就是EurekaServer,因此設(shè)為false。
service-url:
defaultZone: http://eurekaServer:8761/eureka/
修改系統(tǒng)的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 創(chuàng)建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
包路徑下創(chuàng)建WebSecurityConfig
類,關(guān)閉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
進行登錄。
如果你的沒有注冊上來,耐心等一分鐘就可以了。
對于創(chuàng)建Eureka的注冊中心集群,請參考文章:http://www.huerpu.cc:7000/?p=607。這里就不做過多的介紹了。
三、創(chuàng)建一個eurekaClientConsumer調(diào)用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
包下創(chuàng)建一個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服務調(diào)用eurekaClient服務,需要在eurekaClientConsumer服務代碼里顯式通過硬編碼IP地址和端口號進行調(diào)用,也可以通過@Value注入配置的方式進行配置,但被調(diào)用方方的IP和端口號變化之后,調(diào)用方就必須進行修改,針對千千萬萬的接口來說,維護這些信息簡直是場噩夢。
@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;
}
}
但現(xiàn)在我們通過eureka就沒有這個煩惱啦,只需要eurekaClient.getNextServerFromEureka("eurekaClient", false)
,就可以獲得服務的調(diào)用地址,其中"eurekaClient"
是由spring.application.name
指定的,即使被調(diào)用方的IP和端口號變化,對我們來說都是無感的,調(diào)用方這邊完全不用做任何修改,是不是很開心?
訪問http://eurekaclientconsumer:8001/consumerEurekaClient
,就可以得到consumerEurekaClient:{id:1,name:jason,age:23}
,證明我們的消費方consumerEurekaClient
調(diào)用被消費方eurekaClient
成功了。
四、Eureka 的元數(shù)據(jù)
Eureka 的元數(shù)據(jù)有兩種,標準元數(shù)據(jù)和自定義元數(shù)據(jù)。標準元數(shù)據(jù)有主機名、IP地址、端口號、狀態(tài)頁和健康檢查等信息,這些信息都會被發(fā)布在服務注冊表中,用于服務之間的調(diào)用。自定義元數(shù)據(jù)可以使用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服務
的相關(guān)實例。
@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的狀態(tài)。
若出現(xiàn)下面紅色警告,其實是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
調(diào)的小一些
eureka:
server:
renewal-percent-threshold: 0.49
或者暴力一點關(guān)閉自我保護模式
# 默認值是true
eureka:
server:
enable-self-preservation: false
默認情況下,服務注冊到Eureka Server
的過程較慢。在開發(fā)或測試時,常常希望能夠加速這一過程,從而提升工作效率。
##默認是30,單位秒。設(shè)成一個更小的值,該配置用于設(shè)置Eureka Client向Eureka Server發(fā)送心跳的時間間隔
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 配置文件設(shè)置
這里為了演示,我們準備好了一臺 ubuntu22.04
,IP地址為192.168.169.128
。
在eurekaserver
項目,創(chuàng)建application-text.yml
文件,內(nèi)容如下
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
目錄下,根據(jù)個人喜好目錄存放即可。使用MobaXterm
等SSH工具上傳即可。
cd /usr
#創(chuàng)建software文件夾,在此文件夾下有我們的eurekaServer-0.0.1-SNAPSHOT.jar包,可以通過上傳工具上傳過來
mkdir software
#賦予權(quán)限
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已經(jīng)啟動了。
把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,查看服務是否注冊上來。
文章來源:http://www.zghlxwxcb.cn/news/detail-704379.html
七、eureka相關(guān)說明
7.1 EurekaServer REST API接口
POST /eureka/apps/{appId} 注冊新的實例
DELETE /eureka/apps/{appId}/{instanceId} 注銷應用實例
PUT /eureka/apps/{appId}/{instanceId} 應用實例發(fā)送心跳
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 更新元數(shù)據(jù)信息
GET /eureka/vips/{vipAddress} 根據(jù)vip地址查詢
GET /eureka/svips/{svipAddress} 根據(jù)svip地址查詢
7.2 Client端參數(shù)
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 是否優(yōu)先使用與該應用相同Zone的Eureka Server
eureka.client.cache-refresh-executor-thread-pool-size: 2 緩存刷新線程池CacheRefreshThread的初始化線程數(shù)
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服務端的連接總數(shù)
eureka.client.eureka-server-total-connections-per-host: 50 從Eureka客戶端到每個Eureka服務端主機的連接總數(shù)
eureka.client.eureka-connection-idle-timeout-seconds: 30 Eureka服務端連接的空閑關(guān)閉時間(s)
eureka.instance.metadata-map: new HashMap<>() 指定應用實例的元數(shù)據(jù)信息
eureka.instance.prefer-ip-address: false 是否優(yōu)先使用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發(fā)送心跳周期(s)
7.3 Server端參數(shù)
eureka.server.enable-self-preservation: true Eureka Server是否開啟自我保護模式
eureka.server.renewal-percent-threshold: 0.85 指定每分鐘需要收到的續(xù)約次數(shù)的闕值,如果閾值比最小值大,則自我保護模式開啟
eureka.server.eviction-interval-timer-in-ms: 60*1000 指定EvictionTask定時任務的調(diào)度頻率,用于剔除過期的實例
eureka.server.wait-time-in-ms-when-sync-empty: 1000*60*5 在Eureka服務器獲取不到集群里對等服務器上的實例時,需要等待的時間
八、代碼地址
代碼共享地址:
http://www.huerpu.cc:2080/root/springcloud-finchley
文章來源地址http://www.zghlxwxcb.cn/news/detail-704379.html
到了這里,關(guān)于Spring Cloud(Finchley版本)系列教程(一) 服務注冊與發(fā)現(xiàn)(eureka)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!