SpringCloud從看不懂到放棄,第二章

SpringCloud從看不懂到放棄,第二章

一、Eureka服務的註冊與發現

Eureka

Netflix在設計Eureka時遵守的就是AP原則

CAP原則又稱CAP定理,指的是在一個分佈式系統中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分區容錯性),三者不可兼得

1、Eureka簡介

	Eureka是Netflix的一個子模塊,是一個基於Rest的服務,用於服務定位,已實現雲端中間層服務發現和故障轉移。
	
	服務註冊與發現對於微服務架構來說是非常重要的,有了服務發現與註冊,只需要使用服務的標識符,就可以訪問到服務,而不需要修改服務調用的配置文件了。

	功能類似於dubbo的註冊中心,比如zookeeper

Eureka基本架構

	Spring Cloud 封裝了 Netflix 公司開發的 Eureka 模塊來實現服務註冊和發現(請對比Zookeeper)。

	Eureka 採用了 C-S 的設計架構。Eureka Server 作爲服務註冊功能的服務器,它是服務註冊中心。
 
	而系統中的其他微服務,使用 Eureka 的客戶端連接到 Eureka Server並維持心跳連接。這樣系統的維護人員就可以通過 Eureka Server 來監控系統中各個微服務是否正常運行。SpringCloud 的一些其他模塊(比如Zuul)就可以通過 Eureka Server 來發現系統中的其他微服務,並執行相關的邏輯。

	Eureka包含兩個組件:Eureka Server和Eureka Client
	Eureka Server提供服務註冊服務
	各個節點啓動後,會在EurekaServer中進行註冊,這樣EurekaServer中的服務註冊表中將會存儲所有可用服務節點的信息,服務節點的信息可以在界面中直觀的看到
 
	EurekaClient是一個Java客戶端,用於簡化Eureka Server的交互,客戶端同時也具備一個內置的、使用輪詢(round-robin)負載算法的負載均衡器。在應用啓動後,將會向Eureka Server發送心跳(默認週期爲30秒)。如果Eureka Server在多個心跳週期內沒有接收到某個節點的心跳,EurekaServer將會從服務註冊表中把這個服務節點移除(默認90秒)

在這裏插入圖片描述

三大結構

1、Eureka server提供服務註冊與發現
2、service provide將自身服務註冊到Eureka,從而使服務消費方能夠找到
3、service consumer從Eureka獲取註冊服務列表,從而能夠消費服務

2、構建項目

項目結構

總父工程
通用模塊API
服務提供者Provider
服務消費者Consumer
eureka服務註冊中心module

(1)、cloud-eureka-7001

POM

主要包含一個spring-cloud-starter-eureka-server

<?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">

    <parent>
        <artifactId>cloud</artifactId>
        <groupId>com.lee</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cloud-eureka-7001</artifactId>

    <dependencies>
        <!--eureka-server服務端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <!-- 修改後立即生效,熱部署 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>


</project>

注意:

基本上我們要引入cloud的一個新的技術組件,會有兩步

1、新增一個相關的maven座標
	<dependency>
		<groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
	</dependency>

2、在主啓動類上標註啓動該新組件的相關注解標籤
	@EnableEurekaServer 
	@EnableZuulProxy
	@EnableXXXXX
	...

APPLICATION.YML

主要暴露eureka端口和對外服務地址

server:
  port: 7001

eureka:
  instance:
    hostname: localhost #eureka服務端的實例名稱
  client:
    register-with-eureka: false #false表示不向註冊中心註冊自己。
    fetch-registry: false #false表示自己端就是註冊中心,我的職責就是維護服務實例,並不需要去檢索服務
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #設置與Eureka Server交互的地址查詢服務和註冊服務都需要依賴這個地址。

主啓動類

package com.lee.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

//EurekaServer服務器端啓動類,接受其它微服務註冊進來
@EnableEurekaServer
@SpringBootApplication
public class EurekaServer7001_App {

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

測試

http://localhost:7001

(2)、將已有的部門微服務註冊進Eureka服務中心

修改cloud-provider-dept-8001

POM - 新增 eureka客戶端 config配置中心

<!-- 將微服務provider側註冊進eureka -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

<!--注意:-->
<!--
	如果eureka下載不下來的話
	改成這個
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.3.6.RELEASE</version>
        </dependency>

-->

YML - 新增 eureka服務地址

 eureka:
  client: #客戶端註冊進eureka服務列表內
    service-url: 
      defaultZone: http://localhost:7001/eureka

主啓動類 - 新增 將本服務啓動後自動註冊進eureka服務中

@EnableEurekaClient //本服務啓動後會自動註冊進eureka服務中

測試:

1、啓動 cloud-eureka-7001
2、啓動 cloud-provider-dept-8001
3、http://localhost:7001

注意:暴露在eureka中的微服務名稱,即provider的yml中spring:application:name的名稱

如果找不到服務的話,大概率是應爲spring-cloud-starter-eureka和
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>

版本不一致導致的

(3)、actuator與註冊微服務信息完善—主機映射名稱修改

Eureka服務中的顯示

Application AMIs Availability Zones Status
CLOUD-DEPT n/a (1) (1) UP (1) - windows10.microdone.cn:cloud-dept:8001

目標:修改 windows10.microdone.cn:cloud-dept:8001的顯示

cloud-provider-dept-8001修改:

YML

eureka:
	instance:
    	instance-id: cloud-dept8001

結果:

Application AMIs Availability Zones Status
CLOUD-DEPT n/a (1) (1) UP (1) - cloud-dept8001

(4)、actuator與註冊微服務信息完善—主機IP信息提示

鼠標移動到上側超鏈接時,瀏覽器左下角的鏈接顯示

cloud-provider-dept-8001修改:

YML

eureka:
	instance:
		prefer-ip-address: true  #訪問路徑可以顯示IP地址

(5)、actuator與註冊微服務信息完善—Info內容構建

cloud-dept8001超瞭解點擊後內容的構建

cloud-provider-dept-8001修改:

POM

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

YML

info:									#內容以info開頭下邊隨便寫
  app.name: cloud
  author.name: lee
  app.function: 部門服務提供者
  build.artifactId: $project.artifactId$
  build.version: $project.version$

CLOUD父工程POM

<build><!--構建-->
   <finalName>microservicecloud</finalName>
   <resources>	<!--可以訪問src/main/resources下的文件-->
     <resource>
       <directory>src/main/resources</directory>
       <filtering>true</filtering>
     </resource>
   </resources>
   <plugins>
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-resources-plugin</artifactId>
       <configuration>
         <delimiters>
          <delimit>$</delimit>
         </delimiters>
       </configuration>
     </plugin>
   </plugins>
  </build>

結果:

訪問:http://192.168.101.39:8001/info
顯示:
{"app":
	{
		"name":"cloud",
		"function":"部門服務提供者"
	},
 "author":{"name":"lee"},
 "build":{
			"artifactId":"$project.artifactId$",
			"version":"$project.version$"
		  }
}

3、Eureka集羣配置

(1)、仿照cloud-eureka-7001創建cloud-eureka-7002和cloud-eureka-7003

(2)、修改 映射

c:\Windows\System32\drivers\etc下的host文件
添加如下:
	127.0.0.1   eureka7001.com
	127.0.0.1   eureka7002.com
	127.0.0.1   eureka7003.com

(3)、三臺eureka服務的yml配置

eureka:
   instance:
		hostname: eureka7001.com  ##eureka服務端的實例名稱,知識localhost換了個名而已

eureka:
	client:
		defaultZone: http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
		##也可以是http://localhost:7002/eureka,http://localhost:7003/eureka

(4)、cloud-provider-dept-8001 YML服務地址修改

eureka:
	client:
		service-url:
			defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka

測試:

http://eureka7001.com:7001
http://eureka7002.com:7002
http://eureka7003.com:7003

在這裏插入圖片描述

4、Eureka自我保護機制

	某時刻某一個微服務不可用了,或者長時間沒有被調用,eureka不會立刻清理,依舊會對該微服務的信息進行保存。(網絡擁堵或者調用超時)

	什麼是自我保護模式?
  
	默認情況下,如果EurekaServer在一定時間內沒有接收到某個微服務實例的心跳,EurekaServer將會註銷該實例(默認90秒)。但是當網絡分區故障發生時,微服務與EurekaServer之間無法正常通信,以上行爲可能變得非常危險了——因爲微服務本身其實是健康的,此時本不應該註銷這個微服務。Eureka通過“自我保護模式”來解決這個問題——當EurekaServer節點在短時間內丟失過多客戶端時(可能發生了網絡分區故障),那麼這個節點就會進入自我保護模式。一旦進入該模式,EurekaServer就會保護服務註冊表中的信息,不再刪除服務註冊表中的數據(也就是不會註銷任何微服務)。當網絡故障恢復後,該Eureka Server節點會自動退出自我保護模式。
 
	在自我保護模式中,Eureka Server會保護服務註冊表中的信息,不再註銷任何服務實例。當它收到的心跳數重新恢復到閾值以上時,該Eureka Server節點就會自動退出自我保護模式。它的設計哲學就是寧可保留錯誤的服務註冊信息,也不盲目註銷任何可能健康的服務實例。一句話講解:好死不如賴活着
 
	綜上,自我保護模式是一種應對網絡異常的安全保護措施。它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留),也不盲目註銷任何健康的微服務。使用自我保護模式,可以讓Eureka集羣更加的健壯、穩定。


5、Eureka和Zookeeper對比

RDBS(mysql/oracle/sqlserver)---->ACID
NOSQL(redis/mongodb)----->CAP
---------------------------------------------------------
---------------------------------------------------------
ACID:   atomicity原子性、
		consistency一致性、
		isolation獨立性、
		durability持久性

CAP:	consistency強一致性、
		 availability高可用、
		 partition tolerance 分區容錯性
---------------------------------------------------------
---------------------------------------------------------
Eureka遵守AP  Zookeeper遵守CP

 
 	作爲服務註冊中心,Eureka比Zookeeper好在哪裏
著名的CAP理論指出,一個分佈式系統不可能同時滿足C(一致性)、A(可用性)和P(分區容錯性)。由於分區容錯性P在是分佈式系統中必須要保證的,因此我們只能在A和C之間進行權衡。
因此
	Zookeeper保證的是CP,
	Eureka則是AP。
 
1. Zookeeper保證CP
	當向註冊中心查詢服務列表時,我們可以容忍註冊中心返回的是幾分鐘以前的註冊信息,但不能接受服務直接down掉不可用。也就是說,服務註冊功能對可用性的要求要高於一致性。但是zk會出現這樣一種情況,當master節點因爲網絡故障與其他節點失去聯繫時,剩餘節點會重新進行leader選舉。問題在於,選舉leader的時間太長,30 ~ 120s, 且選舉期間整個zk集羣都是不可用的,這就導致在選舉期間註冊服務癱瘓。在雲部署的環境下,因網絡問題使得zk集羣失去master節點是較大概率會發生的事,雖然服務能夠最終恢復,但是漫長的選舉時間導致的註冊長期不可用是不能容忍的。
 
2. Eureka保證AP
	Eureka看明白了這一點,因此在設計時就優先保證可用性。Eureka各個節點都是平等的,幾個節點掛掉不會影響正常節點的工作,剩餘的節點依然可以提供註冊和查詢服務。而Eureka的客戶端在向某個Eureka註冊或時如果發現連接失敗,則會自動切換至其它節點,只要有一臺Eureka還在,就能保證註冊服務可用(保證可用性),只不過查到的信息可能不是最新的(不保證強一致性)。除此之外,Eureka還有一種自我保護機制,如果在15分鐘內超過85%的節點都沒有正常的心跳,那麼Eureka就認爲客戶端與註冊中心出現了網絡故障,此時會出現以下幾種情況: 

2.1、Eureka不再從註冊列表中移除因爲長時間沒收到心跳而應該過期的服務 
2.2、Eureka仍然能夠接受新服務的註冊和查詢請求,但是不會被同步到其它節點上(即保證當前節點依然可用) 
2.3、當網絡穩定時,當前實例新的註冊信息會被同步到其它節點中
 
	因此, Eureka可以很好的應對因網絡故障導致部分節點失去聯繫的情況,而不會像zookeeper那樣使整個註冊服務癱瘓。
	

拓展知識

#服務發現

@AutoWire
private DiscoveryClient client;

List<String> serviceList = client.getServices();//列出Eureka中所有的服務
List<ServiceInstance> instanceList = client.getInstances("CLOUD-DEPT");//查找服務實例
 
instance.getServiceId();//實例ID
instance.getHost();//實例主機
instance.getPort();//實例端口
instance.getUri();//實例Uri
    
@EnableDiscoveryClient //主啓動類上+服務發現註解
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章