在跟我學Spring Cloud(Finchley版)-05-服務註冊與服務發現-Eureka入門 一節中,已經編寫了一個Eureka Server,並將服務提供者與消費者都註冊到了Eureka Server上。html
本節,來深刻探討Eureka的高級特性。java
本節來探討Eureka的原理。python
下面分析一下Eureka原理,在分析原理前,先來了解一下Region和Availability Zone,以下圖。git
衆所周知,Netflix公司將他們的應用都部署在了AWS上,因此Eureka的架構使用到了AWS中的一些概念——不用擔憂,這不是說Eureka和AWS環境綁定,Eureka能夠部署在任意環境。github
Region和Availability Zone均是AWS的概念。spring
Spring Cloud中,默認使用的Region是us-east-1
。非AWS環境下,可將將Region理解爲內網沒有打通的機房,將Availability Zone理解成相同機房的不一樣機架(內網打通)。npm
拓展閱讀vim
如圖是Eureka集羣的工做原理。圖中的組件很是多,概念也比較抽象,咱們先來用通俗易懂的文字翻譯一下:windows
由圖可知,Eureka包含兩個組件:Eureka Server 和 Eureka Client,它們的做用以下:api
綜上,Eureka經過心跳檢查、客戶端緩存等機制,提升了系統的靈活性、可伸縮性和可用性。
TIPS
事實上,這個官方架構圖是有一點問題的:Eureka Server自己也集成了Eureka Client,彼此經過Eureka Client同步數據給其它實例又或者從其餘實例同步數據——如今,你應該能理解上一節中所使用的 register-with-eureka
以及fetch-registry
的做用了。
下面來編寫一個雙節點Eureka Server集羣。編寫這個集羣很是簡單,只需修改單實例Eureka Server的配置便可:
爲系統配置主機名:
vim /etc/hosts # 添加以下內容 127.0.0.1 peer1 peer2 對於Windows系統,請修改C:\windows\system32\drivers\etc\hosts文件
配置:
spring: application: name: microservice-discovery-eureka-ha --- spring: profiles: peer1 # 指定profile=peer1 server: port: 8761 eureka: instance: hostname: peer1 # 指定當profile=peer1時,主機名是peer1 client: serviceUrl: defaultZone: http://peer2:8762/eureka/ # 將本身註冊到peer2這個Eureka上面去 --- spring: profiles: peer2 server: port: 8762 eureka: instance: hostname: peer2 client: serviceUrl: defaultZone: http://peer1:8761/eureka/
由配置不難看出咱們設置了兩個Profile:peer一、peer2。兩個Profile下各有一個Eureka Server,經過相互註冊的方式,構建了Eureka Server集羣。
啓動:
java -jar microservice-discovery-eureka-ha-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1 java -jar microservice-discovery-eureka-ha-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
第一個實例會報錯,這是正常的,由於它會嘗試鏈接第二個實例,但第二個實例還沒有啓動,因此會報鏈接不上的異常。
注意點
http://127.0.0.1:8761/eureka/
)相互註冊,Eureka Server誤認爲兩個Eureka Server實例是一個實例——這會形成Eureka Server首頁顯示不正常等一系列問題!!拓展閱讀
TIPS
編寫Eureka Server集羣的簡寫方式:
spring: application: name: microservice-discovery-eureka-ha eureka: client: serviceUrl: defaultZone: http://peer2:8762/eureka/,http://peer1:8761/eureka/ --- spring: profiles: peer1 server: port: 8761 eureka: instance: hostname: peer1 --- spring: profiles: peer2 server: port: 8762 eureka: instance: hostname: peer2
以microservice-provider-user
項目爲例,只須修改eureka.client.serviceUrl.defaultZone
,配置多個Eureka Server地址,就能夠將其註冊到Eureka Server集羣了。示例:
eureka: client: serviceUrl: defaultZone: http://peer1:8761/eureka/,http://peer2:8762/eureka/
這樣就能夠將服務註冊到Eureka Server集羣上了。
固然,微服務即便只配置Eureka Server集羣中的某個節點,也能正常註冊到Eureka Server集羣,由於多個Eureka Server之間的數據會相互同步。例如:
eureka: client: serviceUrl: defaultZone: http://peer1:8761/eureka/
正常狀況下,這種方式與配置多個Server節點的效果是同樣的。不過爲適應某些極端場景,筆者建議在客戶端配置多個Eureka Server節點。
應用啓動後,訪問Eureka Server應能看到相似以下的界面:
前文說過,Eureka自己是一個基於REST的服務。本節來探討Eureka Server的RESTful API。
下表展現了Eureka Server提供的RESTful API,來自https://github.com/Netflix/eureka/wiki/Eureka-REST-operations ,只需按表格向Eureka Server發送請求,便可操做Eureka Server中的數據。
Operation | HTTP action | Description |
---|---|---|
Register new application instance | POST /eureka/apps/appID | Input:JSON/XMLpayload HTTPCode: 204 on success |
De-register application instance | DELETE /eureka/apps/appID/instanceID | HTTP Code: 200 on success |
Send application instance heartbeat | PUT /eureka/apps/appID/instanceID | HTTP Code: 200 on success 404 if instanceID doesn’t exist |
Query for all instances | GET /eureka/apps | HTTP Code: 200 on success Output:JSON/XML |
Query for all appIDinstances | GET /eureka/apps/appID | HTTP Code: 200 on success Output:JSON/XML |
Query for a specificappID/instanceID | GET /eureka/apps/appID/instanceID | HTTP Code: 200 on success Output:JSON/XML |
Query for a specificinstanceID | GET /eureka/instances/instanceID | HTTP Code: 200 on success Output:JSON/XML |
Take instance out of service | PUT /eureka/apps/appID/instanceID/status?value=OUT_OF_SERVICE | HTTP Code: 200 on success 500 on failure |
Put instance back into service (remove override) | DELETE /eureka/apps/appID/instanceID/status?value=UP (The value=UP is optional, it is used as a suggestion for the fallback status due to removal of the override) | HTTP Code: 200 on success 500 on failure |
Update metadata | PUT /eureka/apps/appID/instanceID/metadata?key=value | HTTP Code: 200 on success 500 on failure |
Query for all instances under a particular vip address | GET /eureka/vips/vipAddress | HTTP Code: 200 on success Output:JSON/XML 404 if thevipAddressdoes not exist. |
Query for all instances under a particular secure vip address | GET /eureka/svips/svipAddress | HTTP Code: 200 on success Output:JSON/XML 404 if thesvipAddressdoes not exist. |
示例1:註冊一個服務:
將如下文件存儲爲rest-api-test.xml
<instance> <instanceId>itmuch:rest-api-test:9000</instanceId> <hostName>itmuch</hostName> <app>REST-API-TEST</app> <ipAddr>127.0.0.1</ipAddr> <vipAddress>rest-api-test</vipAddress> <secureVipAddress>rest-api-test</secureVipAddress> <status>UP</status> <port enabled="true">9000</port> <securePort enabled="false">443</securePort> <homePageUrl>http://127.0.0.1:9000/</homePageUrl> <statusPageUrl>http://127.0.0.1:9000/info</statusPageUrl> <healthCheckUrl>http://127.0.0.1:9000/health</healthCheckUrl> <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo"> <name>MyOwn</name> </dataCenterInfo> </instance>
經過cURL調用Eureka Server
cat ./rest-api-test.xml | curl -v -X POST -H "Content-type: application/xml" -d @- http://localhost:8761/eureka/apps/rest-api-test
示例2:查看指定服務的所註冊的信息
只需訪問:http://Eureka Server的地址/eureka/apps/microservice-provider-user
便可查看microdervice-provider-user
服務的信息。
你可能會問:咱們不是已經有Eureka Client了嗎?誰閒着沒事再去用RESTful API啊?
要知道,微服務的優點之一就是容許使用異構的技術、異構的語言甚至異構的平臺解決你想解決的問題。
舉個例子,若是你有一個系統,一部分是Spring Cloud構建的,一部分是用世界上最好的語言PHP寫的!可是呢,你但願Java應用與PHP應用之間的通訊也能享受服務發現所帶來的好處,此時就可編寫一個基於PHP的Eureka Client,將PHP應用也註冊到Eureka Server!
事實上,前文說的Eureka Client不過是一個用Jersey 1.x封裝了RESTful API的Jar包而已。
拓展閱讀 事實上,業界已經有一些不一樣語言的Eureka Client,例如:
自我保護模式是Eureka的重要特性,筆者以前已經專題寫過文章詳解了,因此本系列再也不贅述,詳見:理解Eureka的自我保護模式
Finchley版本相對以前的版本有些改動,比較重要。詳見: 跟我學Spring Cloud(Finchley版)番外-01-Eureka安全詳解 。
http://www.itmuch.com/spring-cloud/finchley-6/