Spring Cloud 封裝了 Netflix 公司開發的 Eureka 模塊來實現服務註冊和發現java
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>
server: port: 3000 eureka: server: enable-self-preservation: false #關閉自我保護機制 eviction-interval-timer-in-ms: 4000 #設置清理間隔(單位:毫秒 默認是60*1000) instance: hostname: localhost
@SpringBootApplication @EnableEurekaServer public class Eureka3000App { public static void main(String[] args) { SpringApplication.run(Eureka3000App.class, args); } }
Eureka作爲註冊中心, 作爲服務的管理,它不能掛掉, 若是它掛掉,整個服務所有訪問不了
所以Eureka也要搭建集羣多臺Eureka服務, 集羣之間要進行相互之間通訊,通訊靠的就是Eureka-client
Eureka是一個服務端, 也是一個客戶商, 之後相互註冊,如今沒有其它的可註冊,因此就會報ClientExceptionnode
解決方案:不讓它作爲客戶端註冊,在application.yml添加以下配置
spring
client: registerWithEureka: false #不把本身做爲一個客戶端註冊到本身身上 fetchRegistry: false #不須要從服務端獲取註冊信息(由於在這裏本身就是服務端,並且已經禁用本身註冊了) serviceUrl: #微服務要註冊到的地址. #http://localhost:3000/eureka defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
<!--Eureka的客戶端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
@EnableEurekaClient
server: port: 5000 eureka: client: serviceUrl: #eureka服務端提供的註冊地址 參考服務端配置的這個路徑 defaultZone: http://localhost:3000/eureka instance: instance-id: user-1 #此實例註冊到eureka服務端的惟一的實例ID prefer-ip-address: true #是否顯示IP地址 #eureka客戶須要多長時間發送心跳給eureka服務器,代表它仍然活着,默認爲30 秒 (與下面配置的單位都是秒) leaseRenewalIntervalInSeconds: 10 #Eureka服務器在接收到實例的最後一次發出的心跳後,須要等待多久才能夠將此實例刪除,默認爲90秒 leaseExpirationDurationInSeconds: 30 spring: application: name: client-user #此實例註冊到eureka服務端的name
服務提供者在啓動時,會檢測配置屬性中的:eureka.client.register-with-erueka=true參數是否正確,
事實上默認就是true。若是值確實爲true,則會向EurekaServer發起一個Rest請求api
當服務消費者啓動是,會檢測eureka.client.fetch-registry=true參數的值,若是爲true, 則會從Eureka
Server服務的列表只讀備份,而後緩存在本地。而且每隔30秒會從新獲取並更新數據。
eureka.client.registry-fetch-interval-seconds: 5 生產環境中,咱們不須要修改這個值。瀏覽器
eureka: instance: lease-expiration-duration-in-seconds: 90 :服務續約(renew)的間隔,默認爲30秒 lease-renewal-interval-in-seconds: 30 :服務失效時間,默認值90秒
在註冊服務完成之後,服務提供者會維持一個心跳
也就是說,默認狀況下每一個30秒服務會向註冊中心發送一次心跳,證實本身還活着。若是超過90秒沒有發送心跳
EurekaServer就會認爲該服務宕機,會從服務列表中移除,這兩個值在生產環境不要修改,默認便可。緩存
有些時候,咱們的服務提供方並不必定會正常下線,可能由於內存溢出、網絡故障等緣由致使服務沒法正常工做 Eureka
Server須要將這樣的服務剔除出服務列表。所以它會開啓一個定時任務,每隔60秒對全部失效的服務(超過90秒未響應)進行剔除
能夠經過eureka.server.eviction-interval-timer-in-ms參數對其進行修改,單位是毫秒服務器
當把一個服務停掉後, 並不會立馬從服務列表當中移除,默認是90秒清除一次
有能夠註冊中心和微服務之間出現了網絡波動,網絡很差,沒有收到心跳,有多是網絡很差,可是微服務還在,因此它不會立馬把服務給移除
當15分鐘內85%的心跳都沒有正常心跳,那麼eureka認爲客戶端與註冊中心出現了網絡問題,此時會出現如下狀況:
1.Eureka再也不從註冊列表中移除由於長時間沒有收到的心跳而過時的服務
2.Eureka仍然可以接收服務的註冊和查詢請求,可是不會被同步到其它節點上
3.當網絡穩定後,當前實例新註冊的信息會被同步到其它節點上網絡
CAP定理又稱CAP原則, 指的是在一個分佈式系統中,Consistency(一致性)、
Availability(可用性)、Partition tolerance(分區容錯性), 最多隻能同時三個特性中的兩個,三者不可兼得架構
「all nodes see the same data at the same time」,
即更新操做成功並返回客戶端後,全部節點在同一時間的數據徹底一致,這就是分佈式的一致性。app
可用性指「Reads and writes always succeed」 即服務一直可用,並且是正常響應時間。
好的可用性主要是指系統可以很好的爲用戶服務,不出現用戶操做失敗或者訪問超時等用戶體驗很差的狀況
大多數分佈式系統都分佈在多個子網絡。每一個子網絡就叫作一個區
分區容錯的意思是,區間通訊可能失敗。好比,一臺服務器放在本地,另外一臺服務器放在外地(多是外省,甚至是外國),這就是兩個區,它們之間可能沒法通訊
兩臺跨區的服務器。Server1 向 Server2 發送一條消息,Server2 可能沒法收到。系統設計的時候,必須考慮到這種狀況.
通常來講,分區容錯沒法避免,所以能夠認爲 CAP 的 P 老是成立
即分佈式系統在遇到某節點或網絡分區故障的時候,仍然可以對外提供知足一致性或可用性的服務。
分區容錯性要求可以使應用雖然是一個分佈式系統,而看上去卻好像是在一個能夠運轉正常的總體。
若是保證 Server2 的一致性,那麼 Server1 必須在寫操做時,鎖定 Server2
的讀操做和寫操做。只有數據同步後,才能從新開放讀寫。鎖按期間,Server2 不能讀寫,沒有可用性 若是保證 Server2的可用性,那麼勢必不能鎖定 Server2,因此一致性不成立
若是不要求P(不容許分區),則C(強一致性)和A(可用性)是能夠保證的。
但放棄P的同時也就意味着放棄了系統的擴展性,也就是分佈式節點受限,沒辦法部署子節點, 這是違背分佈式系統設計的初衷的。
2.CP without A:
若是不要求A(可用),至關於每一個請求都須要在服務器之間保持強一致,而P(分區)會致使同步時間無限延長
(也就是等待數據同步完才能正常訪問服務)
一旦發生網絡故障或者消息丟失等狀況,就要犧牲用戶的體驗,等待全部數據所有一致了以後再讓用戶訪問系統。
3.AP wihtout C:
要高可用並容許分區,則需放棄一致性。 一旦分區發生,節點之間可能會失去聯繫,爲了高可用,每一個節點只能用本地數據提供服務
而這樣會致使全局數據的不一致性。
搶購商品時,可能前幾秒你瀏覽商品的時候頁面提示是有庫存的,當你選擇完商品準備下單的時候,系統提示你下單失敗,商品已售完。這其實就是先在
A(可用性)方面保證系統能夠正常的服務,而後在數據的一致性方面作了些犧牲,雖然多少會影響一些用戶體驗,但也不至於形成用戶購物流程的嚴重阻塞。
沒有最好的策略,好的系統應該是根據業務場景來進行架構設計的,只有適合的纔是最好的