一、簡介
服務消費者需要一個強大的服務發現機制,服務消費者使用這種機制擷取服務提供者的網絡資訊。即使服務提供者的資訊發生變化,服務消費者也無須修改配置。
服務提供者、服務消費者、服務發現元件三者之間的關系大緻如下:
1.各個微服務在啟動時,将自己的網絡位址等資訊注冊到服務發現元件中,服務發現元件會存儲這些資訊。
2.服務消費者可以從服務發現元件查詢服務提供者的網絡位址,并使用該位址調用服務提供者的接口。
3.各個微服務與服務發現元件使用一定機制(如:心跳)通信,服務發現元件如長時間無法與某微服務執行個體通信,就會登出該執行個體。
4.微服務網絡位址發生變更時,會重新注冊到服務發現元件。
1.1、服務發現元件
服務發現元件應具備以下功能:服務系統資料庫、服務注冊與服務發現、服務檢查
1.1.1、服務系統資料庫
是服務發現元件的核心,用來記錄各個微服務的資訊,如服務名稱、IP、端口等。服務系統資料庫提供查詢API(用于查詢可用的微服務執行個體)和管理API(使用者服務的注冊與登出)
1.1.2、服務注冊與服務發現
服務注冊是指微服務在啟動時,将自己的資訊注冊到服務發現元件上的過程。服務發現是指查詢可用微服務清單及其網絡位址的機制。
1.1.3、服務檢查
服務發現元件使用一定機制定時檢測已注冊的服務,如發現某執行個體長時間無法通路,就會從服務系統資料庫中移除執行個體
Spring Cloud提供了多種服務發現元件的支援,如:Eureka、Zookeeper等。
二、Eureka
Eureka是Netflix開源的服務發現元件,本身是基于REST的服務。它包含Server和Client兩部分。Spring Cloud将其內建在子項目Spring Cloud Netflix中,進而實作微服務的注冊與發現。
Eureka的兩個元件
Eureka包含兩個元件:Eureka Server與Eureka Client,作用如下:
1、Eureka Server提供服務發現的能力,各個微服務啟動時,會向Eureka Server注冊自己的資訊(IP、端口、微服務名稱等),Eureka Server會存儲這些資訊。
2、Eureka Client是一個java用戶端,用于簡化與Eureka Server的互動。
3、微服務啟動後,會周期性(預設30秒)地向Eureka Server發送心跳以續約自己的“租期”。
4、如果Eureka Server在一定時間内沒有接收到某個微服務執行個體的心跳,Eureka Server将會登出該執行個體(預設90秒)
5、預設情況下,Eureka Server同時也是Eureka Client。多個Eureka Server執行個體,互相之間通過複制的方式,來實作服務系統資料庫中資料的同步。
6、Eureka Client會緩存服務系統資料庫中的資訊。這種方式有一定的優勢---首先,微服務無須每次請求都查詢Eureka Server,進而降低了Eureka Server的壓力;其次,即使Eureka Server所有的節點都宕掉,服務消費者依然可以使用緩存中的資訊找到服務提供者并完成調用。
綜上:Eureka通過心跳檢查、用戶端緩存等機制,提高了系統的靈活性、可伸縮性和可用性
2.1、編寫Eureka Server
2.1.1 建立springboot工程
建立一個springboot(1.5.4.RELEASE)工程,再添加如下依賴:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
2.1.2、編寫啟動類
package com.example.demo;
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);
}
}
2.1.3、配置檔案application.properties
server.port=9090
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://localhost:9090/eureka/,http://localhost:9090/eureka1/
說明:
eureka.client.register-with-eureka:表示是否将自己注冊到Eureka Server,預設為true.(由于此工程本身就是Eureka Server,所有這裡寫false)
eureka.client.fetch-registry:表示是否從Eureka Server擷取資訊,預設為true(由于此工程現在是單節點的,所有這裡寫false)
eureka.client.service-url.defaultZone:設定與Eureka Server互動的位址,查詢服務和注冊服務都需要依賴這個位址,多個用逗号分隔
2.1.4、測試
通路:http://localhost:9090/

2.2、将微服務注冊到Eureka Server上
2.2.1 建立springboot工程
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
</dependencies>
2.2.2、編寫啟動類
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient
@SpringBootApplication
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
2.2.3、配置檔案application.properties
server.port=9091
spring.application.name=demo1
eureka.client.service-url.defaultZone=http://localhost:9090/eureka/
eureka.instance.prefer-ip-address=true
2.2.4、測試
如果在Eureka Server的首頁看到以下這段提示,則說明Eureka已經進入了保護模式:
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.
server.port=9091
spring.application.name=demo1
eureka.client.service-url.defaultZone=http://localhost:9090/eureka/
eureka.instance.prefer-ip-address=true
#顯示指定IP
eureka.instance.instance-id: ${spring.cloud.client.ipAddress}:${server.port}