淘寶(taobao)HSF框架


http://www.cnblogs.com/mengheyun/archive/2010/12/16/1963077.html

一、背景

      隨着網站訪問量增加,僅僅靠增加機器已不能滿足系統的要求,於是需要對應用系統進行垂直拆分和水平拆分。在拆分之后,各個被拆分的模塊如何通信?如何保證性能?如何保證各個應用都以同樣的方式交互?這就需要一種負責各個拆分的模塊間通信的高性能服務框架(HSF)。

二、HSF做的事情

 

1. 標准Service方式的RPC

    1). service定義:基於OSGI的service定義方式

    2). TCP/IP通信:

           IO方式:nio,采用mina框架

           連接方式:長連接

           服務器端有限定大小的連接池

           WebService方式

    3). 序列化:hessian序列化機制

 

2. 軟件負載體系

    采用軟件實現負載均衡,支持隨機、輪詢、權重、按應用路由等方式。軟件負載均衡沒有中間點,通過配置中心統一管理。配置中心收集服務提供者和消費者的注冊信息,以推送的方式發送到服務消費者直接使用,不經過中間點;注冊中心可以感應服務器的狀態,出現failover時,實現注冊信息重新推送。

3. 模塊化、動態化

4. 服務治理

    服務治理利用注冊中心實現服務信息管理(服務提供者、調用者信息查詢)、服務依賴關系分析、服務運行狀況感知、服務可用性保障,如:路由調整、流量分配、服務端降級、調用端降級等

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/marine2010/archive/2010/03/21/5401366.aspx

背景: WEBX -- 阿里巴巴網站所采用的WEB應用框架.

HSF接口: com.taobao.item.service.ItemQueryService

需求: 根據商品ID取得商品信息

載體: TBCMS系統

實現步驟: 1. 創建 /bundle/war/src/webroot/META-INF/autoconf/item-hsf-xml.vm

代碼:
<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
  <bean id="itemQueryService" class="com.taobao.hsf.app.spring.util.HSFSpringConsumerBean" init-method="init">
   <property name="interfaceName">
    <value>com.taobao.item.service.ItemQueryService</value>
   </property>
   <property name="version">
    <value>${item_provide_service_version}</value>
   </property>
   <!--asyncallMethods為可選配置[List],含義為調用此服務時需要采用異步調用的方法名列表,默認為空集合,即所有方法都采用同步調用-->
   <property name="asyncallMethods">
    <list>
</list>
</property>
</bean>

</beans>  

2.其中: ${item_provide_service_version} 需要在 auto-config.xml 中配置,在 <group name="arkcms-bundle-war"> ...</group>中增加:

<property name="item.provide.service.version" defaultValue="1.0.0.daily" desc="itemClient調用版本"/>

同時在 <script>...</script>中增加:

<generate template="item-hsf.xml.vm" destfile="WEB-INF/biz/bean/item-hsf.xml" charset="GBK"/>

3.在 /bundle/war/src/webroot/WEB-INF/cms-biz-services.xml中增加:

        <service name="BeanFactoryService" class="com.alibaba.service.spring.DefaultBeanFactoryService">
            <property name="bean.descriptors">

                     ....................

                    <value>/cms/biz/bean/item-hsf.xml</value>
            </property>
        </service>

至此,我們已經引入了ItemQueryService的HSF服務.

4. 接下來我們就要做Servlet接口了,當然寫一個servlet直接調用hsf也是可以的,但是從結構考慮,我們還是先本地封裝一層先.

但是首先,需要對 /all/project.xml 中需要增加對ItemQueryService的支持:

    <projects name="taobao/itemcenter" version="1.9.5">
     <project id="taobao/itemcenter/itemcenter-client"/>
     <project id="taobao/itemcenter/itemcenter-common"/>
    </projects>

並在/biz/project.xml和/web/project.xml中增加:

<?xml version="1.0" encoding="GB2312"?>

<project id="tbcms/web" extends="../all/project.xml">
    <build>
        <dependencies>
                  ............
        <include uri="taobao/itemcenter/itemcenter-client"/>
        <include uri="taobao/itemcenter/itemcenter-common"/>
        </dependencies>
    </build>
</project>

命令行模式下執行:antx reactor goals=eclipse來執行對依賴包的裝載.(前提是對/antx/repository.project/taobao/itemcenter/進行SVN更新)

本地封裝: 在/biz/src/java/com/ark/cms/biz/util/item/下創建ItemService.java接口:

package com.ark.cms.biz.util.item;

import com.taobao.item.domain.DbRoute;
import com.taobao.item.domain.query.ItemIdDO;
import com.taobao.item.domain.result.ItemResultDO;
import com.taobao.item.exception.IcException;
/**
 * 根據id取得商品信息
 * @author duxing
 *
 */
public interface ItemService {
 public ItemResultDO getItemById(ItemIdDO itemId,DbRoute mainDbRoute) throws IcException;
}
 

在biz/src/java/com/ark/cms/biz/util/item/impl/下 ItemServiceImpl.java進行實現:

package com.ark.cms.biz.util.item.impl;

import com.ark.cms.biz.util.item.ItemService;
import com.taobao.item.domain.DbRoute;
import com.taobao.item.domain.query.ItemIdDO;
import com.taobao.item.domain.query.QueryItemOptionsDO;
import com.taobao.item.domain.result.ItemResultDO;
import com.taobao.item.exception.IcException;
import com.taobao.item.service.ItemQueryService;

/**
 * 根據id取得商品信息 實現
 * @author duxing
 *
 */

public class ItemServiceImpl implements ItemService {

 private ItemQueryService itemQueryService;

 public void setItemQueryService(ItemQueryService itemQueryService) {
  this.itemQueryService = itemQueryService;
 }

 @SuppressWarnings("deprecation")
 public ItemResultDO getItemById(ItemIdDO itemId, DbRoute mainDbRoute) throws IcException {
  QueryItemOptionsDO options = null;
  return itemQueryService.queryItemById(itemId, options, mainDbRoute);
 }

}
然后將此接口移交給spring,在 /bundle/war/src/webroot/META-INF/autoconf/item-hsf-xml.vm中增加 

<bean id="itemService" class="com.ark.cms.biz.util.item.impl.ItemServiceImpl"></bean>

至此,我們已經在spring中產生一個itemService

5.接下來創建servlet

在/web/src/java/com/ark/cms/web/下創建ItemServiceServlet.java

因為servlet中不能直接用set形式讓spring來set itemService進來,所以只能采用一下方法獲取itemService:

  BeanFactoryService beanFactory = (BeanFactoryService) BizServiceManager.getInstance().getService(BeanFactoryService.SERVICE_NAME);
  ItemService itemService = (ItemService) beanFactory.getBean("itemService");

完整代碼如下:

package com.ark.cms.web;

import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.service.spring.BeanFactoryService;
import com.ark.cms.biz.core.BizServiceManager;
import com.ark.cms.biz.util.item.ItemService;
import com.taobao.item.domain.DbRoute;
import com.taobao.item.domain.ItemDO;
import com.taobao.item.domain.query.ItemIdDO;
import com.taobao.item.domain.result.ItemResultDO;
import com.taobao.item.exception.IcException;


/**
 * 根據id取得商品大圖的接口
 * @author duxing
 *
 */
public class ItemServiceServlet extends HttpServlet {

 private static final long serialVersionUID = -3348559907279438489L;

 @Override
 protected void doPost(HttpServletRequest request,
   HttpServletResponse response) throws ServletException, IOException {
// http://item.taobao.com/auction/item_detail-db1-67af640ba3f16a2006cd63f1f...
// long itemId=4399800173l;

  String item_id = request.getParameter("item_id");

  String xid = request.getParameter("xid");
  DbRoute mainDbRoute=DbRoute.getDbRouteByXid(xid);

  ItemIdDO itemIDDO=new ItemIdDO();
  if(item_id!=null){
   itemIDDO.setItemIdStr(item_id);
  }
  if(request.getParameter("item_num_id")!=null){
   Long item_num_id = Long.valueOf(request.getParameter("item_num_id"));
   itemIDDO.setItemId(item_num_id);
  }
  if(request.getParameter("id")!=null){
   Long id = Long.valueOf(request.getParameter("id"));
   itemIDDO.setItemId(id);
  }
// 兩種id的傳入方式
// itemIDDO.setItemId(itemId);
// itemIDDO.setItemIdStr("67af640ba3f16a2006cd63f1f5dddc271");

  ItemResultDO itemResultDO;
  BeanFactoryService beanFactory = (BeanFactoryService) BizServiceManager.getInstance().getService(BeanFactoryService.SERVICE_NAME);
  ItemService itemService = (ItemService) beanFactory.getBean("itemService");
  try {
   itemResultDO=itemService.getItemById(itemIDDO, mainDbRoute);
  } catch (IcException e) {
   e.printStackTrace();
   itemResultDO=new ItemResultDO();
  }

  ItemDO itemDO=itemResultDO.getItem();
  byte[] result="".getBytes();
  if(itemDO!=null){
   result=itemDO.getPictUrl().getBytes();
  }
  response.setContentType("text/xml;charset=gb2312");
  response.setContentLength(result.length);
  OutputStream out = response.getOutputStream();
  out.write(result);
  out.flush();

 }
}
6.servlet寫好了之后我們就要配置進WEBX了:

在 /bundle/war/src/webroot/META-INF/autoconf/web.xml.vm中增加:

      <servlet-mapping>

        <servlet-name>ItemServiceServlet</servlet-name>
        <url-pattern>/item/query</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>ItemServiceServlet</servlet-name>
        <servlet-class>com.ark.cms.web.ItemServiceServlet</servlet-class>
    </servlet>

7.至此,開發完成 

命令行模式下執行:antx reactor goals=clean,default來對項目重新編譯打包.重啟本地服務器進行測試.

對/item/query接口進行post的時候觸發此servlet.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM