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
啟動後: