本文介紹如何使用EDAS-SDK快速開發HSF應用,完成服務注冊與發現。

前提條件

下載Demo工程

您可以按照本文步驟一步步搭建工程,也可以直接下載本文對應的示例工程,或者使用Git下載git clone https://github.com/aliyun/alibabacloud-microservice-demo.git

該項目包含了眾多示例工程,本文對應的示例工程位于alibabacloud-microservice-demo/microservice-doc-demo/hsf-ali-tomcat,包含itemcenter-apiitemcenterdetail三個Maven工程文件夾。

  • itemcenter-api:提供接口定義。
  • itemcenter:服務提供者。
  • detail:消費者服務。
說明 請使用JDK 1.7及以上版本。

定義服務接口

HSF服務基于接口實現,當接口定義完成后,生產者將使用該接口實現具體的服務,消費者也基于此接口訂閱服務。

在Demo的itemcenter-api工程中,定義了一個服務接口com.alibaba.edas.carshop.itemcenter.ItemService
public interface ItemService {
    public Item getItemById(long id);
    public Item getItemByName(String name);
}

該服務接口將提供兩個方法:getItemByIdgetItemByName

開發服務提供者

服務提供者將實現服務接口以提供具體服務。同時,如果使用了Spring框架,還需要在XML文件中配置服務屬性。
說明 Demo工程中的itemcenter文件夾為服務提供者的示例代碼。
  1. 實現服務接口。
    請參考ItemServiceImpl.java文件中的示例代碼構建服務接口。
    public class ItemServiceImpl implements ItemService {
    
        @Override
        public Item getItemById( long id ) {
            Item car = new Item();
            car.setItemId( 1l );
            car.setItemName( "Mercedes Benz" );
            return car;
        }
        @Override
        public Item getItemByName( String name ) {
            Item car = new Item();
            car.setItemId( 1l );
            car.setItemName( "Mercedes Benz" );
            return car;
        }
    }
  2. 服務提供者配置。

    實現服務接口中實現了com.alibaba.edas.carshop.itemcenter.ItemService,并在兩個方法中返回了Item對象。代碼開發完成之后,除了在web.xml中進行必要的常規配置,您還需要增加相應的Maven依賴,同時在Spring配置文件使用<hsf />標簽注冊并發布該服務。

    1. pom.xml中添加Maven依賴。
        <dependencies>
            <!-- 添加servlet的依賴 -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
                <scope>provided</scope>
            </dependency>
            <!-- 添加服務接口的依賴 -->      
            <dependency>
                <groupId>com.alibaba.edas.carshop</groupId>
                <artifactId>itemcenter-api</artifactId>
                <version>1.0.0-SNAPSHOT</version>
            </dependency>
            <!-- 添加Spring的依賴 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>2.5.6(及其以上版本)</version>
            </dependency>
            <!-- 添加edas-sdk的依賴 -->
            <dependency>
                  <groupId>com.alibaba.edas</groupId>
                   <artifactId>edas-sdk</artifactId>
                  <version>1.8.1</version>
            </dependency>
        </dependencies>
    2. hsf-provider-beans.xml文件中增加Spring關于HSF服務的配置。
        <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:hsf="http://www.taobao.com/hsf"
            xmlns="http://www.springframework.org/schema/beans"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.taobao.com/hsf
            http://www.taobao.com/hsf/hsf.xsd" default-autowire="byName">
            <!-- 定義該服務的具體實現 -->
            <bean id="itemService" class="com.alibaba.edas.carshop.itemcenter.ItemServiceImpl" />
            <!-- 用hsf:provider標簽表明提供一個服務生產者 -->
            <hsf:provider id=“itemServiceProvider"
                <!-- 用interface屬性說明該服務為此類的一個實現 -->
                interface="com.alibaba.edas.carshop.itemcenter.ItemService"
                <!-- 此服務具體實現的Spring對象 -->
                ref="itemService"
                <!-- 發布該服務的版本號,可任意指定,默認為1.0.0 -->
                version="1.0.0"
            </hsf:provider>
        </beans>

      上面的示例為基本配置,您也可以根據您的實際需求,參考下面的生產者服務屬性列表,增加其它配置。

      屬性 描述
      interface 必須配置,類型為 [String],為服務對外提供的接口。
      version 可選配置,類型為 [String],含義為服務的版本,默認為1.0.0。
      clientTimeout 該配置對接口中的所有方法生效,但是如果客戶端通過methodSpecials屬性對某方法配置了超時時間,則該方法的超時時間以客戶端配置為準。其他方法不受影響,還是以服務端配置為準。
      serializeType 可選配置,類型為[String(hessian|java)],含義為序列化類型,默認為hessian。
      corePoolSize 單獨針對這個服務設置核心線程池,從公用線程池中劃分出來。
      maxPoolSize 單獨針對這個服務設置線程池,從公用線程池中劃分出來。
      enableTXC 開啟分布式事務GTS。
      ref 必須配置,類型為 [ref],為需要發布為HSF服務的Spring Bean ID。
      methodSpecials 可選配置,用于為方法單獨配置超時時間(單位ms),這樣接口中的方法可以采用不同的超時時間。該配置優先級高于上面的clientTimeout的超時配置,低于客戶端的methodSpecials配置。

      服務創建及發布存在以下限制:

      名稱 示例 限制大小 是否可調整
      {服務名}:{版本號} com.alibaba.edas.testcase.api.TestCase:1.0.0 最大192字節
      組名 HSF 最大32字節
      單個Pandora應用實例發布的服務數 N/A 最大800個 可在應用基本信息頁面單擊應用設置部分右側的設置,在下拉列表中選擇JVM,在彈出的應用設置對話框中進入自定義 > 自定義參數-DCC.pubCountMax=1200屬性參數(該參數值可根據應用實際發布的服務數調整)。
      服務提供者屬性配置示例:
      <bean id="impl" class="com.taobao.edas.service.impl.SimpleServiceImpl" />
      <hsf:provider
              id="simpleService"
              interface="com.taobao.edas.service.SimpleService"
              ref="impl"
              version="1.0.1"
              clientTimeout="3000"
              enableTXC="true"
              serializeType="hessian">
              <hsf:methodSpecials>
                  <hsf:methodSpecial name="sum" timeout="2000" />
              </hsf:methodSpecials>
      </hsf:provider>

開發服務消費者

消費者訂閱服務從代碼編寫的角度分為兩個部分。
  • Spring的配置文件使用標簽<hsf:consumer/>定義好一個Bean。
  • 在使用的時候從Spring的context中將Bean取出來。
說明 Demo工程中的detail文件夾為消費者服務的示例代碼。
與生產者相同,消費者的服務屬性配置分為Maven依賴配置與Spring的配置。
  1. 配置服務屬性。
    1. pom.xml文件中添加Maven依賴。
        <dependencies>
            <!-- 添加 servlet 的依賴 -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
                <scope>provided</scope>
            </dependency>
            <!-- 添加 Spring 的依賴 -->
            <dependency>
                <groupId>com.alibaba.edas.carshop</groupId>
                <artifactId>itemcenter-api</artifactId>
                <version>1.0.0-SNAPSHOT</version>
            </dependency>
            <!-- 添加服務接口的依賴 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>2.5.6(及其以上版本)</version>
            </dependency>
            <!-- 添加 edas-sdk 的依賴 -->
            <dependency>
                  <groupId>com.alibaba.edas</groupId>
                   <artifactId>edas-sdk</artifactId>
                  <version>1.8.1</version>
            </dependency>
        </dependencies>
    2. hsf-consumer-beans.xml文件中添加Spring關于HSF服務的配置。
      增加消費者的定義,HSF框架將根據該配置文件去服務中心訂閱所需的服務。
      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:hsf="http://www.taobao.com/hsf"
              xmlns="http://www.springframework.org/schema/beans"
              xsi:schemaLocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
              http://www.taobao.com/hsf
              http://www.taobao.com/hsf/hsf.xsd" default-autowire="byName">
              <!-- 消費一個服務示例 -->
              <hsf:consumer
                  <!-- Bean ID,在代碼中可根據此ID進行注入從而獲取consumer對象  -->
                  id="item"
                  <!-- 服務名,與服務提供者的相應配置對應,HSF將根據interface + version查詢并訂閱所需服務  -->
                  interface="com.alibaba.edas.carshop.itemcenter.ItemService"
                  <!-- 版本號,與服務提供者的相應配置對應,HSF將根據interface + version查詢并訂閱所需服務  -->
                  version="1.0.0">
              </hsf:consumer>
      </beans>
  2. 服務消費者配置。
    請參考StartListener.java文件中的示例進行。
    public class StartListener implements ServletContextListener{
    
        @Override
        public void contextInitialized( ServletContextEvent sce ) {
            ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext( sce.getServletContext() );
            // 根據Spring配置中的Bean ID“item” 獲取訂閱到的服務
              final ItemService itemService = ( ItemService ) ctx.getBean( "item" );
            ……
            // 調用服務ItemService的getItemById方法
               System.out.println( itemService.getItemById( 1111 ) );
            // 調用服務ItemService的getItemByName方法
               System.out.println( itemService.getItemByName( "myname is le" ) );
            ……
        }
    }

    上面的示例中為基本配置,您也可以根據您的實際需求,參考下面的服務屬性列表,增加其它配置。

    屬性 描述
    interface 必須配置,類型為 [String],為需要調用的服務的接口。
    version 可選配置,類型為 [String],為需要調用的服務的版本,默認為1.0.0。
    methodSpecials 可選配置,為方法單獨配置超時時間(單位ms)。這樣接口中的方法可以采用不同的超時時間,該配置優先級高于服務端的超時配置。
    target 主要用于單元測試環境和開發環境中,手動地指定服務提供端的地址。如果不想通過此方式,而是通過配置中心推送的目標服務地址信息來指定服務端地址,可以在消費者端指定 -Dhsf.run.mode=0。
    connectionNum 可選配置,為支持設置連接到server連接數,默認為1。在小數據傳輸,要求低延遲的情況下設置多一些,會提升TPS。
    clientTimeout 客戶端統一設置接口中所有方法的超時時間(單位ms)。超時時間設置優先級由高到低是:客戶端methodSpecials,客戶端接口級別,服務端methodSpecials,服務端接口級別 。
    asyncallMethods 可選配置,類型為 [List],設置調用此服務時需要采用異步調用的方法名列表以及異步調用的方式。默認為空集合,即所有方法都采用同步調用。
    maxWaitTimeForCsAddress 配置該參數,目的是當服務進行訂閱時,會在該參數指定時間內,阻塞線程等待地址推送,避免調用該服務時因為地址為空而出現地址找不到的情況。若超過該參數指定時間,地址還是沒有推送,線程將不再等待,繼續初始化后續內容。注意,在應用初始化時,需要調用某個服務時才使用該參數。如果不需要調用其它服務,請勿使用該參數,會延長啟動時間。
    消費者服務屬性配置示例
    <hsf:consumer
          id="service"
          interface="com.taobao.edas.service.SimpleService"
          version="1.1.0"
          clientTimeout="3000"
          target="10.1.6.57:12200?_TIMEOUT=1000"
          maxWaitTimeForCsAddress="5000">
          <hsf:methodSpecials>
               <hsf:methodSpecial name="sum" timeout="2000" ></hsf:methodSpecial>
          </hsf:methodSpecials>
    </hsf:consumer>

本地運行服務

完成代碼、接口開發和服務配置后,在Eclipse或IDEA中,可直接以Ali-Tomcat運行該服務(具體請參見安裝及開發環境配置)。

在開發環境配置時,有一些額外JVM啟動參數來改變HSF的行為,具體如下:

屬性 描述
-Dhsf.server.port 指定HSF的啟動服務綁定端口,默認值為12200。
-Dhsf.serializer 指定HSF的序列化方式,默認值為hessian。
-Dhsf.server.max.poolsize 指定HSF的服務端最大線程池大小,默認值為720。
-Dhsf.server.min.poolsize 指定HSF的服務端最小線程池大小。默認值為50。
-DHSF_SERVER_PUB_HOST 指定對外暴露的IP,如果不配置,使用 -Dhsf.server.ip的值。
-DHSF_SERVER_PUB_PORT 指定對外暴露的端口,該端口必須在本機被監聽,并對外開放了訪問授權,默認使用 -Dhsf.server.port的配置,如果 -Dhsf.server.port沒有配置,默認使用12200。

本地查詢HSF服務

在開發調試的過程中,如果您的服務是通過輕量級注冊配置中心進行服務注冊與發現,就可以通過EDAS控制臺查詢某個應用提供或調用的服務。

假設您在一臺IP為192.168.XX.XX的機器上啟動了EDAS配置中心。
  • 進入http://192.168.xx.xx:8080/
  • 在左側菜單欄,單擊服務列表,輸入服務名、服務組名或者IP地址進行搜索,查看對應的服務提供者以及服務調用者。
    說明 配置中心啟動之后默認選擇第一塊網卡地址做為服務發現的地址,如果開發者所在的機器有多塊網卡的情況,可設置啟動腳本中的SERVER_IP變量進行顯式的地址綁定。

常見查詢案例

  • 提供者列表頁
    • 在搜索框中輸入IP地址,單擊搜索,即可查詢該IP地址的物理機所提供的服務。
    • 在搜索框中輸入服務名或服務分組,即可查詢提供該服務的IP地址。
  • 調用者列表頁
    • 在搜索框中輸入IP地址,單擊搜索,即可查詢該IP地址的物理機所調用的服務。
    • 在搜索框中輸入服務名或服務分組,即可查詢調用該服務的IP地址。

部署到EDAS

本地使用輕量級配置及注冊中心的應用可以直接部署到EDAS中,無需做任何修改,注冊中心會被自動替換為EDAS上的注冊中心。

正常打包出可供EDAS-Container運行的WAR包,需要添加如下的Maven打包插件。

  1. pom.xml文件中添加以下打包插件的配置。
       <build>
           <finalName>itemcenter</finalName>
           <plugins>
               <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-compiler-plugin</artifactId>
                   <version>3.1</version>
               </plugin>
           </plugins>
       </build>
  2. 執行mvn clean package將本地的程序打成WAR包。

應用運行時環境需要選擇EDAS-Container

具體部署操作詳情請參見在ECS集群中部署應用在K8s集群中使用鏡像部署Java微服務應用