1. 程式人生 > >三、Eurake 服務註冊與發現

三、Eurake 服務註冊與發現

3、 Eurake 服務註冊與發現

3.1 基於Springboot構建Eurake服務

在第二節中《Springboot專案構建》中的第三步 中選擇如下元件:左側選擇cloud Discovery在其子元件中選擇EurakeServer,我們在這裡面還可以看到EurakeDiscoveryZookeeperDiscovery等元件。 其中EurakeDiscovery就是我們後面,將服務提供方的服務註冊到EurakeServer 中時需要引入的元件。

專案構建成功後我們會在pom.xml發現如下依賴:

<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>

說明我們已經成功引入了EurakeServer。 不過我們還需要進行下面配置 雖然我們已經引入了EurakeServer 元件,但我們還需要啟用他(後面很多元件也需要類似的方式去啟用):

@SpringBootApplication
 @EnableEurekaServer
public class EurekaserverApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaserverApplication.class, args);
    }
}

我們通過@EnableEurekaServer去啟用Eurake

resources/application.properties中新增如下配置:

server.port=8761 
eureka.client.register-with-eureka=false #是否將自己註冊到EurrkeServer,預設為true
eureka.client.fetch-registry=false #表示是否從EurekaServer獲取註冊資訊,預設為true,表示需要從其他server同步資訊
eureka.client.service-url.defaultZone= http://localhost:8761/eureka/#設定與EurekaServer 互動的地址,查詢服務和註冊服務都依賴這個地址

至此,我們的Eurake已經配置完成了,是不是很簡單。 啟動服務,開啟http://localhost:8761/我們看看見如下頁面:

目前還沒有服務註冊進來。

Now that we’ve stood up a service registry, let’s stand up a client that both registers itself with the 
registry and uses the Spring Cloud DiscoveryClient abstraction to interrogate the registry for it’s own host and port. The @EnableDiscoveryClient activates the Netflix Eureka DiscoveryClient implementation. There are other implementations for other service registries like Hashicorp’s Consul or Apache Zookeeper.

現在,我們已經註冊了一個服務註冊中心,讓我們再使用登錄檔註冊自己的客戶端,並使用Spring Cloud DiscoveryClient抽象來詢問登錄檔本身的主機和埠。@EnableDiscoveryClient啟用Netflix Eureka DiscoveryClient實現。還有其他服務註冊的實現,比如Hashicorp的領事或Apache Zookeeper。

3.2 基於Springboot 構建服務提供方

在第二節中《Springboot專案構建》中的第三步 中選擇如下元件:

左側選擇cloud Discovery在其子元件中選擇EurakeDiscovery

專案構建成功後我們會在pom.xml發現如下依賴:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

其實與構建EurakeServer 的依賴一樣。

啟用服務發現:

@SpringBootApplication
@EnableDiscoveryClient
public class AppApplication {

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

resources/application.properties中新增如下配置:

server.port=8802 #應用埠號
spring.application.name=app-8801 #服務名稱
eureka.client.service-url.defalutZone= http://localhost:8761/eureka/ #EurekaServer服務地址
turbine.combine-host-port=true #同一主機上的服務,以不同埠號區分,預設情況下是以host來區分,後面服務監控時是將到
eureka.instance.prefer-ip-address=true #表示將自己的IP註冊到EurekaServer 上,如果不配置或者將其設定為false,則表示將微服務所在系統的hostname註冊到EurekaServer上

啟動服務,我們再次開啟http://localhost:8761/我們發現多了一條服務:

我們通過不同埠再次啟動該服務 我們發現有多了一條服務:

我們發現這兩個服務 屬於一個共同的application:APP-8801 ,當服務呼叫端Client去呼叫該服務是,只需知道服務名稱 APP-8801 ,Eurake會通過Ribbon進行負載均衡 隨機請求兩個服務中的一個服務,服務在均衡的策略是可以配置的。在《4、Ribbon 客戶端負載均衡》我會具體介紹,如何去設計負載均衡的策略。

3.3 EurakeServer 高可用

單點的Eurake server 在生產環境下並不適用,一旦發生宕機,會造成所有服務之間的呼叫無法適用,在3.1中配置EurakeServer時 有如下兩個屬性:

 eureka.client.register-with-eureka=false #是否將自己註冊到EurrkeServer,預設為true
 eureka.client.fetch-registry=false #表示是否從EurekaServer獲取註冊資訊,預設為true,表示需要從其他server同步資訊

我關閉了 eurakaServer 將自己註冊的功能,和sever之間的同步功能, 他們是預設開啟的。 我們只要將這兩個設定為true,就可以實現Eurake的高可用了。

Eureka自我保護性

預設情況下Eureka 在90內沒有獲取的服務的心跳,將登出該服務。但是有時候是網路分割槽故障的問題導致Eureka無法收到心跳,服務本身是健壯的,如果刪除此服務,這會導致服務不可用。當開啟了Eureka自我保護後,Eureka會保護此服務在登錄檔中的資訊,使其不會被刪除,等網路恢復後,Eureka節點會自動退出自我保護模式。 Eureka 的自我保護模式預設是允許開啟的,如要禁用可在application.properties 中新增如下配置:

eureka.server.enable-self-preservation=false

3.4 EurakeSever 認證

在生產環境下,我們不可能允許什麼服務都能註冊到Eurake 中,為此需要新增EurakeServer的身份認證。

我們需要在EurakeSever中新增如下依賴:org.springframework.bootspring-boot-starter-security

並在application.properties 中新增如下資訊:

#新增basic認證
security.basic.enabled=true
security.user.name=user
security.user.password=password

此時我們已經為EurakeSever 開啟了Basic 認證

為此,我們也修改服務端,我們只需要將服務提供端application.properties 中原來的

eureka.client.service-url.defalutZone= http://localhost:8761/eureka/

變為: eureka.client.service-url.defalutZone= http://user:[email protected]:8761/eureka/

3.5 Eureka Server Rest 端點

非java編寫的服務可以利用這些Rest端點去操作Eureka。

操作 HTTP action 描述
註冊新的應用例項 POST /eureka/v2/apps/appID 接受JSON/XML格式請求,返回204響應碼錶示成功
傳送應用例項心跳 PUT /eureka/v2/apps/appID/instanceID 返回響應碼200表示成功,404表示instanceID不存在
查詢所有例項 GET /eureka/v2/apps 返回響應碼200表示成功,響應內容格式JSON/XML
為所有appID例項做查詢(Query for all appID instances) GET /eureka/v2/apps/appID 返回響應碼200表示成功,響應內容格式JSON/XML
為特定的appID/instanceID做查詢 GET /eureka/v2/apps/appID/instanceID 返回響應碼200表示成功,響應內容格式JSON/XML
為特定的instanceID做查詢 GET /eureka/v2/instances/instanceID 返回響應碼200表示成功,響應內容格式JSON/XML
停止服務例項(Take instance out of service) PUT /eureka/v2/apps/appID/instanceID/status?value=OUT_OF_SERVICE 返回響應碼200表示成功,500失敗。
將例項恢復到服務(移除覆蓋) DELETE /eureka/v2/apps/appID/instanceID/status?value=UP (value=UP是可選的,它被建議用於fallback狀態,由於取消了覆蓋) 返回響應碼200表示成功,500失敗。
更新元資料 PUT /eureka/v2/apps/appID/instanceID/metadata?key=value 返回響應碼200表示成功,500失敗。
查詢特定vip address 下的所有例項 GET /eureka/v2/vips/vipAddress 返回響應碼200表示成功,響應內容格式:JSON/XML,返回404表示vipAddress不存在
查詢特定secure vip address下所有例項 GET /eureka/v2/svips/svipAddress 返回響應碼200表示成功,響應內容格式:JSON/XML,返回404表示svipAddress不存在

如我請求查詢所有例項http://localhost:8761/eureka/apps獲取到如下結果:

對於我們使用java編寫的應用,基於Springcloud EurekaDiscovery 中已經分裝這些功能。下面對原始碼進行分析一下。

我們可以發現Springcloud 定義了 DiscoveryClient 介面,來抽象Rest端,其下面有三實現類,我們關注的是基於Eureka實現的EurekaDiscoveryClient。檢視此類的實現:此類中引入了com.netflix.discovery包下的EurakeClient 介面。實現此介面的類是com.netflix.discovery包下的DiscovClient 類。