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过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值