1. 程式人生 > >springcloud-Eureka-服務註冊與發現核心元件

springcloud-Eureka-服務註冊與發現核心元件

Eureka元件

Eureka是Netfilx開源的服務發現元件,本身是一個基於rest的服務,它包含client和server兩部分。

Spirng Cloud將它整合在子專案Spirng Cloud Netfilx中,從而實現服務的註冊和發現

client註冊到Server什麼?

client註冊後還會在本地做一個快取,防止Server宕機後服務無法呼叫,如果提供服務的service宕機,此時呼叫不就出錯了嗎?所以要做Server的叢集,後文會提到。

1.eureka中的server和client的介紹及特點

  • Eureka Server:提供服務發現的能力,各個微服務啟動時,會向Eureka Server註冊自己的資訊例如(IP,埠號,服務名稱等),Eureka會儲存這些資訊。
  • Eureka Client:是一個java的客戶端用來簡化Eureka Server的互動。
  • 微服務啟動後會週期性的(預設30秒)向Eureka Server傳送心跳,如果Eureka在規定的時間沒有收到心跳,則會登出該例項(預設90秒)。
  • Eureka Client會快取服務登錄檔中的資訊。這種方式有一定的優勢首先可以降低Eureka Server的壓力,其次當所有的Eureka Server宕機服務呼叫方依然可以完成呼叫。

2.服務註冊與服務發現

  • 服務註冊:當微服務client啟動時,向Eureka Server發起註冊,並上報該節點的相關資訊
  • 服務發現:client從Eureka Server獲取註冊資訊,然後發起呼叫

3.Eureka Server開發

測試環境使用springcloud的Dalston版本。由IDEA快速構建出springboot專案,再引入相關依賴。

1.引入springcloud的相關依賴
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--eureka server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
    </dependencies>
    <!--依賴管理,所引入的jar都是沒有版本號的,全部都是Dalston版本-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.RC1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!--倉庫-->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
2.入口類的開發
//啟用EurekaServer
@EnableEurekaServer
@SpringBootApplication
public class EurekaServer {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer.class,args);
    }
}
3.配置檔案
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
#不能向自身註冊
eureka.client.register-with-eureka=false
#關閉自我發現
eureka.client.fetch-registry=false
#本例項名稱
spring.application.name=eureka
#使用埠號
server.port=8761

注意:Eureka本身既是Server又是Client,作為Server不能向自身註冊,自我發現關閉。

檢視Server的狀態,Eureka提供了一個web介面檢視當前Server上的註冊例項以及其他資訊

地址:http://127.0.0.1:8761/

這裡忘記截圖了,假裝沒有例項註冊,將就看下

2.Eureka Client的開發

1.jar包和Server不同
       將spring-cloud-starter-eureka-server改為spring-cloud-starter-eureka
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
2.入口類
//該註解可以將client註冊到以zookeeper為server的服務中心
@EnableDiscoveryClient
//該註解註冊到Eureka  @EnableEurekaClient
@SpringBootApplication
public class HiApplication {

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

3.配置檔案

#指定Eureka Server的地址
eureka.client.service-url.default-zone=http://localhost:8761/eureka
server.port=8762
spring.application.name=eureka-client

3.Eureka client之間的相互呼叫測試

準備兩個client,一個作為消費者,一個作為服務者。

服務者

1.匯入相關的jar
同上Client
2.入口類同上
3.配置檔案
eureka.client.service-url.default-zone=http://localhost:8761/eureka
server.port=8762
spring.application.name=eureka-provider
編寫一個作為測試用的Controller
@RestController
@RequestMapping("/test")
public class TestController {

    @RequestMapping("/test1")
    public String test(String name){
        return "xixixi 8763  :"+name;
    }
}

消費者

1.jar不變
2.入口類不變
3.配置檔案
eureka.client.service-url.default-zone=http://localhost:8761/eureka
server.port=8763
spring.application.name=eureka-client
4.使用java配置RestTemplate
@Configuration
public class RestTemplateConf {
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

關於RestTemplate的說明:類似於HTTPClient,在程式中發起http請求,RestTemplate是對HTTPClient的封裝。

5.寫個簡單的控制器
@RestController
@RequestMapping("/query")
public class ClientController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/test")
    public String test(String name){
        String template = restTemplate.getForObject("http://EUREKA-PROVIDER/test/test1?name=" + name, String.class);
        return template;
    }
}

方法說明:getForObject("http://EUREKA-PROVIDER/test/test1?name=" + name, String.class); EUREKA-PROVIDER是註冊過的例項名稱,可以在Eureka Server的web介面看到的,大小寫都可以,是有對應的對映的地址的。

6.測試

啟動Eureka Server,兩個Client,檢視Eureka Server 中註冊的例項是否有兩個Client,兩個則正常;

位址列發起請求:http://localhost:8763/query/test?name=xixi

檢視結果呼叫成功。

4.Eureka的自我保護機制

Eureka進入自我保護機制的最直接體現,是Eureka首頁輸出警告如圖:

預設情況下,如果Eureka Server在一定時間內沒有接受到服務例項的心跳,Eureka將會登出該例項(預設90秒).但是當網路分割槽發生故障時,微服務和Eureka Server 無法正常通訊.以上行為可能變得特別危險了-因為微服務本身是健康的,此時不能登出該服務例項.

Eureka通過自我保護機制來解決這個問題,當Eureka Server在短時間丟失過多的服務例項(可能發生了網路分割槽的故障,那麼這個節點進入自我保護模式,一旦進入此模式,Eureka Server將會保護服務登錄檔中的資訊,不再刪除服務登錄檔中的資料(也就是不再登出任何的服務例項),當網路故障恢復後,Eureka會自動退出自我保護模式。

綜上,自我保護模式是一種應對網路故障的安全保護措施,它的架構哲學是寧可同時保留所有的微服務,也不盲目登出任何健康的微服務,使用自我保護模式可以讓Eureka,更加健壯,穩定。

在springcloud中可以通過

#關閉自我保護機制  預設開啟
eureka.server.enable-self-preservation=false

如果想及時剔除eureka的服務除了關閉自我保護機制外,可以調低eureka的心跳值

eureka-server服務端
配置檔案中新增如下配置

#關閉保護機制,以確保註冊中心將不可用的例項正確剔除
eureka.server.enable-self-preservation=false
#(代表是5秒,單位是毫秒,清理失效服務的間隔 )
eureka.server.eviction-interval-timer-in-ms=5000
客戶端
配置檔案中新增如下配置

# 心跳檢測檢測與續約時間
# 測試時將值設定設定小些,保證服務關閉後註冊中心能及時踢出服務
# 配置說明
#  lease-renewal-interval-in-seconds 每間隔10s,向服務端傳送一次心跳,證明自己依然”存活“
#  lease-expiration-duration-in-seconds  告訴服務端,如果我20s之內沒有給你發心跳,就代表我“死”了,將我踢出掉。
eureka.instance.lease-renewal-interval-in-seconds=10
eureka.instance.lease-expiration-duration-in-seconds=20

5.client的高可用

搭建Client的叢集十份簡單,只需要保證例項名稱一致,比如都叫做:client-provider,但是埠不能衝突。

保證埠號不一致(測試環境)
保證例項名一致!!!
示例配置
eureka.client.service-url.defaultZone=http://peer:8761/eureka
spring.application.name=eureka-provider
server.port=8764        
eureka.client.service-url.defaultZone=http://peer:8761/eureka
spring.application.name=eureka-provider
server.port=8763        
最終在Eureka Server的web介面可以看到如下一個叢集

6.Eureka Server的高可用

單節點的Eureka Server 不適合線上的生產環境,Eureka Client會定時連線Eureka Server,獲取服務登錄檔中的資訊並快取在本地,微服務消費遠端API總是使用本地快取的資料,因此一般來說既是Eureka Server發生宕機,也不會影響到服務的呼叫,但是如果Eureka Server宕機時某些微服務也出現了不可用的情況,Eurek Client中的快取若不被更新,可能會影響到服務的呼叫,甚至影響到整個系統的高可用性,因此在生產環境會部署一個高可用的Eureka Server叢集。

Eureka可以通過執行多個例項並互相註冊實現高可用部署,Eureka Server例項會彼此同步資訊。

Server1向Server2註冊
server.port=8761
eureka.client.service-url.defaultZone=http://peer1:8765/eureka
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.instance.hostname=peer1
server.port=8762
eureka.client.service-url.defaultZone=http://peer:8761/eureka
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
spring.application.name=peer
注:peer是hosts對映本地127.0.0.1,http://peer1:8761/eureka,peer1作為Eureka複製集的名稱
注意:在client註冊到eureka server時 需要填寫所有eureka server的地址
eureka.client.service-url.defaultZone=http://peer:8761/eureka,http://peer1:8765/eureka

7.Eureka的健康監測

服務有時候也會出現異常情況,我們也需要知道某個服務的健康狀況。我們可以通過新增如下依賴,開啟某個服務的健康檢查。

      <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-actuator</artifactId>
       </dependency>

我們來訪問一下這個介面http://localhost:port/health,看到了一個很簡短的健康報告:

{"description":"Spring Cloud Eureka Discovery Client","status":"UP"}

類似的還有

  • info 顯示任意的應用資訊
  • metrics 展示當前應用的指標資訊 true
  • mappings 顯示所有@RequestMapping路徑的整理列表
  • trace 顯示trace資訊(預設為最新的一些HTTP請求)
  • health 展示應用的健康資訊
  • beans 顯示一個應用中所有Spring Beans的完整列表

這其中有一些是敏感資訊,出於安全考慮,一般使用者無法訪問,如果內網情況下可以

eureka.client.healthcheck.enabled=true
#關掉認證(公網下的生產環境不建議,內網部署可以)
management.security.enabled=false

8.http VS rpc

應用間通訊方式主要是HTTP和RPC,在微服務架構中兩大配方的主角分別是:

  • Dubbo RPC框架

基於dubbo開發的應用還是要依賴周邊的平臺生態, 相比其它的RPC框架, dubbo在服務治理與服務整合上可謂是非常完善, 不僅提供了服務註冊,發現還提供了負載均衡,叢集容錯等基礎能力同時,還提供了面向開發測試節點的Mock和泛化呼叫等機制。 在spring cloud 出現之前dubbo在國內應用十分廣泛,但dubbo定位始終是一個RPC框架。

  • SpringCloud 微服務框架(HTTP通訊)

Spring Cloud 的目標是微服務架構下的一棧式解決方案,自dubbo復活後dubbo官方表示要積極適配到spring cloud的生態方式,比如作為springcloud的二進位制通訊方案來發揮dubbo的效能優勢,或者通過dubbo的模組化以及對http的支援適配到Spring Cloud,但是到目前為止dubbo與spring cloud 還是不怎麼相容,spring cloud 微服務架構下微服務之間使用http的RestFul方式進行通訊,Http RestFul 本身輕量易用適用性強,可以很容易跨語言,跨平臺,或者與已有的系統整合。