SpringCloud-服務與註冊
- 2021 年 3 月 7 日
- 筆記
- SpringCloud
SpringCloud- Eureka服務註冊與發現
1.概述
springcloud是一個非常優秀的微服務框架,要管理眾多的服務,就需要對這些服務進行治理,管理每個服務與每個服務之間的依賴關係,可以實現服務調用、負載均衡、服務容錯、以及服務的註冊與發現。
如果微服務之間存在調用依賴,就需要得到目標服務的服務地址,也就是微服務治理的服務發現。要完成服務發現,就需要將服務資訊存儲到某個載體,載體本身即是微服務治理的服務註冊中心,而存儲到載體的動作即是服務註冊。
2.使用註冊中心前服務間的調用
使用RestTemplate
服務消費方創建一個RestTemplate,通過http請求服務提供方暴露的介面形式
簡單程式碼
消費方:
//bean
@Configuration
public class ConfigBean {
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
//controller
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/consumer/dept/add")
public boolean add(Dept dept)
{
return restTemplate.postForObject("//localhost:8080" + "/dept/add", dept, Boolean.class);
}
有什麼缺陷?
- 路徑硬編碼,如果服務提供方埠或地址變更,不方便切換;
- 如果服務提供方是多實例集群模式一個路徑如何訪問集群的api;(加nginx(或硬體f5),那是不是每個集群都要加呢?這樣會造成nginx泛濫。)
3.難以實現如實健康檢查,負載均衡調用、高可用性等等。
3.Eureka服務註冊與發現
Eureka是Spring Cloud微服務套件中的一部分,可以與Springboot構建的微服務很容易的整合起來。
Eureka包含了伺服器端和客戶端組件。
3.1 Eureka Server
Eureka Server 主要對外提供了三個功能:
1.服務註冊,所有的服務都註冊到 Eureka Server 上面來。
2.提供註冊表,註冊表就是所有註冊上來服務的一個列表,Eureka 內部通過一個二層快取機制來維護這個註冊表。Eureka Client 在調用服務時,需要獲取這個註冊表,一般來說,這個註冊表會快取下來,如果快取失效,則直接獲取最新的註冊表。
3.同步狀態,Eureka Client 通過註冊、心跳等機制,和 Eureka Server 同步當前客戶端的狀態,以便 Eureka Client 能夠及時感知到變化。
3.2 Eureka Client
1.服務註冊,將自己註冊到服務註冊中心(Eureka Server)
2.獲取註冊表資訊
Eureka Client 從 Eureka Server 上獲取服務的註冊資訊,「並將其快取在本地」,這句是關鍵。
當 Eureka Client 在需要調用遠程服務時,會從該資訊中查找遠程服務所對應的 IP 地址、埠等資訊。Eureka Client 上快取的服務註冊資訊會定期更新(30 秒),如果 Eureka Server 返回的註冊表資訊與本地快取的註冊表資訊不同的話,Eureka Client 會自動處理。
- 服務續約
Eureka CLient 每隔 30 秒就要向 Eureka Server 發送一條心跳消息,來告訴 Eureka Server 我還在運行。
如果 Eureka Server 連續 90 秒都有沒有收到 Eureka Client 的續約消息(連續三次沒發送),它會認為 Eureka Client 已經掉線了,會將掉線的 Eureka Client 從當前的服務註冊列表中剔除。
- 服務下線。當 Eureka Client 下線時,它會主動發送一條消息,告訴 Eureka Server ,我下線啦。
從上面的介紹可以看出,Eureka Client 會自動拉取、更新以及快取 Eureka Server 中的資訊,這樣,即使 Eureka Server 所有節點都宕機,Eureka Client 依然能夠獲取到想要調用服務的地址(前提是服務地址沒有發生變化)
3.3服務註冊與發現原理圖:
服務註冊 -存儲服務的主機及埠資訊
服務發現-允許其他用戶發現註冊階段存儲的資訊

概況:Provider 和 Consumer 分別作為服務啟動,並且註冊到 Eureka 上面去,以 provider 為例,provider 註冊時會告訴 eureka,我叫 provider,我的地址是 xx.xx.xx.xx,我的埠是 xx,我的 xx 是 xx,就是說,provider 會將自己的一些元數據資訊告訴 eureka;同理,consumer 也是如此。
接下來,consumer 要調用 provider 的介面,但是它不知道 provider 的地址是什麼,他只知道要調用的服務叫 provider,於是 consumer 找到 eureka,從 eureka 上查詢出來 provider 的具體地址和埠,這個具體的地址和埠,可能是一個,也可能是多個(集群化部署)。
4.項目集成搭建
4.1創建服務中心Eureka
創建子項目microservicecloud-eureka-7001
Pom 添加依賴
<!--eureka-server服務端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
配置文件
application.yml
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服務端的實例名稱
client:
register-with-eureka: false #false表示不向註冊中心註冊自己。
fetch-registry: false #false表示自己端就是註冊中心,我的職責就是維護服務實例,並不需要去檢索服務
service-url:
defaultZone: //${eureka.instance.hostname}:${server.port}/eureka/ #設置與Eureka Server交互的地址查詢服務和註冊服務都需要依賴這個地址(單機)。
啟動類:
@SpringBootApplication
@EnableEurekaServer // EurekaServer伺服器端啟動類,接受其它微服務註冊進來
public class EurekaServer7001_App {
public static void main(String[] args) {
SpringApplication.run(EurekaServer7001_App.class, args);
}
}
啟動測試:
4.2將服務的註冊進Eureka
創建提供服務的客戶端,並向服務註冊中心註冊自己。
1.引兩個包
如修改8001工程,pom.xml 添加這兩個包:
<!-- 將微服務provider側註冊進eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
2.修改8001 的yml,後面追加
eureka:
client: #客戶端註冊進eureka服務列表內
service-url:
defaultZone: //localhost:7001/eureka
3.修改8001啟動類,添加註解
@EnableEurekaClient//表明是Eureka客戶端
就可以看到服務名了。

4.3 Eureka的高可用性
Eureka Server除了單點運行之外,還可以通過運行多個實例,並進行互相註冊的方式來實現高可用的部署。
Eureka的集群配置
1.原理:把功能多部署幾份應當高並發的請求提供服務。
2.搭建eureka-7002,eureka-7003,
複製eureka-7001的pom文件、啟動類、yml文件,改相應的名稱;
修改系統hosts文件映射:
添加
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com
每個註冊中心yml文件,兩兩註冊,配置集群:
defaultZone: //eureka7002.com:7002/eureka/,//eureka7003.com:7003/eureka/
相應的客戶端8001也修改yml文件
defaultZone: //eureka7001.com:7001/eureka/,//eureka7002.com:7002/eureka/,//eureka7003.com:7003/eureka/
可以看到集群資訊:

兩兩註冊的方式可以實現集群中節點完全對等的效果,實現最高可用性集群,任何一台註冊中心故障都不會影響服務的註冊與發現

4.4 Eureka自我保護
一句話:某時刻某一個微服務不可用了(如8001),Eureka-server不會立刻清理,依舊會對該微服務的消息進行保存。
默認情況下,如果Eureka-Server在一定時間內沒有接收到某個微服務實例的心跳,如果 Eureka Server 連續 90 秒都有沒有收到 Eureka Client 的續約消息(連續三次沒發送),它會認為 Eureka Client 已經掉線了,會將掉線的 Eureka Client 從當前的服務註冊列表中剔除。
但是當網路分區故障發生時,微服務於EurekaServer之間無法正常通訊,以上行為可能變得非常危險了—因為微服務本身其實是健康的,此時本不應該註銷這個微服務。Eureka通過「自我保護模式」來解決這個問題—當Eureka Server節點短時間內丟失過多客戶端時(可能發送了網路分區故障),那麼這個節點就會進入自我保護模式。一旦進入該模式,EurekaServer就會保護服務註冊表中的消息,不再刪除服務註冊表的數據(也就是不會註銷任何微服務)。當網路故障恢復後,該EurekaServer節點會自動退出自我保護模式。
7001 yml文件:
eureka:
server:
#關閉自我保護false(預設true),一般不建議這麼做。
enable-self-preservation: false
#續期時間,即掃描失效服務的間隔時間(預設為90*1000ms)
eviction-interval-timer-in-ms: 10000
5. 與其他註冊中心PK
後續:
Eureka閉源,目前2.0不更新
替代方案:
Nacos:阿里開源2019.6正式1.0企業級,致力於幫助您發現、配置和管理微服務.
Zookeeper:分散式協調工具,可以實現註冊中心功能
consul:簡化了分散式環境中的服務的註冊和發現流程,通過 HTTP 或者 DNS 介面發現。
這四個組件雖然都實現了註冊中心的功能,但是他們的功能和實現方式都有不同的地方,也各有各的優點,單從註冊中心方面來比價四個註冊中心。
|
功能 |
Eureka |
Nacos |
Consul |
ZK |
|
CAP定理(協議) |
AP |
AP(或CP) |
CP |
CP |
|
負載均衡策略 |
Ribbon |
權重/metadata/Selecto |
Fabio |
- |
|
雪崩保護 |
有 |
有 |
無 |
無 |
|
SpringCloud集成 |
支援 |
支援 |
支援 |
- |
|
多數據中心 |
支援 |
支援 |
支援 |
- |
CAP原則又稱CAP定理,指的是在一個分散式系統中,一致性(Consistency)、可用性(Availability)、分區容錯性(Partition tolerance)。CAP 原則指的是,這三個要素最多只能同時實現兩點,不可能三者兼顧。
CAP原則的精髓就是要麼AP,要麼CP,要麼AC,但是不存在CAP。
· Consistency 一致性:所有數據備份,在同一時刻是否同樣的值。(等同於所有節點訪問同一份最新的數據副本)
· Availability 可用性:在集群中一部分節點故障後,集群整體是否還能響應客戶端的讀寫請求。(對數據更新具備高可用性)
· Partition Tolerance 容錯性:以實際效果而言,分區相當於對通訊的時限要求。系統如果不能在時限內達成數據一致性,就意味著發生了分區的情況,必須就當前操作在C和A之間做出選擇。
6. 思考問題
如果Eureka server都宕機了,微服務還能調通嗎(微服務消費方調微服務提供方)?為什麼?
7.參考文獻
//www.cnblogs.com/sharpest/p/13678513.html
註冊中心的比較
//www.jianshu.com/p/9b8a746e0d90
//www.cnblogs.com/grasp/p/9258811.html
Spring Cloud構建微服務架構:服務註冊與發現(Eureka、Consul)【Dalston版】
//blog.didispace.com/spring-cloud-starter-dalston-1/
Eureka 都掛了,微服務還能調通嗎?
//blog.csdn.net/weixin_26757939/article/details/112497977
畫圖工具

