1. 程式人生 > >Spring Cloud系列(二):Eureka應用詳解

Spring Cloud系列(二):Eureka應用詳解

一、註冊中心

  1、註冊中心演變過程

   2、註冊中心必備功能

  ① 服務的上線

  ② 服務的下線

  ③ 服務的剔除

  ④ 服務的查詢

  ⑤ 註冊中心HA

  ⑥ 註冊中心節點資料同步

  ⑦ 服務資訊的儲存,比如mysql,redis,zookeeper,記憶體map等

  3、RPC遠端呼叫過程

  ① 負載均衡策略:隨機,輪詢,一致性Hash等;

  ② 容錯機制:失敗重試,失敗自動切換等;

  ③ 透明代理: 呼叫遠端方法跟呼叫本地的方法一樣;

  ④ 協議: 雙方約定好的協議,比如http協議,dubbo協議等;

  ⑤ 協議編解碼:按照指定的協議進行編解碼;

  ⑤ 序列化反序列化:網路傳輸的都是流,分位元組流和字元流,所以需要對傳輸的資料做序列化,接收的流做反序列化;

  ⑥ 網路傳輸: 知道對方的ip+port就可以建立網路連線也就是socket連線,然後可以發起網路請求和接收對應的響應;

  ⑦ 執行緒池:io執行緒負責io連線,讀取事件,等讀取完成後交給執行緒池去處理相應的業務,類似netty的reactor模型;

二、Eureka詳解

  1、Eureka核心的Rest Api介面列表

請求名稱 請求方式 HTTP地址 請求描述
註冊服務 POST /eureka/apps/{appID} 傳遞JSON或者XML格式的引數內容,HTTP code為204表示成功
刪除服務 DELETE /eureka/apps/{appID}/{instanceID}  HTTP code為200時表示成功
發起心跳  PUT  /eureka/apps/{appID}/{instanceID}  HTTP code為200時表示成功
 查詢服務  GET  /eureka/apps  HTTP code為200時表示成功,返回XML/JSON資料
 查詢指定appID的服務列表  GET  /eureka/apps/{appID}  HTTP code為200時表示成功,返回XML/JSON資料
 查詢指定appID&instanceID的服務  GET  /eureka/apps/{appID}/{instanceID}  獲取指定appID以及instanceID的服務資訊,HTTP code為200時表示成功,返回XML/JSON資料
 查詢指定instanceID服務列表  GET  /eureka/apps/instances/{instanceID}  獲取指定instanceID的服務資訊,HTTP code為200時表示成功,返回XML/JSON資料
 變更服務狀態  PUT  /eureka/apps/{appID}/{instanceID}/status?value=DOWN  服務上線、服務下線等狀態改變,HTTP code為200時表示成功

   2、Eureka服務端和客戶端

  2.1 搭建Eureka服務端

  第一步:加依賴

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

  第二步:加註解

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

  第三步:編寫配置檔案

server:
  #Eureka服務端應用的埠預設是8761
  port: 8761
eureka:
  client:
    #表示是否將自己註冊到EurekaServer,預設為true,由於當前應用就是EurekaServer,故而設為false
    registerWithEureka: false
    #表示是否從EurekaServer獲取註冊資訊,預設為true,因為這是一個單點的EurekaServer,不需要同步其他的EurekaServer節點的資料
    fetchRegistry: false
    #註冊地址
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

  2.2 搭建Eureka客戶端

  第一步:加依賴

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

  第二步:加註解

/**
 * spring-cloud F版本可不寫 @EnableDiscoveryClient
 * @desc: 使用者服務啟動
 * @author: toby
 */
@SpringBootApplication
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
}

  第三步:編寫配置檔案

#eureka
eureka:
  client:
    #註冊到Eureka服務端的地址
    serviceUrl:
      defaultZone: http://localhost:8761/eureka
  instance:
    #點選具體的微服務,右下角是否顯示ip
    prefer-ip-address: true

   第四步:使用RestTemplate呼叫,需要加@LoadBalanced註解

 /**
     * 負載均衡加上@LoadBalanced
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

  當然實際專案中都是採用FeignClient來呼叫的。

  啟動Eureka服務端和客戶端:

   3、Eureka部署架構

  3.1 架構圖

  3.2 Region

區域 編碼
亞太(東京) ap-northeast-1
亞太(新加坡) ap-southeast-1
亞太(悉尼) ap-southeast-2
歐洲(愛爾蘭) eu-west-1
南美(聖保羅) sa-east-1
美東(北佛傑尼亞) us-east-1
美西(北加利佛尼亞) us-west-1
美西(俄勒岡) us-west-2

   3.3 核心功能

  ① 服務註冊(Register):Eureka Client會通過傳送REST請求向Eureka Server註冊自己的服務,提供自身IP、埠、微服務名稱等資訊。Eureka Server接收到註冊請求後,就會把這些資訊儲存在一個雙層的Map中。

  ② 服務續約(Renew):在服務註冊後,Eureka Client會維護一個心跳來持續通知Eureka Server,說明服務一直處於可用狀態,防止被剔除。Eureka Client在預設的情況下會每隔30秒(eureka.instance.leaseRenewallIntervalInSeconds)傳送一次心跳來進行服務續約。

  ③ 服務同步(Replicate):Eureka Server叢集中多個Eureka Server之間會互相進行註冊,不同Eureka Server之間會進行服務同步,用來保證Eureka Server叢集內的所有例項中的資料一致性(從這個架構來看,Eureka Server所有例項所處的角色都是對等的,沒有類似Zookeeper、選舉過程,也不存在主從,所有的節點都是主節點。Eureka官方將Eureka Server叢集中的所有例項稱為"對等體(peer)")。

  ④ 獲取服務(Get Registry):服務消費者(Eureka Client)在啟動的時候,會發送一個REST請求給Eureka Server,獲取上面註冊的服務清單,並且快取在Eureka Client本地,預設快取30秒(eureka.client.registryFetchIntervalSeconds)。同時,為了效能考慮,Eureka Server也會維護一份只讀的服務清單快取,該快取每隔30秒更新一次。

  ⑤ 服務呼叫(Make Remote Call):服務消費者在獲取到服務清單後,就可以根據清單中的服務列表資訊,查詢到其他服務的地址,從而進行遠端呼叫。

  ⑥ 服務下線(Cancel):當Eureka Client需要關閉或重啟時,就不希望在這個時間段內再有請求進來,所以,就需要提前先發送REST請求給Eureka Server,告訴Eureka Server自己要下線了,Eureka Server在收到請求後,就會把該服務狀態置為下線(DOWN),並把該下線事件傳播出去。

  ⑦ 服務剔除(Evict):服務例項可能會因為網路故障等原因導致不能提供服務,而此時該例項也沒有傳送請求給Eureka Server來進行服務下線,所以,還需要有服務剔除的機制。Eureka Server在啟動的時候會建立一個定時任務,每隔一段時間(預設60秒),從當前服務清單中把超時沒有續約(預設90秒,eureka.instance.leaseExpirationDurationInSeconds )的服務剔除。

  ⑧ 自我保護:既然Eureka Server會定時剔除超時沒有續約的服務,那就有可能出現一種場景,網路一段時間內發生了異常,所有的服務都沒能夠進行續約,Eureka Server就把所有的服務都剔除了,這樣顯然不太合理。所以,就有了自我保護機制,當短時間內,統計續約失敗的比例,如果達到一定閾值,則會觸發自我保護的機制,在該機制下,Eureka Server不會剔除任何的微服務,等到正常後,再退出自我保護機制。自我保護開關(eureka.server.enableself-preservation: false)

三、Eureka高可用

  啟動eureka-8761,eureka-8762 2個服務

  1、eureka-8761配置檔案如下:

spring:
  application:
    name: eureka-ha
server:
  #Eureka服務端應用的埠預設是8761
  port: 8761
eureka:
  client:
    #表示是否將自己註冊到EurekaServer,表示8761的服務端需要向8762註冊自己
    registerWithEureka: true
    #表示是否從EurekaServer獲取註冊資訊,預設為true,需要從8762獲取資料
    fetchRegistry: true
    #註冊地址
    serviceUrl:
      defaultZone: http://localhost:8762/eureka/

  2、eureka-8762配置檔案如下:

spring:
  application:
    name: eureka-ha
server:
  #Eureka服務端應用的埠預設是8761
  port: 8762
eureka:
  client:
    #表示是否將自己註冊到EurekaServer,表示8762的服務端需要向8761註冊自己
    registerWithEureka: true
    #表示是否從EurekaServer獲取註冊資訊,預設為true,需要從8761獲取資料
    fetchRegistry: true
    #註冊地址
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

  3、eureka-client需要向2個註冊中心註冊服務(其實寫一個就可以,因為eureka叢集中的例項之前會同步資料)

#eureka
eureka:
  client:
    #註冊到Eureka服務端的地址
    serviceUrl:
      defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka

  啟動後: