SpringCloud之Eureka

xbmchina發表於2019-04-03

背景

服務發現是基於微服務的體系結構的關鍵原則之一。嘗試手工配置每個客戶端或某種形式的約定可能很困難,而且很脆弱。Eureka是Netflix的服務發現伺服器和客戶端。可以將伺服器配置和部署為高可用性,每個伺服器將註冊服務的狀態複製到其他伺服器。

簡介

Eureka是Netflix開發的服務發現框架,本身是一個基於REST的服務,主要用於定位執行在AWS域中的中間層服務,以達到負載均衡和中間層服務故障轉移的目的。SpringCloud將它整合在其子專案spring-cloud-netflix中,以實現SpringCloud的服務發現功能。

Eureka包含兩個元件:Eureka Server和Eureka Client。 Eureka Server提供服務註冊服務,各個節點啟動後,會在Eureka Server中進行註冊,這樣EurekaServer中的服務登錄檔中將會儲存所有可用服務節點的資訊,服務節點的資訊可以在介面中直觀的看到。

Eureka Client是一個java客戶端,用於簡化與Eureka Server的互動,客戶端同時也就是一個內建的、使用輪詢(round-robin)負載演算法的負載均衡器。

原理探究

參考文章:dwz.cn/kvCWGp9X

架構

Eureka特點:
  • Eureka不持久化,快取。
  • Eureka通過增量更新註冊資訊,只關心瞬時狀態。
  • Eureka提供客戶端快取,寧可返回某服務5分鐘之前在哪幾個伺服器上可用的資訊,也不能因為暫時的網路故障而找不到可用的伺服器。
Eureka服務註冊與發現:

註冊與發現

服務註冊:

  • 1將例項註冊資訊放入或者更新registry
  • 2.將例項註冊資訊加入最近修改的記錄佇列
  • 3.主動讓Response快取失效

服務取消:

  • 1.從registry中剔除這個例項
  • 2.將例項註冊資訊加入最近修改的記錄佇列
  • 3.主動讓Response快取失效
EurekaClient 快取
  • EurekaClient第一次全量拉取,定時增量拉取應用服務例項資訊,儲存在快取中。
  • EurekaClient增量拉取失敗,或者增量拉取之後對比hashcode發現不一致,就會執行全量拉取,這樣避免了網路某時段分片帶來的問題。
  • 同時對於服務呼叫,如果涉及到ribbon負載均衡,那麼ribbon對於這個例項列表也有自己的快取,這個快取定時從EurekaClient的快取更新
自我保護機制

自我保護機制:預設情況下,如果Eureka Server在一定時間內沒有接收到某個微服務例項的心跳,Eureka Server將會登出該例項(預設90秒)。但是當網路分割槽故障發生時,微服務與Eureka Server之間無法正常通訊,以上行為可能變得非常危險了——因為微服務本身其實是健康的,此時本不應該登出這個微服務。

Eureka通過“自我保護模式”來解決這個問題——當Eureka Server節點在短時間內丟失過多客戶端時(可能發生了網路分割槽故障),那麼這個節點就會進入自我保護模式。一旦進入該模式,Eureka Server就會保護服務登錄檔中的資訊,不再刪除服務登錄檔中的資料(也就是不會登出任何微服務)。當網路故障恢復後,該Eureka Server節點會自動退出自我保護模式。

綜上,自我保護模式是一種應對網路異常的安全保護措施。它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留),也不盲目登出任何健康的微服務。使用自我保護模式,可以讓Eureka叢集更加的健壯、穩定。

但是,在我們實際生產中,我們雲環境同一個Region下不會發生大規模網路分割槽狀況,所以沒有啟用自我保護。

生成環境配置參考: dwz.cn/yB8F2sNa

更多問題可閱讀這大神的文章: dwz.cn/pPecH6CY

使用

參考文章:dwz.cn/GwCz3aB9

父級專案依賴

使用IDEA建立父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>cn.xbmchina</groupId>
    <artifactId>cloud-parent</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>pom</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/>
    </parent>

    <modules>
        <module>cloud-eureka-sever</module>
        <module>cloud-eureka-client</module>
    </modules>


    <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-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>
複製程式碼
Eureka Server搭建

**第一步:**建立一個cloud-erueka-server的Model專案,指定為父級專案

<?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>
	<parent>
		<groupId>cn.xbmchina</groupId>
		<artifactId>cloud-parent</artifactId>
		<version>1.0-SNAPSHOT</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<groupId>cn.xbmchina</groupId>
	<artifactId>cloud-eureka-sever</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>


	<name>cloud-eureka-sever</name>
	<description>服務註冊中心</description>


	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
		</dependency>
	</dependencies>
</project>
複製程式碼

**第二步:**配置檔案application.yml的配置

server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false #通過eureka.client.registerWithEureka:false和fetchRegistry:false來表明自己是一個eureka server.
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

spring:
  application:
    name: cloud-eureka-server
複製程式碼

**第三步:**在啟動類中加入註解@EnableEurekaServer證明是個啟動服務註冊。

@SpringBootApplication
@EnableEurekaServer
public class CloudEurekaSeverApplication {

	public static void main(String[] args) {
		SpringApplication.run(CloudEurekaSeverApplication.class, args);
	}

}
複製程式碼
Eureka Client的搭建

**第一步:**建立一個cloud-erueka-client的Model專案,指定為父級專案

<?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>
	<parent>
		<groupId>cn.xbmchina</groupId>
		<artifactId>cloud-parent</artifactId>
		<version>1.0-SNAPSHOT</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<groupId>cn.xbmchina</groupId>
	<artifactId>cloud-eureka-client</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>cloud-eureka-client</name>
	<description>一個服務提供者</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<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-web</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>
複製程式碼

**第二步:**配置application.yml連線到erueka-server端

server:
  port: 8762

spring:
  application:
    name: cloud-eureka-client

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

複製程式碼

**第三步:**啟動類@EnableEurekaClient指定為客戶端

@SpringBootApplication
@EnableEurekaClient
@RestController
public class CloudEurekaClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(CloudEurekaClientApplication.class, args);
	}

	@Value("${server.port}")
	String port;

	@RequestMapping("/hi")
	public String home(@RequestParam(value = "name", defaultValue = "zero") String name) {
		return "hi " + name + " ,i am from port:" + port;
	}
}
複製程式碼

最後在瀏覽器中開啟地址:http://localhost:8761/ 就可以看到客戶端都註冊了。

參考文章

張雜湊的部落格:dwz.cn/4ugM5OLV 方誌朋:dwz.cn/GwCz3aB9 官網:github.com/Netflix/eur… 文件:dwz.cn/6PaESsA6

總結

Eureka2.x: Spring Cloud 下的 Netflix Eureka 元件專案居然宣佈停止開發了。

下次再看看spring-cloud-consul

看完了,珍愛生命,早點回去睡覺啦!!!

最後

如果對 Java、大資料感興趣請長按二維碼關注一波,我會努力帶給你們價值。覺得對你哪怕有一丁點幫助的請幫忙點個贊或者轉發哦。

SpringCloud之Eureka

相關文章