Eureka
“ Eureka ”來源于古希臘詞彙,意為“發現了”。在軟體領域, Eureka是一個開源的服務注冊與發現的元件,和其他Netflix公司的服務元件(例如負載均衡、熔斷器、網關等) 一起被Spring Cloud 社群整合為Spring Cloud Netflix 子產品。
本節将從以下4個方面來講解服務注冊與發現子產品Eureka :
1)Eureka 簡介;2)編寫一個Eureka 注冊和發現的例子;3)深入了解Eureka;4)編寫高可用的Eureka Server
一、Eureka 簡介
什麼是Eureka?
Eureka 是一個用于服務注冊和發現的元件,最開始主要應用于亞馬遜公司旗下的雲計算服務平台AWS;Eureka 分為Eureka Server 和Eureka Client, Eureka Server 為Eureka 服務注冊中心, Eureka Client 為Eureka 用戶端
為什麼選擇Eureka?
1)Eureka 完全開源, 經曆了Netflix 公司的生産環境的考驗,以及3年時間的不斷疊代,在功能和性能上都非常穩定可以放心使用;
2)Eureka 是Spring Cloud 首選推薦的服務注冊與發現元件, 與Spring Cloud 其他元件可以無縫對接;
3)Eureka 和其他元件,如負載均衡元件Ribbon 、熔斷器元件Hystrix、熔斷器監控元件Hystrix Dashboard 元件、熔斷器聚合監控Turbine 元件,以及網關Zuul 元件互相配合, 能夠很容易實作服務注冊、負載均衡、熔斷和智能路由等功能。這些元件都是由Netflix 公司開源的稱為Netflix OSS 元件;Netflix OSS 元件由Spring Cloud 整合為Spring Cloud Netflix 元件,是Spring Cloud 構架微服務的核心元件,也是基礎元件。
Eureka 的基本架構
Eureka 的基本架構如下圖所示:
主要包括以下3 種角色:
1)Register Service :服務注冊中心,它是一個Eureka Server ,提供服務注冊和發現的功能;
2)Provider Service :服務提供者,它是一個Eureka Client ,提供服務;
3)Consumer Service :服務消費者,它是一個Eureka Cient ,消費服務。
服務消費的基本過程如下:
1)需要一個服務注冊中心Eureka Server ,服務提供者Eureka Client 向服務注冊中心Eureka Server 注冊,将自己的資訊(比如服務名和服務的IP 位址等)通過REST API的形式送出給服務注冊中心Eureka Server ;
2)服務消費者Eureka Client 也向服務注冊中心 Eureka Server 注冊,同時服務消費者擷取一份服務注冊清單的資訊, 該清單
包含了所有向服務注冊中心Eureka Server 注冊的服務資訊;
3)擷取服務注冊清單資訊之後,服務消費者就知道服務提供者的IP 位址,可以通過Http遠端排程來消費服務提供者的服務。
二、編寫 Eureka Server
由于本案例有多個Spring Boot 工程,為了友善管理,采用 Maven 多 Module 的結構,是以需要建立一個Maven 主工程,本案例最終完整項目的結構如下:
建立完主Maven 工程之後,在主Maven 的pom 檔案下,引入eureka-client 和eureka-server兩個Module 工程共同所需的依賴,包括版本為1 . 5 . 3.RELEASE 的Spring Boot 依賴,版本為Dalston.SRI 的Spring Cloud 依賴,指定Java 版本為1.8 ,編碼為UTF-8;主 Maven 的pom 檔案代碼如下: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.forezp</groupId>
<artifactId>chapter5-2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>eureka-client</module>
<module>eureka-server</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.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>Dalston.SR1</spring-cloud.version>
</properties>
<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>
建立完主Maven 工程且配置完主工程的pom檔案後,建立一個Module 工程,命名為eureka-server。采用Spring Initializr 的方式建構, 作為服務注冊中心Eureka Server 的工程, 其工程目錄結構如下:
在 eureka-server 工程的pom檔案引入相關的依賴, 包括繼承了主Maven 工程的pom 檔案,引入了Eureka Server的起步依賴spring-cloud-starter-eureka-server,以及Spring Boot 測試的起步依賴spring-boot-starter-test ;最後還引入了Spring Boot 的Maven 插件spring-boot-maven-plugin , 有了該插件, 即可使用Maven 插件的方式來啟動Spring Boot 工程。具體代碼如下:
<?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.forezp</groupId>
<artifactId>eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eureka-server</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.forezp</groupId>
<artifactId>chapter5-2</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在工程的配置檔案application.yml 中做程式的相關配置, 首先通過server.port 指定Eureka Server 的端口為8761 ,在預設情況下, Eureka Server 會向自己注冊,這時需要配置 eureka.client.registerWithEureka 和 eureka.client. fetchRegistry 為false ,防止自己注冊自己。配置檔案application.yml 的代碼如下:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
在工程的啟動類 EurekaServerApplication 加上注解@EnableEurekaServer , 開啟 Eureka Server 的功能。代碼如下:
EurekaServerApplication.java :
package com.forezp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
到此為止, Eureka Server 的所有搭建工作已經完成;
啟動程式啟動類 EurekaServerApplication 的main 方法,啟動程式;在浏覽器上通路Eureka Server 的主界面 http://localhost:8761, 在界面上的Instances currently registered with Eureka 這一項上沒有任何注冊的執行個體,沒有是正常的,
因為還沒有Eureka Client 用戶端向注冊中心Eureka Server 注冊執行個體。Eureka Server 的主界面如下圖:
三、編寫 Eureka Client
在主Maven 工程中建立一個新的Module 工程,命名為eureka-client , 該工程作為Eureka Client 的工程向服務注冊中心Eureka server 注冊,目錄結構如下圖:
eureka-client 工程建立完之後, 在其pom檔案中引入相關的依賴,其pom 檔案繼承了主工程的pom檔案, 并且需要引入Eureka Client 用戶端所需的依賴spring-cloud-starter-eureka,引入Web 功能的起步依賴spring-boot- starter-web,
以及Spring Boot 測試的起步依賴spring-boot-starter-test , 具體代碼如下: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.forezp</groupId>
<artifactId>eureka-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eureka-client</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.forezp</groupId>
<artifactId>chapter5-2</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在工程的配置檔案bootstrap.yml 做Eureka Client 用戶端的相關配置,配置了程式名為eureka-client ,程式端口為8762 ,服務注冊位址為 http://localhost:8761/eureka/ ,代碼如下:bootstrap.yml
server:
port: 8762
spring:
application:
name: eureka-client
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
在程式的啟動類 EurekaClientApplication 加上注解@EnableEurekaClient 開啟Eureka Client功能,其代碼如下:EurekaClientApplication.java
package com.forezp;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@EnableEurekaClient
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
啟動Eureka Client 工程, 啟動成功之後, 在控制台會列印出如下資訊:
INFO 3536 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_EUREKA-CLIENT/jianghaok.digitalchina.com:eureka-client:8762 - registration status: 204
以上的日志資訊說明Eureka Client 用戶端已經向Eureka Server 注冊了;在浏覽器上打開
Eureka Server 首頁 :http://localhost:8761/, 首頁顯示如下圖所示:
在上圖中, 在首頁上的Instances currently registered with Eureka 選項中己經有一個執行個體被注冊, Application 為EUREKA-CLIENT, Staus 為UPC 線上) , 端口為8762 ;這就說明Eureka Client己成功向Eureka Server 注冊。
在eureka-client 工程中寫一個API 接口。建立一個類Hi Controller , 在H iController 類加上@RestController 注解,開啟RestController 的功能。@ GetMapping 注解表明是一個Get 請求,其請求位址映射為“ /hi ”,其中@Value(”$ {server. port }”)向配置檔案讀取配置的端口資訊。其完整代碼如下:HiController.java
package com.forezp.web;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HiController {
@Value("${server.port}")
String port;
@GetMapping("/hi")
public String home(@RequestParam String name) {
return "hi " + name + ",i am from port:" + port;
}
}
在浏覽器上通路:http: //localhost:8762/hi?name=forezp ,浏覽器顯示如下的資訊:
————————————————————————————————————————————