Spring Cloud 之 服務註冊與發現 Eureka元件,Eureka Server叢集
Eureka是Netflix公司開源的一個服務註冊與發現元件,類似的元件還有Zookeeper、Consul。
Eureka分為Eureka Server(服務註冊中心,每個服務都在這裡註冊資訊,提供服務名、IP、埠等資訊)和Eureka Client(客戶端) ,Eureka Client又可以分為服務提供者和服務消費者,譬如兩個服務都在註冊中心註冊了,同時服務消費者從註冊中心Eureka Server獲得一份在註冊中心註冊的所有服務註冊資訊,服務消費者就知道了所有服務提供者的IP,通過Http遠端排程來消費服務提供者的服務,他們相互之間呼叫彼此的介面了。這樣既是服務的提供者又是服務消費者。
一、Eureka Server
此Demo要包含很多Spring Cloud的元件,專案為多model專案,先建立一個Maven工程,作為主工程。然後把src資料夾刪除。所有子模組都將繼承主工程的pom依賴。使用的依賴幾乎都是當前時間(2018-07)的最新版本。
改造主工程的pom依賴:
<?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>
<groupId>com.cloud</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging >pom</packaging>
<modules>
<module>eurekaclient</module>
<module>eurekaserver</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.3.RELEASE</version>
</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>
</project>
<modules>
<module>eurekaclient</module>
<module>eurekaserver</module>
</modules>
這個是後面新增了model新增進去的
右鍵專案名稱new–>model,通過Spring Initializr快速新建model:eurekaserver。可以在裡面勾選上你需要的依賴。
Eureka Server 的 pom.xml
<?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>
<groupId>com.cloud</groupId>
<artifactId>eurekaserver</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eurekaserver</name>
<description>Demo project for Spring Boot</description>
<parent>
<!--繼承主工程依賴-->
<groupId>com.cloud</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<!--eureka server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</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>
</project>
在應用主類標明Eureka Server註冊中心:@EnableEurekaServer
@SpringBootApplication
//啟動一個服務註冊中心
@EnableEurekaServer
public class EurekaserverApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaserverApplication.class, args);
}
}
在resourses檔案下新建application.yml配置檔案(更喜歡用yml格式)
server:
# 訪問地址 http://localhost:7777/
port: 7777
eureka:
instance:
hostname: localhost
client:
#預設情況下eureka server也是一個eureka client ,必須要指定一個 server。
#通過eureka.client.registerWithEureka:false和fetchRegistry:false來表明自己是一個eureka server.
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
二、Eureka Client
如上面一樣新建一個model:eurekaclient
pom.xml
<?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>
<groupId>com.cloud</groupId>
<artifactId>eurekaclient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eurekaclient</name>
<description>Demo project for Spring Boot</description>
<parent>
<!--繼承主工程依賴-->
<groupId>com.cloud</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.0.RELEASE</version>
</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>
</project>
應用主類上添加註解:@EnableEurekaClient
新增@RestController用作測試
@SpringBootApplication
//通過註解@EnableEurekaClient 表明自己是一個eurekaclient.
@EnableEurekaClient
@RestController
public class EurekaclientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaclientApplication.class, args);
}
@Value("${server.port}")
String port;
@RequestMapping("/hi")
public String home(@RequestParam String name) {
return "hi " + name + ",i am from port:" + port;
}
}
配置檔案:application.yml
eureka:
client:
serviceUrl:
# 在哪個服務註冊中心註冊自己
defaultZone: http://localhost:7777/eureka/
server:
port: 8002
spring:
application:
#若沒有配置serviceId,預設情況下spring.application.name相當於服務名
name: service-hi
三、測試
啟動eureka-server,然後啟動eureka-client,訪問:http://localhost:7777/
可以看到向服務註冊中心註冊的服務。status為UP說明服務線上。
訪問:http://localhost:8002/hi?name=mistra
Eureka Client在預設情況下會每隔30秒傳送一次心跳來進行服務續約,告知Eureka Server該Eureka Client仍然可用。如果Eureka Server 90秒內沒有收到心跳,Eureka Server會將該Eureka Client例項從註冊列表中刪除。
可以將伺服器Eureka Server 叢集部署,通過執行多個例項並要求它們相互註冊,可以使Eureka更具彈性和可用性,每個伺服器將註冊服務的狀態複製到其他伺服器。也就是說一個Eureka Client只需要在一個註冊中心註冊,這個Client的資訊就會被同步到其他的註冊中心。
四、構建高可用的Eureka Server 叢集
修改原來的eureka-server配置檔案:
spring:
profiles:
active: instanceOne
application:
name: eureka-service
eureka:
client:
#不向註冊中心註冊自己
register-with-eureka: false
server:
enable-self-preservation: false
#是否從eureka伺服器獲取註冊資訊,這裡不需要
fetch-registry: false
logging:
level:
com:
netflix:
eureka: OFF
discovery: OFF
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: ALWAYS
---
spring:
profiles: instanceOne
server:
port: 7777
eureka:
client:
service-url:
defaultZone: http://localhost:7778/eureka/
---
spring:
profiles: instanceTwo
server:
port: 7778
eureka:
client:
service-url:
defaultZone: http://localhost:7777/eureka/
記得關閉這個單例項配置
先啟動spring.profiles.active.instanceOne下的eureka-server例項,然後修改active為instanceTwo,再啟動一個eureka-server例項。讓兩個 Eureka 互相向對方註冊。
最後啟動eureka-client,並且只向7777埠的eureka-server註冊中心註冊。eureka-client還是預設的上面的那個配置。
檢視註冊中心:
埠7777:
埠7778:
eureka-client並沒有向7778埠的註冊中心註冊自己,但是7778埠也有eureka-client的資訊。兩個註冊中心 Eureka 相互註冊了,所有註冊到其中一個 Eureka 的服務例項資訊會同步到另一箇中。
把7777埠的eureka-server停了,eureka-client依然能夠訪問。