SpringCloud——Eureka-微服務的註冊中心

weixin_46572109發表於2020-11-26

基於網上學習做了一個提升自己記憶的筆記:
首先聊一下微服務,和分散式,叢集的理解

分散式

一個業務分拆多個子業務,部署在不同的伺服器上。分散式他是一個具體的部署方式,也就是說他是實現微服務的。即 一個業務已經分拆出很多個子業務,並且部署在不同的伺服器上. 也就是具體的一個實現方式

微服務

微服務是一種架構風格,一個大型複雜軟體應用由一個或多個微服務組成。系統中的各個微服務可被獨立部署,各個微服務之間是鬆耦合的。每個微服務僅關注於完成一件任務並很好地完成該任務。在所有情況下,每個任務代表著一個小的業務能力。
通常我們也可以說 微服務=分散式開發+服務治理

叢集

同一個業務,部署在多個伺服器上。


Eureka-微服務的註冊中心

Eureka簡介

Eureka 是Netflix的子模組之一,也是一個核心的模組,Eureka 裡有2個元件,一個是EurekaServer(一個獨立的專案) 這個是用於定位服務以實現中間層伺服器的負載平衡和故障轉移,另一個便是EurekaClient(我們的微服務) 它是用於與Server互動的,可以使得互動變得非常簡單:只需要通過服務識別符號即可拿到服務。

與spring-cloud的關係

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

Eureka 採用了 C-S 的設計架構。Eureka Server 作為服務註冊功能的伺服器,它是服務註冊中心。

而系統中的其他微服務,使用 Eureka 的客戶端連線到 Eureka Server並維持心跳連線。這樣系統的維護人員就可以通過 Eureka Server 來監控系統中各個微服務是否正常執行。SpringCloud 的一些其他模組(比如Zuul)就可以通過 Eureka Server 來發現系統中的其他微服務,並執行相關的邏輯。

(Eureka Server:1.收集客戶端的註冊資訊。2.定時更新資訊看是否還活著,3.服務消費者還會發起遠端的呼叫 )

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-lMJasBuU-1606318536185)(C:\Users\Administrator.USER-20190927LX\AppData\Roaming\Typora\typora-user-images\image-20201124235643007.png)]

使用Eureka

Eureka服務端:

(充當服務與發現的)

pom依賴:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

專案配置檔案裡面加入以下配置:

server:
  port: 8761
eureka:
  server:
    enable-self-preservation: false  #關閉自我保護機制
    eviction-interval-timer-in-ms: 4000 #設定清理間隔(單位:毫秒 預設是60*1000)
  instance:
    hostname: localhost
  client:
    registerWithEureka: false #不把自己作為一個客戶端註冊到自己身上
    fetchRegistry: false  #不需要從服務端獲取註冊資訊(因為在這裡自己就是服務端,而且已經禁用自己註冊了)
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka

啟動類註解:

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class,args);
    }
}

啟動服務端程式,看到以下圖片則啟動成功:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-OSbs96Af-1606318536187)(C:\Users\Administrator.USER-20190927LX\AppData\Roaming\Typora\typora-user-images\image-20201124235703321.png)]

圖中這個紅色警告只是說你把他的自我保護機制關閉了

THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.

自動保護機制是一種針對網路異常波動的安全保護措施,使用自我保護模式能使Eureka叢集更加的健壯、穩定的執行。

(自我保護機制,用來踢出沒有正常上線的服務, 可以滿足服務的踢出有兩種方式:1.關閉自我保護機制的情況下,只能通過發心跳判斷是否正常上線,從而踢除下線或者壞死的服務

2.如果開啟了自我保護機制,就需要判斷到底是不是這個註冊中心服務本身也有可能出現問題,因為基於本機執行Eureka,不需要網路.自我保護機制就是為了防止誤殺,有一個計算公式: 服務的總數x每分鐘的續約數(傳送的心跳)x自我保護的預值 然後才是我們的保護值。 這個保護值也就是說達到了某個量,預設85% 如果低於85%,那就會判斷出是自己的問題 這就是自我保護的一個基準,如果不是 還是會通過發心跳的方式來踢出服務. 但是一般都會關掉 因為為了容災搭叢集,我們在單機測試的時候很容易滿足心跳失敗比例在 15 分鐘之內低於 85%,一旦開啟了保護機制,則服務註冊中心維護的服務例項就不是那麼準確了,此時我們可以使用eureka.server.enable-self-preservation=false來關閉保護機制,這樣可以確保註冊中心中不可用的例項被及時的剔除(不推薦))

Eureka客戶端:

pom依賴:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

專案配置檔案裡面加入以下配置:

server:
  port: 8081
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/ #eureka服務端地址
  instance:
    instance-id: user-1 #此例項註冊到eureka服務端的唯一的例項ID
    prefer-ip-address: true #是否顯示IP地址
    lease-renewal-interval-in-seconds: 10 #eureka客戶需要多長時間傳送心跳給eureka伺服器,表明它仍然活著,預設為30秒 (與下面配置的單位都是秒)
    lease-expiration-duration-in-seconds: 60 #Eureka伺服器在接收到例項的最後一次發出的心跳後,需要等待多久才可以將此例項刪除,預設為90秒
spring:
  application:
    name: server-user #此例項註冊到eureka服務端的name

啟動類註解:

@EnableEurekaClient
@SpringBootApplication
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class,args);
    }
}

啟動客戶端程式,看到客戶端註冊資訊則啟動成功:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-V40w0qZP-1606318536189)(C:\Users\Administrator.USER-20190927LX\AppData\Roaming\Typora\typora-user-images\image-20201124235719212.png)]

這裡我們能看見名字叫SERVER-USER的例項ID為user-1的服務註冊到Eureka上面來了至此,一個簡單的Eureka已經搭建好了。

Eureka叢集

Eureka叢集原理

服務啟動後向Eureka註冊,Eureka Server會將註冊資訊向其他Eureka Server進行同步,當服務消費者要呼叫服務提供者,則向服務註冊 中心獲取服務提供者地址,然後會將服務提供者地址快取在本地,下次再呼叫時,則直接從本地快取中取,完成一次呼叫。

Eureka叢集配置

( Eureka 叢集配置:最主要配置的地方就是真實註冊的地址, Eureka的服務端本身自己可以提供服務,還能把自己給註冊上去,所以Eureka實現叢集的原理就是通過把自己當成一個服務註冊到另一個服務上去.負載均衡的規則也是輪詢

Eureka 它有同步的機制,同步的機制不是說馬上同時註冊到多臺地址上去,我們只需要註冊其中一臺就可以了.這時候註冊中心就會主動的發起通訊告訴其他的同樣是服務端的Eureka的server端,告訴他門註冊的佇列資訊直接傳送過去.拿到註冊資訊後 要進行一個同步. 所以叢集就是基於他本身就是註冊中心註冊到服務端來,還可以通訊的方式把我們的註冊資訊傳送給另外的伺服器,以此確保資訊是同步的)

剛剛我們瞭解到 Eureka Server會將註冊資訊向其他Eureka Server進行同步 那麼我們s的宣告有哪些server呢?

這裡假設我們有3個Eureka Server:

eureka-server-1
eureka-server-2
eureka-server-3

現在怎麼宣告叢集環境的server呢? 我們看一張圖:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-vGrqSCsU-1606318536192)(C:\Users\Administrator.USER-20190927LX\AppData\Roaming\Typora\typora-user-images\image-20201124235734700.png)]

這裡為了方便理解叢集,但是又沒有真實的環境供我們模擬,所以來做一個域名的對映,修改電腦的hosts檔案:

Win10目錄:C:\Windows\System32\drivers\etc
127.0.0.1  eureka3000.com
127.0.0.1  eureka3001.com
127.0.0.1  eureka3002.com

我們來看看具體一臺的配置:

server:
  port: 3000
eureka:
  server:
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 4000
  instance:
    hostname: eureka3000.com
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://eureka3001.com:3001/eureka,http://eureka3002.com:3002/eureka

三臺Eureka服務都配置完成之後,我們的客戶端只需要改一個配置即可:

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:3000/eureka/,http://eureka3001.com:3001/eureka,http://eureka3002.com:3002/eureka

配置完成之後,全部啟動我們可以看到效果:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-BM630ELi-1606318536194)(C:\Users\Administrator.USER-20190927LX\AppData\Roaming\Typora\typora-user-images\image-20201124235754299.png)]

客戶端雖然要配置三個Eureka註冊地址,但是不是代表他會註冊三次,因為我們EurekaServer的註冊資訊是同步的,這裡只需要註冊一次就可以了,但是為什麼要寫三個地址呢。因為這樣就可以做到高可用的配置:打個比方有3臺伺服器。但是突然當機了一臺, 但是其他2臺還健在,依然可以註冊我們的服務,換句話來講, 只要有一臺服務還建在,那麼就可以註冊服務。

CAP

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-LrWRKJfR-1606318536196)(C:\Users\Administrator.USER-20190927LX\AppData\Roaming\Typora\typora-user-images\image-20201124235808508.png)]

1998年,加州大學的電腦科學家 Eric Brewer 提出,分散式系統有三個指標。

Consistency 一致性
Availability 可用性
Partition tolerance 分割槽容錯性

他們第一個字母分別是C、A、P。Eric Brewer說,這三個指標不可能同時做到。這個結論就叫做 CAP 定理。

Partition tolerance

中文叫做"分割槽容錯"。

大多數分散式系統都分佈在多個子網路。每個子網路就叫做一個區(partition)。分割槽容錯的意思是,區間通訊可能失敗。比如,一臺伺服器放在本地,另一臺伺服器放在外地(可能是外省,甚至是外國),這就是兩個區,它們之間可能無法通訊。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-d97orZa7-1606318536199)(C:\Users\Administrator.USER-20190927LX\AppData\Roaming\Typora\typora-user-images\image-20201124235819800.png)]

上圖中,S1 和 S2 是兩臺跨區的伺服器。S1 向 S2 傳送一條訊息,S2 可能無法收到。系統設計的時候,必須考慮到這種情況。

一般來說,分割槽容錯無法避免,因此可以認為 CAP 的 P 總是成立。CAP 定理告訴我們,剩下的 C 和 A 無法同時做到。

(分散式必須要把p 考慮進去,不然沒辦法完成分散式的一個設計,完成分散式的部署 ,說白了分散式最主要就是為了解決容錯這個問題)

Consistency

Consistency 中文叫做"一致性"。意思是,寫操作之後的讀操作,必須返回該值。舉例來說,某條記錄是 v0,使用者向 S1 發起一個寫操作,將其改為 v1。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-u9t7lCPR-1606318536201)(C:\Users\Administrator.USER-20190927LX\AppData\Roaming\Typora\typora-user-images\image-20201124235829450.png)]

接下來使用者讀操作就會得到v1。這就叫一致性。

![外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-I9mqW7it-1606318536203)(C:\Users\Administrator.USER-20190927LX\AppData\Roaming\Typora\typora-user-images\image-20201124235840211.png)]

問題是,使用者有可能會向S2發起讀取操作,由於S2的值沒有發生變化,因此返回的是v0,所以S1和S2的讀操作不一致,這就不滿足一致性了。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-L5Fo9Wl2-1606318536205)(C:\Users\Administrator.USER-20190927LX\AppData\Roaming\Typora\typora-user-images\image-20201124235851169.png)]

為了讓S2的返回值與S1一致,所以我們需要在往S1執行寫操作的時候,讓S1給S2也傳送一條訊息,要求S2也變成v1。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-l9lYEcGo-1606318536207)(C:\Users\Administrator.USER-20190927LX\AppData\Roaming\Typora\typora-user-images\image-20201124235903107.png)]

這樣子使用者向S2發起讀操作,就也能得到v1。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-8aRGnILu-1606318536208)(C:\Users\Administrator.USER-20190927LX\AppData\Roaming\Typora\typora-user-images\image-20201124235948331.png)]

Availability

Availability 中文叫做"可用性",意思是隻要收到使用者的請求,伺服器就必須給出回應。

使用者可以選擇向 S1 或 S2 發起讀操作。不管是哪臺伺服器,只要收到請求,就必須告訴使用者,到底是 v0 還是 v1,否則就不滿足可用性。

Consistency 和 Availability 的矛盾

一致性和可用性,為什麼不可能同時成立?答案很簡單,因為可能通訊失敗(即出現分割槽容錯)。

如果保證 S2 的一致性,那麼 S1 必須在寫操作時,鎖定 S2 的讀操作和寫操作。只有資料同步後,才能重新開放讀寫。鎖定期間,S2 不能讀寫,沒有可用性不。

如果保證 S2 的可用性,那麼勢必不能鎖定 S2,所以一致性不成立。

綜上所述,S2 無法同時做到一致性和可用性。系統設計時只能選擇一個目標。如果追求一致性,那麼無法保證所有節點的可用性;如果追求所有節點的可用性,那就沒法做到一致性。

Eurka 工作流程

瞭解完 Eureka 核心概念,自我保護機制,以及叢集內的工作原理後,我們來整體梳理一下 Eureka 的工作流程:

1、Eureka Server 啟動成功,等待服務端註冊。在啟動過程中如果配置了叢集,叢集之間定時通過 Replicate 同步登錄檔,每個 Eureka Server 都存在獨立完整的服務登錄檔資訊

2、Eureka Client 啟動時根據配置的 Eureka Server 地址去註冊中心註冊服務

3、Eureka Client 會預設每 30s 向 Eureka Server 傳送一次心跳請求,證明客戶端服務正常

4、當 Eureka Server 預設 90s 內沒有收到 Eureka Client 的心跳,註冊中心則認為該節點失效,會登出該例項

5、單位時間內 Eureka Server 統計到有大量的 Eureka Client 沒有上送心跳,則認為可能為網路異常,進入自我保護機制,不再剔除沒有上送心跳的客戶端

6、當 Eureka Client 心跳請求恢復正常之後,Eureka Server 自動退出自我保護模式

7、Eureka Client 定時全量或者增量從註冊中心獲取服務登錄檔,並且將獲取到的資訊快取到本地

8、服務呼叫時,Eureka Client 會先從本地快取找尋調取的服務。如果獲取不到,先從註冊中心重新整理登錄檔,再同步到本地快取

9、Eureka Client 獲取到目標伺服器資訊,發起服務呼叫

10、Eureka Client 程式關閉時向 Eureka Server 傳送取消請求,Eureka Server 將例項從登錄檔中刪除

這就是Eurka基本工作流程

相關文章