天天看點

Eureka詳解系列(二)--如何使用Eureka(原生API,無Spring)

Eureka詳解系列(二)--如何使用Eureka(原生API,無Spring)

通過上一篇部落格,我們知道了 Eureka 是什麼以及為什麼要使用它,今天,我們開始研究如何使用 Eureka。

在此之前,先說明一點。網上幾乎所有關于 Eureka 的文章都是基于 Spring 的,但**本文的例子不會有任何 Spring 的代碼,我盡量使用 Eureka 原生的 API**,後面的源碼分析也是如此。因為 Spring 把 Eureka 藏得越好,我們研究起來就會越困難,畢竟我寫這個系列不是隻為了學會怎麼使用 Eureka,我們還要分析它的源碼。當然,實際項目中就沒必要這麼搞了。

簡介

通過上一篇部落格 Eureka詳解系列(一)--先談談負載均衡器 ,我們知道了 Eureka 是什麼以及為什麼要使用它,今天,我們開始研究如何使用 Eureka。

在此之前,先說明一點。網上幾乎所有關于 Eureka 的文章都是基于 Spring 的,但本文的例子不會有任何 Spring 的代碼,我盡量使用 Eureka 原生的 API,後面的源碼分析也是如此。因為 Spring 把 Eureka 藏得越好,我們研究起來就會越困難,畢竟我寫這個系列不是隻為了學會怎麼使用 Eureka,我們還要分析它的源碼。當然,實際項目中就沒必要這麼搞了。

另外,這隻是一個簡單的例子,隻配置了幾個必備的參數,下篇部落格會展開分析。

項目環境

os:win 10

jdk:1.8.0_231

eureka:1.10.11

tomcat:9.0.21

maven:3.6.3

使用例子

如何設計例子

通過 Eureka 的結構圖可以知道,我們需要分别搭建 Eureka Server、Eureka Client for application service、Eureka Client for application client 三個子產品。

Eureka詳解系列(二)--如何使用Eureka(原生API,無Spring)

我參考了官網的例子,并做了一點小改動,代碼和配置就不一一列出了,具體源碼見文末連結。

Eureka詳解系列(二)--如何使用Eureka(原生API,無Spring)
  1. eureka-server:作為 Eureka Server,它是一個獨立的 Web 服務,能夠處理 Eureka Client 的 rest 請求:注冊、續約、登出服務,以及擷取服務的資訊。它需要打包成 war 包運作在 tomcat 上。
  2. eureka-service:作為 application service,它需要向 Eureka Server 注冊自己,并監聽 Eureka Client 的消費請求。
  3. eureka-client:作為 application client,它需要從 Eureka Server 擷取 application service 的位址,然後通路 application service。

如何運作例子

我們需要按照順序運作它們。

eureka-server

eureka-server 使用 jersey 作 Web 架構(jersey 和 struts2、springMVC 作用差不多,沒接觸過也不礙事),項目最終要打包成 war 包運作在 tomcat 上。項目的運作方法如下:

  1. 建構項目。使用

    mvn clean package

    将項目打包成 eureka.war。
  2. 将 eureka.war 拷貝到 ${CATALINA_HOME}/webapps 目錄下。
  3. 啟動 tomcat。通過 http://127.0.0.1:8080/eureka/ 可以通路成功,這個時候,我們就可以使用 Eureka Client 往上面注冊服務了。另外,我們可以看到,Eureka Server 将自己注冊了上去(30s 内)。
Eureka詳解系列(二)--如何使用Eureka(原生API,無Spring)

補充一點,官方提供了基于 java 實作的 Eureka Client 來與 Eureka Server 進行互動,其實,我們也可以直接使用 rest 請求,例如,通過 http://127.0.0.1:8080/eureka/v2/apps 可以擷取所有的服務清單。當我們的用戶端不支援 java 時,這些接口将非常有用,具體接口可以參考官網。在項目中,我們查找包含

javax.ws.rs.Path

注解的類,也可以找到這些接口。

eureka-service

eureka-service 的實作比較簡單,它先把自己注冊到 Eureka Server,然後一直監聽 application client 的消費,監聽到後,隻進行簡單的互動後就直接關閉用戶端。代碼簡化如下:

// 建立ApplicationInfoManager對象(用來注冊、登出目前執行個體)
ApplicationInfoManager applicationInfoManager = new ApplicationInfoManager(
    new MyDataCenterInstanceConfig(), new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get());
// 建立EurekaClient對象(用來擷取其他服務以及提供内部入口用來注冊、續約、和登出目前執行個體)
EurekaClient eurekaClient = new DiscoveryClient(applicationInfoManager, new DefaultEurekaClientConfig());
// 設定目前執行個體狀态為STARTING
applicationInfoManager.setInstanceStatus(InstanceInfo.InstanceStatus.STARTING);
// 設定目前執行個體狀态為UP
applicationInfoManager.setInstanceStatus(InstanceInfo.InstanceStatus.UP);
// 和application client互動
// ······
// 關閉用戶端,同時也會登出目前執行個體
eurekaClient.shutdown();
           

操作方法很簡單,隻要運作

ExampleEurekaService.main

方法就行(加上啟動參數:

-Deureka.client.props=sample-eureka-service

)。當控制台出現"Service started and ready to process requests.."時,說明目前執行個體已經注冊到 Eureka Server,并且準備被消費。

Eureka詳解系列(二)--如何使用Eureka(原生API,無Spring)

eureka-client

eureka-client 項目的具體邏輯為:從 Eureka Server 上擷取到系統資料庫,然後和 application service 互動,得到響應後直接關閉用戶端。代碼簡化如下:

// 建立ApplicationInfoManager對象(用來注冊、登出目前執行個體)
ApplicationInfoManager applicationInfoManager = new ApplicationInfoManager(
    new MyDataCenterInstanceConfig(), new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get());
// 建立EurekaClient對象(用來擷取其他服務以及提供内部入口用來注冊、續約、和登出目前執行個體)
EurekaClient eurekaClient = new DiscoveryClient(applicationInfoManager, new DefaultEurekaClientConfig());
// 擷取指定服務的執行個體對象
InstanceInfo nextServerInfo = eurekaClient.getNextServerFromEureka(vipAddress, false);
// 和application service互動
// ······
// 關閉用戶端
eurekaClient.shutdown();
           

直接運作

ExampleEurekaClient.main

就行(加上啟動參數

-Deureka.client.props=sample-eureka-client

)。我們可以從控制台看到整個過程。

Eureka詳解系列(二)--如何使用Eureka(原生API,無Spring)

以上,通過一個簡單的例子,我們實作了将服務注冊到 Eureka Server 以及正常地消費它。這是非常“入門級”的例子,下篇部落格我們再深入研究各種配置參數的作用。

最後,感謝閱讀。

參考資料

https://github.com/Netflix/eureka/wiki/Eureka-at-a-glance

相關源碼請移步:https://github.com/ZhangZiSheng001/eureka-demo
本文為原創文章,轉載請附上原文出處連結:https://www.cnblogs.com/ZhangZiSheng001/p/14337985.html

分層,抽象,高内聚,低耦合