Spring-Cloud項目的搭建
因爲spring-cloud是基於spring-boot項目來的,所以我們項目得是一個spring-boot項目,這裏要注意的一個點是spring-cloud的版本與spring-boot的版本要對應下圖:
參考:https://spring.io/projects/spring-cloud-alibaba 或 https://spring.io/projects/spring-cloud
SpringCloud常用組件
服務發現——Netflix Eureka
客服端負載均衡——Netflix Ribbon
斷路器——Netflix Hystrix
服務網關——Netflix Zuul
分佈式配置——Spring Cloud Config
本文使用版本
SpringBoot :2.2.6
SpringCloud: Hoxton.SR3
<!--SpringBoot--> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.2.6.RELEASE</version> </dependency> </dependencies> <!--SpringCloud--> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
一、Spring-Cloud-Netflix組件:Eureka
作用:實現服務治理(服務註冊與發現)
簡介:
Eureka是Netflix(https://spring.io/projects/spring-cloud-netflix)的子模塊之一,也是一個核心的模塊,Eureka裏有2個組件:
1、EurekaServer 用作服務註冊中心。支持集羣部署。
這個是用於定位服務以實現中間層服務器的負載平衡和故障轉移
2、EurekaClient 是一個java客戶端,用來處理服務註冊與發現。
用於與Server交互的,可以使得交互變得非常簡單:只需要通過服務標識符即可 拿到服務。
與spring-cloud的關係:
Spring Cloud 封裝了 Netflix 公司開發的 Eureka 模塊來實現服務註冊和發現(可以對比Zookeeper)。
Eureka 採用了 C-S 的設計架構。Eureka Server 作爲服務註冊功能的服務器,它是服務註冊中心。
而系統中的其他微服務,使用 Eureka 的客戶端連接到 Eureka Server並維持心跳連接。這樣系統的維護人員就可以通過 Eureka Server 來監控系統中各個微服務是否正常運行。(在應用啓動時,Eureka客戶端向服務端註冊自己的服務信息,同時將服務端的服務信息緩存到本地。客戶端會和服務端週期性的進行心跳交互,以更新服務租約和服務信息。)
SpringCloud 的一些其他模塊(比如Zuul)就可以通過 Eureka Server 來發現系統中的其他微服務,並執行相關的邏輯。
角色關係圖:
二、搭建一個簡單的Eureak (單機版)
1、Eureka Server加入依賴 :
<dependencies> <!--服務端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>
EurekaServer服務端配置:application.yml
例如:
server: port: 3000 eureka: server: enable-self-preservation: false #關閉自我保護機制 eviction-interval-timer-in-ms: 4000 #設置清理間隔(單位:毫秒 默認是60*1000) instance: hostname: localhost client: registerWithEureka: false #表示是否註冊自身到eureka服務器,因爲當前這個應用就是eureka服務器,沒必要註冊自身 fetchRegistry: false #不需要從服務端獲取註冊信息(因爲在這裏自己就是服務端,而且已經禁用自己註冊了) serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
在spring-boot啓動項目上 加入註解:@EnableEurekaServer 就可以啓動項目了
如果看見這個圖片,那麼說明你就搭建好了:
注意:這個警告只是說你把他的自我保護機制關閉了。(因爲.yml文件中設置了enable-self-preservation: false)
打開自我保護機制:如果某臺機器宕機,Eureka會認爲是自己問題。
2、EurekaClient加入依賴 :
<dependencies> <!--客戶端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
EurekaClient客戶端配置:application.yml
例如:
server: port: 6000 eureka: client: serviceUrl: defaultZone: http://localhost:3000/eureka/ #eureka服務端提供的註冊地址 參考服務端配置的這個路徑 instance: instance-id: power-1 #此實例註冊到eureka服務端的唯一的實例ID prefer-ip-address: true #是否顯示IP地址 leaseRenewalIntervalInSeconds: 10 #eureka客戶需要多長時間發送心跳給eureka服務器,表明它仍然活着,默認爲30 秒 (與下面配置的單位都是秒) leaseExpirationDurationInSeconds: 30 #Eureka服務器在接收到實例的最後一次發出的心跳後,需要等待多久纔可以將此實例刪除,默認爲90秒 spring: application: name: server-power #此實例註冊到eureka服務端的name
在客戶端的spring-boot啓動項目上 加入註解:@EnableEurekaClient 就可以啓動項目了
看效果圖:
如果配置多個EurekaClient,那麼如下圖:
三、Eureka集羣
Eureka集羣原理
服務啓動後向Eureka註冊,Eureka Server會將註冊信息向其他Eureka Server進行同步,當服務消費者要調用服務提供者,則向服務註冊中心獲取服務提供者地址,然後會將服務提供者地址緩存在本地,下次再調用時,則直接從本地緩存中取,完成一次調用。
此處單臺機器模擬集羣:修改文件【C:\Windows\System32\drivers\etc 中的 hosts】增加 域名的映射
注意:集羣配置與單體不同的點在於 原來是把服務註冊到自己身上,而現在是註冊到其它服務身上。Why?
Eureka的server會把自己的註冊信息與其他的server同步,所以這裏我們不需要註冊到自己身上,因爲另外兩臺服務器會配置本臺服務器。
1、配置服務端 EurekServer
假設我們有3個Eureka Server 模塊如圖:
配置時注意:是註冊到其他的服務上 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
配置服務端子模塊 eureka3000:application.yml
server: port: 3000 eureka: server: enable-self-preservation: false #關閉自我保護機制 eviction-interval-timer-in-ms: 4000 #設置清理間隔(單位:毫秒 默認是60*1000) instance: hostname: eureka3000.com client: # registerWithEureka: false #表示是否註冊自身到eureka服務器,因爲當前這個應用就是eureka服務器,沒必要註冊自身 # fetchRegistry: false #不需要從服務端獲取註冊信息(因爲在這裏自己就是服務端,而且已經禁用自己註冊了) serviceUrl: defaultZone: http://eureka3001.com:3001/eureka,http://eureka3002.com:3002/eureka
配置服務端子模塊 eureka3001:application.yml
server: port: 3001 eureka: server: enable-self-preservation: false #關閉自我保護機制 eviction-interval-timer-in-ms: 4000 #設置清理間隔(單位:毫秒 默認是60*1000) instance: hostname: eureka3001.com client: # registerWithEureka: false #表示是否註冊自身到eureka服務器,因爲當前這個應用就是eureka服務器,沒必要註冊自身 # fetchRegistry: false #不需要從服務端獲取註冊信息(因爲在這裏自己就是服務端,而且已經禁用自己註冊了) serviceUrl: defaultZone: http://eureka3000.com:3000/eureka,http://eureka3002.com:3002/eureka
配置服務端子模塊 eureka3002:application.yml
server: port: 3002 eureka: server: enable-self-preservation: false #關閉自我保護機制 eviction-interval-timer-in-ms: 4000 #設置清理間隔(單位:毫秒 默認是60*1000) instance: hostname: eureka3002.com client: # registerWithEureka: false #表示是否註冊自身到eureka服務器,因爲當前這個應用就是eureka服務器,沒必要註冊自身 # fetchRegistry: false #不需要從服務端獲取註冊信息(因爲在這裏自己就是服務端,而且已經禁用自己註冊了) serviceUrl: defaultZone: http://eureka3000.com:3000/eureka,http://eureka3001.com:3001/eureka
配置完畢後,全部啓動查看:
2、配置客戶端 EurekClient
配置客戶端子模塊 user:application.yml
server: port: 5000 eureka: client: serviceUrl: defaultZone: http://eureka3000.com:3000/eureka/,http://eureka3001.com:3001/eureka/,http://eureka3002.com:3002/eureka/ #eureka服務端提供的註冊地址 參考服務端配置的這個路徑 instance: instance-id: user-1 #此實例註冊到eureka服務端的唯一的實例ID prefer-ip-address: true #是否顯示IP地址 leaseRenewalIntervalInSeconds: 10 #eureka客戶需要多長時間發送心跳給eureka服務器,表明它仍然活着,默認爲30 秒 (與下面配置的單位都是秒) leaseExpirationDurationInSeconds: 30 #Eureka服務器在接收到實例的最後一次發出的心跳後,需要等待多久纔可以將此實例刪除,默認爲90秒 spring: application: name: client-user #此實例註冊到eureka服務端的name
注意:原來是註冊到一個地址上面,現在是要寫三個eureka註冊地址,但是不是代表他會註冊三次,因爲我們eureka server的註冊信息是同步的,這裏只需要註冊一次就可以了,但是爲什麼要寫三個地址呢?????????因爲這樣就可以做到高可用的配置:比如有3臺服務器,突然宕機了一臺, 但是其他2臺還健在,依然可以註冊我們的服務,換句話來講, 只要有一臺服務還建在,那麼就可以註冊服務。
總結:服務隨便註冊到哪個eureka server上,其他的eureka server上都有該服務的註冊信息。
3、 測試
先啓動EurekaServer中的一個服務:比如【eureka3000】 ,再啓動客戶端 user
接着啓動EurekaServer中的一個服務:比如【eureka3001】
四、Eureka對比Zookeeper:
Zookeeper
Eureka
Zookeeper在設計的時候遵循的是CP原則,即一致性。 Eureka在設計的時候遵循的是AP原則,即可用性。 Zookeeper會出現這樣一種情況:當master節點因爲網絡故障與其他節點失去聯繫時,剩餘節點會重新進行leader選舉,問題在於,選舉leader的時間太長:30~120s,且選舉期間整個Zookeeper集羣是不可用的,這就導致在選舉期間註冊服務處於癱瘓狀態,在雲部署的環境下,因網絡環境使Zookeeper集羣失去master節點是較大概率發生的事情,雖然服務能夠最終恢復,但是漫長的選舉時間導致長期的服務註冊不可用是不能容忍的。
Eureka各個節點(服務)是平等的, 沒有主從之分,幾個節點down掉不會影響正常工作,剩餘的節點(服務) 依然可以提供註冊與查詢服務,而Eureka的客戶端在向某個Eureka註冊或發現連接失敗,則會自動切換到其他節點,也就是說,只要有一臺Eureka還在,就能註冊可用(保證可用性), 只不過查詢到的信息不是最新的(不保證強一致);
除此之外,Eureka還有自我保護機制,如果在15分鐘內超過85%節點都沒有正常心跳,那麼eureka就認爲客戶端與註冊中心出現了網絡故障,此時會出現以下情況:
1:Eureka 不再從註冊列表中移除因爲長時間沒有收到心跳而過期的服務。
2:Eureka 仍然能夠接收新服務的註冊和查詢請求,但是不會被同步到其它節點上(即保證當前節點可用)
3:當網絡穩定後,當前實例新的註冊信息會被同步到其它節點中