SpringCloud進擊 | 一淺出:服務註冊與發現(Eureka)【Finchley版本】
1.前言
Spring Cloud 已經幫我們實現了服務註冊中心,我們只需要很簡單的幾個步驟就可以完成。關於理論知識,我想大家都已經有不同程度上的瞭解和認識,這裡,我們最後再進行總結。本系列 Spring Cloud 介紹基於 Spring Boot 2.0.5 版本和 Spring Cloud Finchley.SR1 版本。
Finchley 版與 Spring Boot 2.0.x 相容,不支援 Spring Boot 1.5.x.
Spring Cloud 為避免與子專案的釋出號混淆,所以沒有采用版本號的方式,而是通過命名的方式。這些版本名稱的命名方式採用了倫敦地鐵站的名稱,同時根據字母表的順序來對應版本時間順序,比如:最早的Release版本:Angel,第二個Release版本:Brixton,然後是Camden、Dalston、Edgware,目前最新的是Finchley版本。
2.準備
我們需要:
- JDK 1.8或以上
- Maven 3.0或以上
- IntelliJ IDEA
另,Spring Cloud 是基於 Spring Boot 的,所以需要我們對 Spring Boot 有一定的瞭解。如果有需要,可以先去連結過一下:
SpringBoot進擊 | 一淺出:Spring Boot簡單快速上手書
SpringBoot進擊 | 二淺出:Spring Boot配置詳解
Finchley版本的官方文件: http://cloud.spring.io/spring-cloud-static/Finchley.RELEASE/single/spring-cloud.html
3.進擊
Eureka 這個詞來源於古希臘語,意為 “我找到了!我發現了!”,據傳,阿基米德在洗澡時發現浮力原理,高興得來不及穿上褲子,跑到街上大喊:“Eureka(我找到了)!”。
實踐出真知。
新建一個Maven工程
為了與後面的演練行成連貫性、系統性,這裡我們需要先建立一個Maven主專案。主專案的 pom.xml 檔案作用於版本控制、依賴管理,其它子模組都繼承於該父 pom.xml。
a) File >> New >> Project >> Maven:Project SDK:1.8 >> [Next]
b)
c) 專案名稱、路徑設定 >> [Finish]
3.1. 服務註冊
3.1.1 建立服務註冊中心(Eureka Server)
3.1.1.1 專案名稱右鍵 >> Model >> 選擇 Spring Initializr >> Module SDK:1.8;choose Initializr Service URL:Default >> [Next]
3.1.1.2 填寫Group、Artifact等專案資訊 >> [Next]
3.1.1.3 Dependencies:專案依賴選擇,選擇 Cloud Discovery,並鉤上 Eureka Server; Spring Boot 版本選擇,這裡我們使用 2.0.5 版本 >> [Next]
3.1.1.4 模組名稱、路徑設定 >> [Finish]
如此,一個畫風乾淨的 Spring Cloud Eureka Server (Eureka服務註冊中心)就映入眼簾。
因為,它是我們這個專案的一個子模組,它繼承了父pom檔案(parent標籤),並引入了 spring-cloud-starter-netflix-eureka-server 核心依賴,Eureka服務註冊中心的 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.wei</groupId>
<artifactId>wei-eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>wei-eureka-server</name>
<description>服務註冊中心(Eureka Server)</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</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.SR1</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>${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>
3.1.2 配置服務註冊中心
在預設設定下,服務註冊中心會將自己作為客戶端來嘗試註冊它自己,所以我們需要禁用它的客戶端註冊行為(預設情況下 Erureka Server 也是一個 Eureka Client,必須要指定一個 Server)。這隻需要在 application.yml (如果創建出來的是properties檔案,可以直接rename成yml)配置檔案中配置以下資訊:
server:
port: 8090 # 服務註冊中心埠號配置
eureka:
instance:
hostname: localhost # 服務註冊中心例項的主機名
client:
register-with-eureka: false # 表示是否註冊自身到eureka伺服器,因為當前這個應用就是eureka伺服器,沒必要註冊自身
fetch-registry: false # 表示是否從eureka伺服器獲取註冊資訊,同上,這裡不需要
service-url: # defaultZone是指定eureka伺服器的地址,無論是註冊還是發現服務都需要這個地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
enable-self-preservation: false # 簡單粗暴把自我保護模式關閉
- eureka.client.register-with-eureka:表示是否將自己註冊到 Eureka Server,預設為 true
- eureka.client.fetch-registry:表示是否從 Eureka Server 獲取註冊資訊,預設為 true
- eureka.client.service-url.defaultZone:是指定 Eureka Server 的地址,無論是註冊還是發現服務都需要這個地址
3.1.3 啟動服務註冊中心
要啟動一個服務註冊中心,只需要在我們剛剛新建的 Eureka Server 模組的啟動類上新增 @EnableEurekaServer 註解即可。
package com.wei;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* 註解@EnableEurekaServer,開啟Eureka服務註冊中心功能
*/
@SpringBootApplication
@EnableEurekaServer
public class WeiEurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(WeiEurekaServerApplication.class, args);
}
}
然後,Run 該啟動類。
如此,一個 Spring Eureka Server 服務註冊中心就被我們建好了。
3.1.4 解讀服務註冊中心
Spring Eureka 服務註冊中心提供了可視介面(Eureka資訊面板)。
我們可以去剛剛配置的URL地址看一下:http://localhost:8090/
當前因為還沒有服務被註冊,所以沒服務可以被發現。
各項備註一下:
System Status
Environment | 指定環境,預設為test, 實際使用過程中,可以不用更改 |
Data center | 資料中心 |
Current time | 當前系統時間 |
Uptime | 已執行時長 |
Lease expiration enabled | 是否啟用租約過期, 自我保護機制關閉時,該值預設是true, 自我保護機制開啟之後為false |
Renews threshold | server 期望在每分鐘中收到的心跳次數 |
Renews (last min) | 上一分鐘內收到的心跳次數 |
DS Replicas
Instances currently registered with Eureka | 當前註冊到服務註冊中心內的服務 |
No instances available | 沒有服務被發現 |
General Info
total-avail-memory | 總共可用的記憶體 |
environment | 環境名稱,預設test |
num-of-cpus | CPU個數 |
current-memory-usage | 當前已經使用記憶體的百分比 |
server-uptime | 服務線上時間 |
registered-replicas | 相鄰叢集複製節點 |
unavailable-replicas | 不可用的叢集複製節點 |
available-replicas | 可用的相鄰叢集複製節點 |
Instance Info
ipAddr | 例項IP地址 |
status | 例項狀態 |
Eureka資訊面板的紅字提醒
Spring Eureka 服務註冊中心在三種情況下會出現紅色加粗的字型提示:
1)自我保護機制開啟時(enable-self-preservation: true):
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.
2)自我保護機制關閉時(enable-self-preservation: false):
RENEWALS ARE LESSER THAN THE THRESHOLD. THE SELF PRESERVATION MODE IS TURNED OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
3)自我保護機制關閉了,但是一分鐘內的續約數沒有達到85%,可能發生了網路分割槽,會有如下提示
THE SELF PRESERVATION MODE IS TURNED OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
3.2. 服務發現
3.2.1 建立一個服務提供者(Eureka Client)
服務提供者,也就是 Service Provider,做為一個 Eureka Client,向 Eureka Server 做服務註冊、續約和下線等操作,註冊的主要資料包括服務名、機器IP、埠號、域名等等。
建立步驟與上面的 Eureka Server 建立過程類似,但在Dependencies選擇依賴時,
a) 選擇左側的 Cloud Discovery 後,這裡需要鉤上 Eureka Discovery 項
b) 選擇左側的 Web 後,這裡需要鉤上 Web 項
建立完後的 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.wei</groupId>
<artifactId>wei-service-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>wei-service-provider</name>
<description>服務提供者(Eureka Client)</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</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.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</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>
</project>
3.2.2 配置服務提供者
修改配置檔案
server:
port: 8010
spring:
application:
name: wei-service-provider # 指定進行服務註冊時該服務的名稱,服務與服務之間相互呼叫一般都是根據這個name
eureka:
client:
service-url:
defaultZone: http://localhost:8090/eureka/ # 指定進行服務註冊地址
建立服務提供者的服務介面
package com.wei.controller.demo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoServiceController {
@Value("${spring.application.name}")
private String serviceName;
@Value("${server.port}")
private String port;
@RequestMapping(value = "/demo/info")
public String getDemoInfo(@RequestParam String name) {
String result = "Hi," + name + ",我是服務,我被呼叫了,服務名為:" + serviceName + ",埠為:" + port;
System.out.println(result);
return result;
}
}
3.2.3 啟動服務提供者
要啟動一個服務提供者,只需要在我們剛剛新建的 Eureka Clinet 模組的啟動類上新增 @EnableEurekaClient 註解即可。
package com.wei;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* 註解@EnableEurekaClient,表明自己是一個Eureka Client
*/
@SpringBootApplication
@EnableEurekaClient
public class WeiServiceProviderApplication {
public static void main(String[] args) {
SpringApplication.run(WeiServiceProviderApplication.class, args);
}
}
然後,Run 該啟動類。
如此,一個 Spring Eureka Client 服務提供者就被我們建好了。
去驗證一下吧:http://localhost:8090/
如你所想,一個服務已經註冊在服務中心了,服務名為 WEI-SERVICE-PROVIDER,埠號為8010
再來看看介面:http://localhost:8010/demo/info?name=tester
瀏覽器列印:
Hi,tester,我是服務,我被呼叫了,服務名為:wei-service-provider,埠為:8010
到此,簡單易用的 Eureka Server 服務註冊中心就建立完成了。當然,還實現了一個 Eureka Client 服務提供者小樣。
官方參考文件:https://springcloud.cc/spring-cloud-config.html
原始碼:https://github.com/itanping/wei-springcloud/tree/master/chapter01-eureka
下一節,請繼續關注:SpringCloud進擊 | 二淺出:服務消費者(Ribbon+REST)【Finchley版本】