eureka-server详解
注冊中心
Eureka是Netflix開發的服務發現框架,本身是一個基于REST的服務,主要用于定位運行在AWS域中的中間層服務,以達到負載均衡和中間層服務故障轉移的目的。SpringCloud將它集成在其子項目spring-cloud-netflix中,以實現SpringCloud的服務發現功能。
Eureka包含兩個組件:Eureka Server和Eureka Client。
- Eureka Server提供服務注冊服務,各個節點啟動后,會在Eureka Server中進行注冊,這樣EurekaServer中的服務注冊表中將會存儲所有可用服務節點的信息,服務節點的信息可以在界面中直觀的看到。
- Eureka Client是一個java客戶端,用于簡化與Eureka Server的交互,客戶端同時也就是一個內置的、使用輪詢(round-robin)負載算法的負載均衡器。
- 在應用啟動后,將會向Eureka Server發送心跳,默認周期為30秒,如果Eureka Server在多個心跳周期內沒有接收到某個節點的心跳,Eureka Server將會從服務注冊表中把這個服務節點移除(默認90秒)。
- Eureka Server之間通過復制的方式完成數據的同步,Eureka還提供了客戶端緩存機制,即使所有的Eureka Server都掛掉,客戶端依然可以利用緩存中的信息消費其他服務的API。綜上,Eureka通過心跳檢查、客戶端緩存等機制,確保了系統的高可用性、靈活性和可伸縮性。
服務治理:Spring Cloud Eureka
什么是服務治理
服務治理可以說是微服務架構中最為核心和基礎的模塊,它主要用來實現各個微服務實例的自動化注冊與發現。為什么需要服務治理模塊
在最初構建微服務系統的時候可能服務并不多,我們可以通過做一些靜態配置來完成服務調用?
此時看著一切都還正常。
隨著項目逐漸接近尾聲,維護人員需要維護的服務越來越多,越來越復雜,最終形成大量的配置文件,維護將會變得越來越困難。此時,微服務應用實例自動化管理框架變得至關重要。
服務治理框架需要完成什么任務
● 服務注冊:在服務治理框架中,通常都會構建一個注冊中心,每個服務單元向注冊中心登記自己提供的服務,將主機與端口號、版本號、通信協議等一些附加信息告知注冊中心,注冊中心按服務名分類組織服務清單。
● 服務發現:我們的所有服務都已經注冊到注冊中心,并且在注冊中心是按照服務名分類,并且由注冊中心維護者服務的具體位置。所以調用方需要調用某個服務時,需要先和注冊中心咨詢,注冊中心會返回被調用方服務的所有具體位置,調用方在根據某種輪詢策略選擇一個具體位置進行服務調用。
Netflix Eureka
Spring Cloud Eureka,使用Netflix Eureka來實現服務注冊與發現,它既包含了服務端組件,也包含了客戶端組件。
Eureka服務端
Eureka服務端,我們也稱為服務注冊中心,他同其他服務注冊中心一樣,支持高可用配置。它依托于強一致性提供良好的服務實例可用性,可以應對多種不同的故障場景。
如果Eureka以集群方式部署,當集群中有分片出現故障時,那么Eureka就轉入自我保護模式。它允許在分片故障期間繼續提供服務的發現和注冊,當故障分片恢復運行時,集群中的其他分片會把它們的狀態再次同步回來。
Eureka客戶端
Eureka客戶端,主要處理服務的注冊與發現。客戶端服務通過注解和參數配置的方式,嵌入在客戶端應用程序的代碼中,在應用程序運行時,Eureka客戶端向注冊中心注冊自身提供的服務并周期性地發送心跳來更新它的服務租約。同時,他也能從服務端查詢當前注冊的服務信息并把它們緩存到本地并周期性地刷新服務狀態。
服務端與客戶端的關系
?
注冊中心代碼詳解
配置文件
eureka: server: shouldUseReadOnlyResponseCache: true #eureka是CAP理論種基于AP策略,為了保證強一致性關閉此切換CP 默認不關閉 false關閉 enable-self-preservation: false #關閉服務器自我保護,客戶端心跳檢測15分鐘內錯誤達到80%服務會保護,導致別人還認為是好用的服務 eviction-interval-timer-in-ms: 60000 #清理間隔(單位毫秒,默認是60\*1000)5秒將客戶端剔除的服務在服務注冊列表中剔除# response-cache-update-interval-ms: 3000 ##eureka server刷新readCacheMap的時間,注意,client讀取的是readCacheMap,這個時間決定了多久會把readWriteCacheMap的緩存更新到readCacheMap上 #eureka server刷新readCacheMap的時間,注意,client讀取的是readCacheMap,這個時間決定了多久會把readWriteCacheMap的緩存更新到readCacheMap上默認30s response-cache-auto-expiration-in-seconds: 180 ##eureka server緩存readWriteCacheMap失效時間,這個只有在這個時間過去后緩存才會失效,失效前不會更新,過期后從registry重新讀取注冊服務信息,registry是一個ConcurrentHashMap。 client: register-with-eureka: true #false:不作為一個客戶端注冊到注冊中心 fetch-registry: false #為true時,可以啟動,但報異常:Cannot execute request on any known server instance-info-replication-interval-seconds: 10 service-url: defaultZone: [http://127.0.0.1:1111/eureka](http://127.0.0.1:1111/eureka) instance: prefer-ip-address: true instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${spring.application.instance\_id:${server.port}} lease-renewal-interval-in-seconds: 30 ## 續約更新時間間隔(默認30秒) lease-expiration-duration-in-seconds: 90 # 續約到期時間(默認90秒) ribbon: ServerListRefreshInterval: 1000org.springframework.boot
???spring-boot-starter-actuator
左側2.0.x版本 右側1.5.9版本差異
核心代碼@EnableEurekaServer注解
/** * @author 作者 owen E-mail: 624191343@qq.com * @version 創建時間:2017年11月28日 下午22:50:29 * 類說明 * eureka高可用三臺機器 */@EnableEurekaServer @SpringBootApplication //@EnableHystrixDashboard //@EnableTurbine public class EurekaServerApp {public static void main(String[] args) {// 1本地啟動采用此方法加載profiles文件 // ConfigurableApplicationContext context = new SpringApplicationBuilder(EurekaServerApp.class). // profiles("slave0").run(args);SpringApplication.run(EurekaServerApp.class, args); // 2服務器采用此方法 java -jar --spring.profiles.active=slave3; // SpringApplication.run(EurekaServerApp.class, args);}}OCP服務治理
eureka重要源碼
com.netflix.eureka.resources.ServerInfoResource
com.netflix.eureka.resources.ApplicationsResource
com.netflix.eureka.resources.InstancesResource
com.netflix.eureka.resources.InstanceResource
com.netflix.eureka.resources.StatusResource
服務治理api
獲取服務列表
獲取某個服務的實例列表
服務下線
服務上線
服務發現負載均衡
指定負載均衡算法
負載均衡器通過Eureka獲取動態后端服務列表
Netflix源碼解析之Ribbon:負載均衡器通過Eureka獲取動態后端服務列表 - 為程序員服務
Ribbon是一種客戶端的負載均衡,本質上是跑在服務消費者的進程里。服務消費者要訪問服務時,通過ribbon向一個服務注冊的列表查詢,然后以配置的負載均衡策略選擇一個后端服務發起請求。
前面?ribbon的實現?,講到LB的定義的兩個主要方法,分別是后端服務相關的調用:
public void addServers(List<Server> newServers); public List<Server> getServerList(boolean availableOnly);在netflix中這個服務注冊列表其實就是eureka服務端集中管理的注冊服務列表。獲取這個列表應該就是是通過eureka的client來完成的。
Netflix源碼解析之Ribbon:負載均衡器通過Eureka獲取動態后端服務列表 - 為程序員服務
也就是ribbon中應該在某個地方集成了eureka client來維護服務列表。這里嘗試追蹤細這個過程,確認下猜想。
ribbon的實現?的繼承圖上可以看到除了介紹的基本實現LoadBalancer外,還有DynamicServerListLoadBalancer的實現,可以動態的加載后端服務列表。正如名所示,可以動態的加載后端的服務列表。
DynamicServerListLoadBalancer中使用一個ServerListRefreshExecutorThread任務線程定期的更新后端服務列表。
class ServerListRefreshExecutorThread implements Runnable { public void run() { updateListOfServers(); } } public void updateListOfServers() { servers = serverListImpl.getUpdatedListOfServers(); updateAllServerList(servers); }其實是通過com.netflix.loadbalancer.ServerList.getUpdatedListOfServers() 方法加載后端服務列表。ServerList這個接口正是用來獲取加載后端服務列表。
Netflix源碼解析之Ribbon:負載均衡器通過Eureka獲取動態后端服務列表 - 為程序員服務
看到ConfigurationBasedServerList是從配置中(可以是通過Archaius這樣的集中配置)加載的。 而DiscoveryEnabledNIWSServerList這個實現中包含DiscoveryEnabled猜想應該就是服務發現框架里的服務吧。看進去果然是通過eureka client 從eureka server獲取服務列表進而在ribbon中可以動態的加載。 從聲明
public class DiscoveryEnabledNIWSServerList extends AbstractServerList<DiscoveryEnabledServer>{能看到管理的服務不是一般的服務,是DiscoveryEnabledServer的服務。觀察List com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList.obtainServersViaDiscovery() 的實現可以了解整個過程。
private List<DiscoveryEnabledServer> obtainServersViaDiscovery() { List<DiscoveryEnabledServer> serverList = new ArrayList<DiscoveryEnabledServer>(); DiscoveryClient discoveryClient = DiscoveryManager.getInstance().getDiscoveryClient(); if (vipAddresses!=null){ for (String vipAddress : vipAddresses.split(“,”)) { // if targetRegion is null, it will be interpreted as the same region of client List<InstanceInfo> listOfinstanceInfo = discoveryClient.getInstancesByVipAddress(vipAddress, isSecure, targetRegion); for (InstanceInfo ii : listOfinstanceInfo) { if (ii.getStatus().equals(InstanceStatus.UP)) { DiscoveryEnabledServer des = new DiscoveryEnabledServer(ii, isSecure, shouldUseIpAddr); des.setZone(DiscoveryClient.getZone(ii)); serverList.add(des); } } return serverList; }可以看到就是通過一個com.netflix.discovery.EurekaClient作為一個句柄來獲取eureka中注冊的服務列表。獲取活的服務,并根據instanceInfo 構造成ribbon需要的DiscoveryEnabledServer并加到服務列表中。
常見問題
項目pom依賴關系
左側2.0.x版本cp項目,右側ocp1.5.9版本
總結
以上是生活随笔為你收集整理的eureka-server详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自助餐比喻秒懂微服务
- 下一篇: springcloud api-gat