從REST和Instance角度理解Netfix Eureka

前言

最近項目開始使用到spring cloud作為項目的微服架構(gòu),在開發(fā)中遇
到很多問題,相信很多多人也遇到桂敛,寫這篇博客也是談?wù)勎谊P(guān)于spring cloud中的eureka的一些認(rèn)識缀遍,當(dāng)中有誤的地方還請各位留言指出,多多交流杭朱。

首先看看官方對eureka的定義

Eureka是一個基于REST(Representational State Transfer)服務(wù),主要是用于云服務(wù)為目的的中間層服務(wù)器的負(fù)載平衡和故障轉(zhuǎn)移阅仔。Eureka還附帶了一個基于java的客戶端組件,Eureka客戶機(jī)使得交互與服務(wù)更加容易』⌒担客戶端也有一個基于循環(huán)負(fù)載平衡內(nèi)置的負(fù)載均衡器八酒。當(dāng)然在Netflix中,還提供很多更加能滿足復(fù)雜要求的負(fù)載均衡器,它們基于交通刃唐、資源使用羞迷、錯誤條件等因素提供更好的彈性。

這個我根據(jù)官方的介紹翻譯的原文鏈接在這https://github.com/Netflix/eureka/wiki/Eureka-at-a-glance/當(dāng)中有翻譯不對的還請留言指出画饥。

從官方的文檔中我們能得到這些重要的信息:

  1. Eureka是基于REST服務(wù)的衔瓮,也就意味著它是基于http協(xié)議的
  2. 它分為服務(wù)端(java語言實現(xiàn))和 客服端(可以是java也可以是非Java語言,因為Eureka提供的是 rest服務(wù)抖甘,當(dāng)然官方也有提供部分其他語言的官方包)热鞍。
  3. Eureka的作用是實現(xiàn)為服務(wù)間的負(fù)載均衡和故障轉(zhuǎn)移。
Eureka的服務(wù)端和客服端

Eureka的服務(wù)端來管理所有的微服,微服內(nèi)的所有服務(wù)需要依賴Eureka客戶端的依賴包薇宠,并在application上添加@EnableEurekaClient注解來實現(xiàn)Eureka客戶端偷办。

<dependency>
  <groupId>com.netflix.eureka</groupId>
  <artifactId>eureka-client</artifactId>
  <version>1.1.16</version>
</dependency>

@EnableEurekaClient
public class ServiceHiApplication {

public static void main(String[] args) {
    SpringApplication.run(ServiceHiApplication.class, args);
}

}

當(dāng)然還有配置文件需要添加相關(guān)的配置,具體的可以參考官方文檔https://github.com/Netflix/eureka/wiki/Configuring-Eureka/
,現(xiàn)在網(wǎng)上也有很多相關(guān)的博客澄港,這里我就不詳細(xì)寫了椒涯。

Eureka的客服端則是通過rest服務(wù)通知Eureka的服務(wù)端該客服端的健康狀況,事實是每個客服端的具體信息保存在InstanceInfo類中回梧,通過ConcurrentHashMap<String, Map<String,Lease<InstanceInfo>>>
的雙層Map結(jié)構(gòu)來管理所有的的客服端废岂。更重要的是其實在每個客服端在以心跳的模式定時通知服務(wù)端客戶端的實時狀態(tài)時,客戶端也會獲得到一份最新的服務(wù)端的InstanceInfo列表清單漂辐,沒錯其實每個客服端也能獲得微服的所有客服端的健康狀況泪喊。具體客服端獲得服務(wù)信息的方法如下:

@Qualifier("eurekaClient")
@Autowired
private EurekaClient eurekaClient;

public String  serviceUrl(){
    InstanceInfo instance = eurekaClient.getNextServerFromEureka("service-hi", false);
    return instance.getHomePageUrl();
}

@Autowired
private DiscoveryClient discoveryClient;
//獲得對應(yīng)服務(wù)名下所有的服務(wù)實力信息列表,服務(wù)如果有做集群髓涯,則返回的是該服務(wù)集群下的所有實力的列表
List<ServiceInstance> list = discoveryClient.getInstances("service-hi");
if (list != null && list.size() > 0 ) {
    String aa = list.get(0).getUri().getAuthority();
}
    
//獲得微服下所有的服務(wù)名
List<String> servicesNames = discoveryClient.getServices();
StringBuilder sb = new StringBuilder();
for (String s:servicesNames) {
    sb.append(s+"\t");
}
Eureka的REST服務(wù)

上面說過服務(wù)端和客戶端是通過rest服務(wù)實現(xiàn)通信的袒啼,也就是說如果我現(xiàn)在想知道服務(wù)端下所有客服端的具體信息和健康狀況只需要通過一個http請求就可以完成,答案是肯定的纬纪,當(dāng)然本身eureka服務(wù)本身就提供了管理界面來查看客戶端的具體信息如下:


image

但是這樣獲得的信息并不完全蚓再,所有如果你想獲得更加詳細(xì)的信息,或則你想使用其他編程語言實現(xiàn)客服端的話可以通過Eureka服務(wù)提供的接口文檔實現(xiàn)注冊包各、取消注冊摘仅、更新、獲得所有InstanceInfo信息等操作,文檔如下:

操作 接口地址 描述
注冊服務(wù) POST /eureka/v2/apps/appID Input: JSON/XML payload HTTP Code: 204 on success
取消服務(wù)注冊 DELETE /eureka/v2/apps/appID/instanceID HTTP Code: 200 on success
發(fā)送一個服務(wù)的心跳 PUT /eureka/v2/apps/appID/instanceID HTTP Code: 200 on success 404 if instanceID doesn’t exist
查詢所有服務(wù)信息 GET /eureka/v2/apps HTTP Code: 200 on success Output: JSON/XML
查詢所有服務(wù)的服務(wù)id GET /eureka/v2/apps/appID HTTP Code: 200 on success Output: JSON/XML
根據(jù)具體服務(wù)id查詢服務(wù)信息 GET /eureka/v2/apps/appID/instanceID HTTP Code: 200 on success Output: JSON/XML
對于一個具體的實例查詢 GET /eureka/v2/instances/instanceID HTTP Code: 200 on success Output: JSON/XML
停止實力服務(wù) PUT /eureka/v2/apps/appID/instanceID/status?value=OUT_OF_SERVICE HTTP Code: 200 on success 500 on failure
把實例重新放入服務(wù)中 DELETE /eureka/v2/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
更新 metadata中的數(shù)據(jù) PUT /eureka/v2/apps/appID/instanceID/metadata?key=value HTTP Code: 200 on success 500 on failure
查詢特定vipaddress地址下的所有實例 GET /eureka/v2/vips/vipAddress HTTP Code: 200 on success Output: JSON/XML 404 if the vipAddress does not exist.
查詢特定安全vipaddress下的所有實例 GET /eureka/v2/svips/svipAddress HTTP Code: 200 on success Output: JSON/XML 404 if the svipAddress does not exist.

官方文檔的鏈接在這:https://github.com/Netflix/eureka/wiki/Eureka-REST-operations/
已獲取所有InstanceInfo列表信息為例问畅,我在postman上的請求結(jié)果如下:

<applications>
<versions__delta>1</versions__delta>
<apps__hashcode>UP_3_</apps__hashcode>
<application>
    <name>SERVICE-HI-APPNAME 8763</name>
    <instance>
        <instanceId>service-hi</instanceId>
        <hostName>DESKTOP-CKLCJ5F</hostName>
        <app>SERVICE-HI-APPNAME 8763</app>
        <ipAddr>192.168.1.8</ipAddr>
        <status>UP</status>
        <overriddenstatus>UNKNOWN</overriddenstatus>
        <port enabled="true">8763</port>
        <securePort enabled="false">443</securePort>
        <countryId>1</countryId>
        <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
            <name>MyOwn</name>
        </dataCenterInfo>
        <leaseInfo>
            <renewalIntervalInSecs>30</renewalIntervalInSecs>
            <durationInSecs>90</durationInSecs>
            <registrationTimestamp>1510988885998</registrationTimestamp>
            <lastRenewalTimestamp>1511102494467</lastRenewalTimestamp>
            <evictionTimestamp>0</evictionTimestamp>
            <serviceUpTimestamp>1510988822454</serviceUpTimestamp>
        </leaseInfo>
        <metadata>
            <testkey4>testValue4</testkey4>
            <testkey3>testValue3</testkey3>
            <testkey2>testValue2</testkey2>
            <testkey1>testValue1</testkey1>
        </metadata>
        <homePageUrl>http://DESKTOP-CKLCJ5F:8763/</homePageUrl>
        <statusPageUrl>http://DESKTOP-CKLCJ5F:8763/info</statusPageUrl>
        <healthCheckUrl>http://DESKTOP-CKLCJ5F:8763/health</healthCheckUrl>
        <vipAddress>service-hi</vipAddress>
        <secureVipAddress>service-hi</secureVipAddress>
        <isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
        <lastUpdatedTimestamp>1510988885998</lastUpdatedTimestamp>
        <lastDirtyTimestamp>1510988885942</lastDirtyTimestamp>
        <actionType>ADDED</actionType>
    </instance>
</application>
<application>
    <name>SERVICE-RIBBON</name>
    <instance>
        <instanceId>DESKTOP-CKLCJ5F:service-ribbon:8764</instanceId>
        <hostName>DESKTOP-CKLCJ5F</hostName>
        <app>SERVICE-RIBBON</app>
        <ipAddr>192.168.1.8</ipAddr>
        <status>UP</status>
        <overriddenstatus>UNKNOWN</overriddenstatus>
        <port enabled="true">8764</port>
        <securePort enabled="false">443</securePort>
        <countryId>1</countryId>
        <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
            <name>MyOwn</name>
        </dataCenterInfo>
        <leaseInfo>
            <renewalIntervalInSecs>30</renewalIntervalInSecs>
            <durationInSecs>90</durationInSecs>
            <registrationTimestamp>1510993263471</registrationTimestamp>
            <lastRenewalTimestamp>1511102494632</lastRenewalTimestamp>
            <evictionTimestamp>0</evictionTimestamp>
            <serviceUpTimestamp>1510988934957</serviceUpTimestamp>
        </leaseInfo>
        <metadata class="java.util.Collections$EmptyMap"/>
        <homePageUrl>http://DESKTOP-CKLCJ5F:8764/</homePageUrl>
        <statusPageUrl>http://DESKTOP-CKLCJ5F:8764/info</statusPageUrl>
        <healthCheckUrl>http://DESKTOP-CKLCJ5F:8764/health</healthCheckUrl>
        <vipAddress>service-ribbon</vipAddress>
        <secureVipAddress>service-ribbon</secureVipAddress>
        <isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
        <lastUpdatedTimestamp>1510993263471</lastUpdatedTimestamp>
        <lastDirtyTimestamp>1510993263422</lastDirtyTimestamp>
        <actionType>ADDED</actionType>
    </instance>
</application>
<application>
    <name>SERVICE-HI-APPNAME 8765</name>
    <instance>
        <instanceId>service-hi</instanceId>
        <hostName>DESKTOP-CKLCJ5F</hostName>
        <app>SERVICE-HI-APPNAME 8765</app>
        <ipAddr>192.168.1.8</ipAddr>
        <status>UP</status>
        <overriddenstatus>UNKNOWN</overriddenstatus>
        <port enabled="true">8765</port>
        <securePort enabled="false">443</securePort>
        <countryId>1</countryId>
        <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
            <name>MyOwn</name>
        </dataCenterInfo>
        <leaseInfo>
            <renewalIntervalInSecs>30</renewalIntervalInSecs>
            <durationInSecs>90</durationInSecs>
            <registrationTimestamp>1511100242138</registrationTimestamp>
            <lastRenewalTimestamp>1511102492656</lastRenewalTimestamp>
            <evictionTimestamp>0</evictionTimestamp>
            <serviceUpTimestamp>1511100242138</serviceUpTimestamp>
        </leaseInfo>
        <metadata>
            <testkey4>testValue4</testkey4>
            <testkey3>testValue3</testkey3>
            <testkey2>testValue2</testkey2>
            <testkey1>testValue1</testkey1>
        </metadata>
        <homePageUrl>http://DESKTOP-CKLCJ5F:8765/</homePageUrl>
        <statusPageUrl>http://DESKTOP-CKLCJ5F:8765/info</statusPageUrl>
        <healthCheckUrl>http://DESKTOP-CKLCJ5F:8765/health</healthCheckUrl>
        <vipAddress>service-hi</vipAddress>
        <secureVipAddress>service-hi</secureVipAddress>
        <isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
        <lastUpdatedTimestamp>1511100242138</lastUpdatedTimestamp>
        <lastDirtyTimestamp>1511100242050</lastDirtyTimestamp>
        <actionType>ADDED</actionType>
    </instance>
</application>
</applications>

上面的信息更加詳細(xì)娃属,如IP地址、服務(wù)的健康狀況护姆、instanceId矾端、hostName等信息都可以查到,方便我們在開發(fā)中發(fā)現(xiàn)問題卵皂。

總結(jié)

相信講到這大家對Eureka是如何管理微服務(wù)已經(jīng)有了一定的認(rèn)識秩铆,管理Eureka下的服務(wù)其實是管理每個InstanceInfo,而負(fù)載均衡,錯誤故障轉(zhuǎn)移都是基于每個InstanceInfo實現(xiàn)的灯变。后面我會單獨對InstanceInfo做更具體的講解殴玛,歡迎大家評論。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末添祸,一起剝皮案震驚了整個濱河市滚粟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌刃泌,老刑警劉巖坦刀,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件愧沟,死亡現(xiàn)場離奇詭異蔬咬,居然都是意外死亡鲤遥,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門林艘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盖奈,“玉大人,你說我怎么就攤上這事狐援「痔梗” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵啥酱,是天一觀的道長爹凹。 經(jīng)常有香客問我,道長镶殷,這世上最難降的妖魔是什么禾酱? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮绘趋,結(jié)果婚禮上颤陶,老公的妹妹穿的比我還像新娘。我一直安慰自己陷遮,他們只是感情好滓走,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著帽馋,像睡著了一般搅方。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绽族,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天姨涡,我揣著相機(jī)與錄音,去河邊找鬼项秉。 笑死绣溜,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的娄蔼。 我是一名探鬼主播怖喻,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼岁诉!你這毒婦竟也來了锚沸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤涕癣,失蹤者是張志新(化名)和其女友劉穎哗蜈,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡距潘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年炼列,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片音比。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡俭尖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出洞翩,到底是詐尸還是另有隱情稽犁,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布骚亿,位于F島的核電站已亥,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏来屠。R本人自食惡果不足惜虑椎,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望的妖。 院中可真熱鬧绣檬,春花似錦、人聲如沸嫂粟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽星虹。三九已至零抬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宽涌,已是汗流浹背平夜。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留卸亮,地道東北人忽妒。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像兼贸,于是被迫代替她去往敵國和親段直。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容