進入阿里必備知識-第二步-HSF學習

[轉]http://iwinit.iteye.com/blog/1745132 

一.  Hsf總體架構

 

某服務框架簡單分析

 

 

這個圖很經典,想必大家都瞭解,Consumer,Provider,中間通過ConfigServer聯接。那麼其內部是如何實現的呢?請看下文。

二.  容器啓動,jboss爲例

HSF使用基於equinox(OSGi框架的eclipse實現,http://www.eclipse.org/equinox/)的OSGi,啓動流程

 

某服務框架簡單分析

 

 

1.     /opt/xxxx/jboss/server/default/conf/xmdesc/org.jboss.deployment.MainDeployer-xmbean.xml指定sar優先加載:

 

Java代碼  收藏代碼
  1. 050:.deployer,050:-deployer.xml,100:.aop,100:-aop.xml,150:.sar,150:-service.xml,200:.beans,250:.rar,300:-ds.xml,350:.har,400:.jar,400:.ejb3,400:.par,500:.war,…  

 

 

2.      taobao-hsf.sar/META-INF/jboss-service.xml 指定初始化類:

 

Java代碼  收藏代碼
  1. <server>  
  2.   <mbeancode="com.xxxx.hsf.thirdcontainer.jboss.HSFContainerDelegator"name="hsf:service=containerdelegator">  
  3.   </mbean>  
  4. </server>  

 

 

3.     設置Jboss的class loader給HSF,以便HSF訪問Jboss的類:

 

Java代碼  收藏代碼
  1. HSFContainer.setThirdContainerClassLoader(jbossClassloader);  

 

 

4.     啓動hsf容器 

 

Java代碼  收藏代碼
  1. HSFContainer.start(null);  

 

 

4.1  尋找HSF的plugins

4.2 配置Equinox

 

Java代碼  收藏代碼
  1. FrameworkProperties.setProperty("osgi.syspath", searchPath);  
  2. …..  

 

 

4.3  啓動 Equinox

 

Java代碼  收藏代碼
  1. EclipseStarter.run(new String[] { "-configuration","hsf.configuration" }, null);  

 

 

這裏HSF使用了OSGi的Declarative Service(http://www.ibm.com/developerworks/cn/opensource/os-ecl-osgids/index.html)方式來啓動,典型配置如下:

OSGI下的配置文件

 

Java代碼  收藏代碼
  1. <?xml version="1.0"encoding="UTF-8"?>  
  2. <component name="ConfigurationComponent">  
  3.     <service>  
  4.         <provide  
  5.            interface="com.xxxx.hsf.configuration.service.ConfigurationService"/>  
  6.     </service>  
  7.     <implementation  
  8.         class="com.xxxx.hsf.configuration.component.ConfigurationComponent"/>  
  9. </component>:  

 

 

有點類似spring的DI,完成整個容器的啓動,這裏hsf用到的service都會初始化完成,但是基本不幹啥事。

4.4  OSGi容器初始化後,拿到OSGi上下文,讓jboss容器和OSGi容器可以相互訪問

 

Java代碼  收藏代碼
  1. context = EclipseStarter.getSystemBundleContext();  

 

 

5.     將hsf暴露的類註冊到jboss的classloader中,方便後續app中使用,典型的比如HSFSpringProviderBean和HSFSpringConsumerBean

 

Java代碼  收藏代碼
  1. Map<String,Class<?>> exportedClasses = HSFContainer.getExportedClasses();  
  2.        for (String className : exportedClasses.keySet()) {  
  3.            jbossRepo.cacheLoadedClass(className, exportedClasses.get(className),jbossClassloader);  
  4.         }   

 

 

三.  Provider啓動

當APP啓動時,會用spring加載hsf的配置文件,典型provider如下:

 

Java代碼  收藏代碼
  1. <beanclass="com.taobao.hsf.app.spring.util.HSFSpringProviderBean" init-method="init">  
  2.     <propertyname="serviceInterface">  
  3.        <value>com.xxxx.ump.core.service.PromotionReadService</value>  
  4.     </property>  
  5.     <propertyname="serviceName">  
  6.       <value>PromotionReadService</value>  
  7.     </property>  
  8.     <propertyname="target">  
  9.       <ref bean="promotionReadService"/>  
  10.     </property>  

 

 

……

  因爲容器初始化時已經將HSF的類註冊到了jboss的classloader中,所以在spring中可以找到HSFSpringProviderBean類定義,開始provider的初始化。

  Provider角度看,類圖如下:

 

某服務框架簡單分析

 

ProcessService是核心控制流程類,掌管發佈和消費的入口。從provider端來看,基本流程如下:

1.根據服務類型,註冊服務提供者,保證服務在本機的唯一性,關聯業務層和通訊層。在這裏會做應用服務器的初始化,服務線程池分配(如果配置)。最終的TBRemotingRPCProtocolComponent.registerProvider代碼如下:

 

Java代碼  收藏代碼
  1. // 僅啓動一次HSF SERVER  
  2.         …….  
  3. providerServer.startHSFServer();  
  4. ……  
  5.        // 註冊對象到HSFServer上  
  6.        providerServer.addMetadata(metadata.getUniqueName(), metadata);  
  7.                  providerServer.addWorker(metadata.getUniqueName(),metadata.getTarget());  

 

 

應用服務器初始化後,本地hsf端口12200打開,可以接受請求。在這一步,我們可以通過配置修改hsf的運行期參數,比如端口,業務線程數等。

2.通過Publisher將服務註冊到configServer上

四.  Consumer啓動

     當消費者啓動時,我們會這樣配置:

 

Java代碼  收藏代碼
  1. <beanid="shopReadServiceImpl"class="com.xxxx.hsf.app.spring.util.HSFSpringConsumerBean" init-method="init">  
  2.         <property name="interfaceName">  
  3.            <value>com.xxxx.shopservice.core.client.ShopReadService</value>  
  4.         </property>  

 

 

  同樣通過jboss的classloader我們可以找到HSFSpringConsumerBean這個類定義,開始consumer的初始化。

  從consumer角度看,類圖如下:

 

某服務框架簡單分析

 

同樣通過ProcessService的consume方法生成一個調用的代理類。流程如下:

1. 使用jdk動態代理,生成調用遠程HSF服務的代理

 

Java代碼  收藏代碼
  1. InvocationHandler handler = newHSFServiceProxy(metadata);  
  2.        Object proxyObj = Proxy.newProxyInstance(getClass().getClassLoader(), newClass[] { interfaceClass }, handler);  

 

生成的代理類叫HSFServiceProxy,其invoke方法使用TBRemotingRPCProtocalComponent組件調用通訊層接口,發送請求。

2.     通過metadataService訂閱服務信息,包括:

a.     通過diamond訂閱服務路由規則和流量規則,路由規則即調用哪些機器,hsf可以限制consumer的調用機器範圍,流量規則即流控策略,hsf可以通過推送規則限流。

b.     通過configServer的client訂閱服務地址信息,這裏可以拿到所有提供該service的機器地址,consumer根據之前獲得的路由規則和訪問策略(默認隨機)來決定請求哪臺機器。

 

 

五.             小結

本文簡單分析了hsf容器的啓動,後續將分析具體的consume和provide過程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章