淘宝(taobao)HSF框架

一、背景

      随着网站访问量增加,仅仅靠增加机器已不能满足系统的要求,于是需要对应用系统进行垂直拆分和水平拆分。在拆分之后,各个被拆分的模块如何通信?如何保证 性能?如何保证各个应用都以同样的方式交互?这就需要一种负责各个拆分的模块间通信的高性能服务框架(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;@Overrideprotected 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.

转载于:https://www.cnblogs.com/longshiyVip/p/5199506.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/404283.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 下实现负载均衡群集(NAT方式)

高可用性群集&#xff1a;以提高应用系统的可靠性&#xff0c;尽可能地减少中断时间为目标&#xff0c;确保服务的连续性&#xff0c;达到高可用&#xff08;HA&#xff09;的容错效果。HA的工作方式包括双工、主从两种模式------双工即所有节点同时在线&#xff0c;主从则只有…

[Redux/Mobx] Redux的中间件是什么?你有用过哪些Redux的中间件?

[Redux/Mobx] Redux的中间件是什么&#xff1f;你有用过哪些Redux的中间件&#xff1f; view在redux中会派发一个action&#xff0c;action通过store的dispatch方法派发给store&#xff0c;store接收到action连同之前老的state一起传给reducer&#xff0c;reducer返回新的数据…

php中json_decode()和json_encode()的使用方法

php中json_decode()和json_encode()的使用方法 json_decode对JSON格式的字符串进行编码而json_encode对变量进行 JSON 编码&#xff0c;需要的朋友可以参考下1.json_decode() json_decode (PHP 5 > 5.2.0, PECL json > 1.2.0) json_decode — 对 JSON 格式的字符串进行编…

获取我的文档“路径

From: http://blog.csdn.net/chinabinlang/article/details/8637362 方法一&#xff1a;来自网络; CString getMyDoc() // 获取“我的文档”路径 {TCHAR m_lpszDefaultDir[MAX_PATH] {0};TCHAR szDocument[MAX_PATH] {0};memset(m_lpszDefaultDir, 0, _MAX_PATH);LPITEMIDLI…

让您变的更智慧 秘笈145条(上)

钱多钱少&#xff0c;常有就好&#xff01;人老人少&#xff0c;健康就好&#xff01;家贫家富&#xff0c;和睦就好。生活其实很简单&#xff0c;过了今天就是明天&#xff0c;重要的每个今天和明天都要智慧快乐得活着。 1. 精神失常的疯子不可怕&#xff0c;可怕的是精神正常…

[Redux/Mobx] 说说redux的优缺点分别是什么?

[Redux/Mobx] 说说redux的优缺点分别是什么&#xff1f; 优点 Redux轻量&#xff0c;生态丰富&#xff0c;可以结合流行的redux-thunk、redux-saga等进行使用Redux的写法比较固定&#xff0c;团队应用中风格比较稳定&#xff0c;提高协作中的可维护性因为Redux中的reducer更新…

Bootstrap(七):CSS--图片

1.基本样式 主要四个样式类&#xff1a; 设置布局 .img-responsive : 可以让图片支持响应式布局&#xff0c;从而让图片在其父元素中更好的缩放&#xff1b; 设置形状 .img-rounded &#xff1a; 设置图片为圆角&#xff1b; 设置形状 .img-circle &#xff1a; 设置图片为圆形…

rtsp摘要认证协议(Response计算方法)

From&#xff1a; http://m.blog.csdn.net/blog/WTBEE/9001859 1. rtsp摘要认证协议流程 RTSP协议&#xff0c;全称Real Time Streaming Protocol&#xff0c;是应用层的协议&#xff0c;它主要实现的功能是传输并控制具有实时特性的媒体流&#xff0c;如音频&#xff08;Audio…

[Redux/Mobx] Redux和vuex有什么区别?

[Redux/Mobx] Redux和vuex有什么区别&#xff1f; 1&#xff1a;vuex的异步数据不需要使用到中件间&#xff0c;redux需要 2&#xff1a;vuex可以直接commit&#xff0c;action不是必须的&#xff0c;redux是必须的 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知…

android 带图片的文本框

基本原理 自定义一个IconTextView类继承自TextView&#xff0c;添加iconsrc属性&#xff0c;表示图片。 重新onDraw方法&#xff0c;将图片绘制到textVIew前面,然后将textView右移。 废话不多说了&#xff0c;直接代码就明白。 package com.zb;import android.content.Context;…

【WiFi密码破解详细图文教程】ZOL仅此一份 详细介绍从CDlinux U盘启动到设置扫描破解

From: http://softbbs.zol.com.cn/1/32_7991.html 每天都能看到有不少网友在回复论坛之前发布的一篇破解WiFi密码的帖子&#xff0c;并伴随各种疑问。今天流云就为大家准备一篇实战型的文章吧&#xff0c;详细图文从思维CDlinux U盘启动到中文设置&#xff0c;如何进行路由SSID…

整理Linux查看系统日志的一些经常使用命令

整理Linux查看系统日志的一些经常使用命令 last-a 把从何处登入系统的主机名称或ip地址&#xff0c;显示在最后一行。-d 指定记录文件。指定记录文件。将IP地址转换成主机名称。-f <记录文件>  指定记录文件。-n <显示列数>或-<显示列数>  设置列出名单的显…

[Redux/Mobx] 在Redux中怎么发起网络请求?

[Redux/Mobx] 在Redux中怎么发起网络请求&#xff1f; 如果单纯的使用Redux&#xff0c;因为redux的actionCreator返回一个plain object&#xff0c;所以不能在actionCreator中发起网络请求&#xff1b;reducer是一个纯函数&#xff0c;不能有副作用&#xff0c;所以也不能有异…

判断整数序列是不是二元查找树的后序遍历结果

题目&#xff1a;输入一个整数数组&#xff0c;判断该数组是不是某二元查找树的后序遍历的结果。 如果是返回true&#xff0c;否则返回false。 例如输入5、7、6、9、11、10、8&#xff0c;由于这一整数序列是如下树的后序遍历结果&#xff1a; 8 / \ 6 10 / \ / \ 5 7 9…

iOS 从相机或相册获取图片并裁剪

/load user image - (void)UesrImageClicked { UIActionSheet *sheet; // 判断是否支持相机 if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { sheet [[UIActionSheet alloc] initWithTitle:"选择图像" delega…

【EWSA无线路由密码破解工具 中文特别版下载】含教程及字典(弱口令生日特殊符号等)

From: http://softbbs.zol.com.cn/1/32_8011.html Elcomsoft Wireless Security Auditor简称EWSA,是一款极为强悍的路由密码破解工具&#xff0c;支持CPU、GPU调用破解&#xff0c;速度比但CPU破解厉害很多&#xff0c;加上此次分享的EWSA字典下载&#xff0c;可以帮助大家更好…

[Redux/Mobx] 什么是单一数据源?

[Redux/Mobx] 什么是单一数据源&#xff1f; Redux的store.getState只能得到一个数据源&#xff0c;通常这是一个对象&#xff0c;通常这也是React App中的唯一Redux数据源&#xff0c;这个state对象中的属性值通过combineReducer整合了子Reducer返回的state的值 个人简介 …

VMware vSphere简介

vSphere是VMware推出的基于云的新一代数据中心虚拟化套件&#xff0c;提供了虚拟化基础架构、高可用性、集中管理、监控等一整套解决方案 现VMware vSphere 版本为5.0&#xff0c;组件如下&#xff1a; ESXi&#xff1a;物理服务器的虚拟化层&#xff0c;它将处理器、内存、存储…

RESTful API 设计指南 (转)

RESTful API 设计指南 2016-02-23 ImportNew(点击上方公号&#xff0c;可快速关注) 作者&#xff1a;阮一峰 链接&#xff1a;http://www.ruanyifeng.com/blog/2014/05/restful_api.html 网络应用程序&#xff0c;分为前端和后端两个部分。当前的发展趋势&#xff0c;就是前端设…

find:查找文件或目录

From: http://yhj1065.blog.163.com/blog/static/198002172007111810502948/ 功能说明&#xff1a; find指令可以在系统中查找你想要的任何文件或目录&#xff0c;你可以通过不同的参数来查找你想要的。该指令也是系统管理员最常用、最强大、最方便的查找文件和目录的指令。 基…