前幾天魯班LB跟我說:你玩把遊戲都要半個鐘啦,為何不用這時間來看看書,如果漲工資還可以幫我買個皮膚。
面對如此合理的這需求,但我不以為然,事實上并不是我不想學習,而是 ↓

實力不允許呀~
直到有一天,突然被叫到會議室,心裡疙瘩一下,這難道?項目出嚴重Bug了,冷靜的我思索片刻後,很快就會否定了這種想法,結果巴拉巴拉2小時後,結論竟然是說:“現在我們這個項目要求重構,需用使用微服務架構,是以不了解相關技術的同僚請利用這段時間學習複習一下,下個月要開始進入開發階段。
呵呵,會議上,總是有人把微服務吹的很厲害似的,我笑而不語,于是
一周後
以下是我的筆記,我一般是帶着問題去學習,有了需求,或者說是好奇心,因為這樣學習的效率會更高
當看到我們架構中有Eureka,我的第一個問題自然就是:做微服務為什麼要使用Eureka,或者Eureka能夠幫助我們解決什麼樣的問題?
對于微服務的概念有經驗的開發人員的一般都聽說過吧,無非就是把大應用拆分為小應用,然後處理好服務的互相通訊即可,但是如果光啟動微服務時,不啟動eureka,其他微服務也是可以通過Nginx反向代理,用rest的方式從不同服務背景擷取到資料(HTTP直怼),那多個eureka服務豈不是多此一舉嗎?細想一下其實并不是的,我覺得原因有如下:
其一:
如果後端微服務之間,有互相通信,那麼在負載均衡時,相同的服務肯定會啟動多個,而且使用不同的端口,這個時候,服務之間就可以通過注冊在eureka中的名稱來找到對方,而不是根據IP+端口号去找對方。反之如果後端微服務之間互相通信,都要知道具體的IP和端口,那開發起來十分麻煩,而IP位址也并不是固定不變的,除非使用域名封裝,是以無論是測試還是開發還是上線都存在問題。
其二:
Eureka注冊中心的作用很大的程度是作用于服務發現和服務心跳,在多個注冊中心的時候,依賴于zuul的負載均衡,保證異常的服務停止,正常的服務加載,保證服務的穩定性。
新手可能不了解這說的是什麼意思,沒關系,請往下看,首先我們先說說什麼是SpringCloud
SpringCloud是一系列架構的有序集合。它利用SpringBoot的開發便利性巧妙地簡化了分布式系統基礎設施的開發,如服務發現注冊、配置中心、消息總線、負載均衡、 熔斷器、資料監控等,都可以用SpringBoot的開發風格做到一鍵啟動和部署。是一套簡單易懂、易部署和易維護的分布式系統開發工具包。
主要組成如下:
- 服務發現——Netflix Eureka 服務調用——Netflix Feign
- 熔斷器——Netflix Hystrix 服務網關——Netflix Zuul
- 分布式配置——Spring Cloud Config 消息總線 —— Spring Cloud Bus
本文主要介紹Eureka注冊中心
組成原理:
Eureka包含兩個元件: Eureka Server和Eureka Client:
Eureka Server提供服務注冊服務,各個Client節點啟動後,會在Eureka Server中進行注冊,這樣EurekaServer中的服務系統資料庫中将會存儲所有可用服務節點的資訊,服務節點的資訊可以在界面中直覺的看到。
Eureka Client是一個java用戶端,用于簡化與Eureka Server的互動,用戶端有一個内置的、使用輪詢(round-robin)負載算法的負載均衡器。在應用啟動後,将會向Eureka Server發送心跳,預設周期為30秒,如果Eureka Server在多個心跳周期内沒有接收到某個節點的心跳,Eureka Server将會從服務系統資料庫中把這個服務節點移除(預設90 秒)。如果Eureka Server做了叢集,Eureka Server之間通過複制的方式完成資料的同步,同時Eureka還提供了用戶端緩存機制,即使所有的Eureka Server都挂掉,用戶端依然可以利用緩存中的資訊消費其他服務的API。
綜上,Eureka能夠通過心跳檢查、用戶端緩存等機制,確定了系統的高可用性。
問題:同為注冊中心,Eureka要比Zookeeper好在哪,或者說為什麼Cloud為什麼不內建Zookeeper,在CAP理論中說道,一個分布式系統不可能同時滿足C(一緻性)、A(可用性)和P(分區容錯性)。由于分區容錯性在是分布式系統中必須要保證的,是以我們隻能在A和C之間進行權衡。我們從需求出發考慮,當向注冊中心查詢服務清單時,我們可以容忍注冊中心傳回的是幾分鐘以前的注冊資訊,但不能接受服務直接down掉不可用。也就是說,對于服務注冊功能對可用性的要求要高于一緻性。
Eureka不會出現這種問題,Zookeeper則會出現這樣一種情況,當master節點因為網絡故障與其他節點失去聯系時,剩餘節點會重新進行leader選舉。選舉leader的時間太長,30 ~ 120s, 且選舉期間整個zk叢集都是不可用的,這就導緻在選舉期間注冊服務癱瘓。在雲部署的環境下,因網絡問題使得zk叢集失去master節點是較大機率會發生的事,雖然服務能夠最終恢複,但是漫長的選舉時間導緻的注冊長期不可用是不能容忍的。
而在此Zookeeper保證的是CP, 而Eureka則是AP,顯然Eureka更加合适。
但在預設配置中,Eureka Server在預設90s沒有得到用戶端的心跳,則登出該執行個體,但是往往因為微服務跨程序調用,網絡通信往往會面臨着各種問題,比如微服務狀态正常,但是因為網絡分區故障時,Eureka Server登出服務執行個體則會讓大部分微服務不可用,這很危險,因為服務明明沒有問題。為了解決這個問題,Eureka 有自我保護機制,通過在Eureka Server配置參數,可啟動保護機制它的工作原理是:當Eureka Server節點在短時間内丢失過多的用戶端時(可能發送了網絡故障),那麼這個節點将進入自我保護模式,不再登出任何微服務,當網絡故障回複後,該節點會自動退出自我保護模式。
實戰:
Eureka服務端開發(非常簡單的3步完成)
1.從官網下載下傳腳手架項目https://start.spring.io/
2.修改一下配置檔案
3.啟動,本質上也是一個SpringBoot項目
把下載下傳好的Demo導入編譯器,打開application.properties或 .yml配置檔案
#配置端口
server:
port: 8761 #服務端口
#配置服務名稱
spring:
application:
name: service-name
#是否将自己注冊到Eureka服務中,本身就是服務端,是以無需注冊
#是否從Eureka中擷取注冊資訊
#用戶端和服務端互動位址
eureka:
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://127.0.0.1:${server.port}/eureka/
配置啟動類
@SpringBootApplication
//加入注解,聲明為服務端
@EnableEurekaServer
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class, args);
}
}
上圖為Eureka服務端啟動成功,可視化界面,Application表示目前并無用戶端使用者注冊進來,這裡說的用戶端就是我們開發的微服務應用
Eureka用戶端開發(其實就是我們真正業務微服務應用)
1.從官網下載下傳腳手架項目https://start.spring.io/
2.修改一下配置檔案
#配置端口
server:
port:1111
#配置服務名稱
spring:
application:
name : client-name
#配置伺服器路徑
eureka:
client:
service‐url:
defaultZone: http://localhost:8761/eureka
instance:
prefer‐ip‐address: true
啟動類配置
//加入注解,聲明為微服務用戶端,項目啟動後自動向服務端注冊
@EnableDiscoveryClient
@SpringBootApplication
public class ServiceProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceProviderApplication.class, args);
}
}
啟動後就能在服務端可視化界面看見用戶端的注冊資訊,我們現在就将所有的微服務都注冊到Eureka中,這樣所有的微服務之間都可以互相調用,服務的調用将在下一篇文章詳細講解
但是有時候會出現下面的文字
說明Eureka已經進入了保護模式:
Eureka Server在運作期間,會統計心跳失敗的比例在15分鐘之内是否低于85%,如果出現低于的情況(在生産環境上通常是由于網絡不穩定導緻),Eureka Server會将目前的執行個體注冊資訊保護起來,同時提示這個警告。保護模式主要用于一組用戶端和Eureka Server之間存在網絡分區場景下的保護。一旦進入保 護模式,Eureka Server将會嘗試保護其服務系統資料庫中的資訊,不會登出任何微服務。
關于Eureka Server叢集的介紹
Eureka注冊中心隻部署在一台機器上,一旦出現問題,會導緻整個服務調用系統的崩潰,針對這種情況,我們需要部署兩台Eureka注冊中心,彼此互相注冊,組成一個高可用的的Eureka叢集。這樣一來,每台伺服器都包含着對方的服務注冊資訊,相當于雙機熱備,同時,服務提供者隻需向其中的一個注冊服務。
在生産環境中,一般是把兩個互相注冊的伺服器安裝在兩台伺服器上,現在我們在一台機器上模拟雙伺服器的場景,具體的實作步驟如下:
到C:\WINDOWS\system32\drivers\etc目錄裡,找到hosts檔案,在其中加入兩個機器名(其實都是指向本機),代碼如下。修改後,需要重新開機機器。
127.0.0.1 erueka-server
127.0.0.1 erueka-server2
配置如下
Eureka service
server:
port: 8761 #端口号
spring:
application:
name: eureka-server #應用名
eureka:
instance:
hostname: hostname1
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://hostname1:8761/eureka/,http://hostname2:8762/eureka/
Eureka service2
server:
port: 8762 #端口号
spring:
application:
name: eureka-server2 #應用名
eureka:
instance:
hostname: hostname2
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://hostname1:8761/eureka/,http://hostname2:8762/eureka/
這樣下來,就算有一台機器當機了,然後可讓服務正常工作。