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

1、註冊中心

  一、註冊中心演變過程

   二、註冊中心必備功能

  ① 服務的上線mysql

  ② 服務的下線react

  ③ 服務的剔除redis

  ④ 服務的查詢spring

  ⑤ 註冊中心HAsql

  ⑥ 註冊中心節點數據同步緩存

  ⑦ 服務信息的存儲,好比mysql,redis,zookeeper,內存map等網絡

  三、RPC遠程調用過程

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

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

  ③ 透明代理: 調用遠程方法跟調用本地的方法同樣;負載均衡

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

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

  ⑤ 序列化反序列化:網絡傳輸的都是流,分字節流和字符流,因此須要對傳輸的數據作序列化,接收的流作反序列化;

  ⑥ 網絡傳輸: 知道對方的ip+port就能夠創建網絡鏈接也就是socket鏈接,而後能夠發起網絡請求和接收對應的響應;

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

2、Eureka詳解

  一、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時表示成功

   二、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服務端和客戶端:

   三、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)

3、Eureka高可用

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

  一、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/

  二、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/

  三、eureka-client須要向2個註冊中心註冊服務(其實寫一個就能夠,由於eureka集羣中的實例以前會同步數據)

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

  啓動後: