、背景
随着网站访问量增加,仅仅靠增加机器已不能满足系统的要求,于是需要对应用系统进行垂直拆分和水平拆分。在拆分之后,各个被拆分的模块如何通信?如何保证 性能?如何保证各个应用都以同样的方式交互?这就需要一种负责各个拆分的模块间通信的高性能服务框架(HSF)。
二、HSF做的事情
1. 标准Service方式的RPC
1). service定义:基于OSGI的service定义方式
2). TCP/IP通信:
IO方式:nio,采用mina框架
连接方式:长连接
服务器端有限定大小的连接池
WebService方式
3). 序列化:hessian序列化机制
2. 软件负载体系
采用软件实现负载均衡,支持随机、轮询、权重、按应用路由等方式。软件负载均衡没有中间点,通过配置中心统一管理。配置中心收集服务提供者和消费者的注册 信息,以推送的方式发送到服务消费者直接使用,不经过中间点;注册中心可以感应服务器的状态,出现failover时,实现注册信息重新推送。
3. 模块化、动态化
4. 服务治理
服务治理利用注册中心实现服务信息管理(服务提供者、调用者信息查询)、服务依赖关系分析、服务运行状况感知、服务可用性保障,如:路由调整、流量分配、服务端降级、调用端降级等
http://i17c.net/blog/?q=node/2
背景: WEBX -- 阿里巴巴网站所采用的WEB应用框架.
HSF接口: com.taobao.item.service.ItemQueryService
需求: 根据商品ID取得商品信息
载体: TBCMS系统
实现步骤: 1. 创建 /bundle/war/src/webroot/META-INF/autoconf/item-hsf-xml.vm
代码:
2.其中: ${item_provide_service_version} 需要在 auto-config.xml 中配置,在
同时在 中增加:
3.在 /bundle/war/src/webroot/WEB-INF/cms-biz-services.xml中增加:
....................
至此,我们已经引入了ItemQueryService的HSF服务.
4. 接下来我们就要做Servlet接口了,当然写一个servlet直接调用hsf也是可以的,但是从结构考虑,我们还是先本地封装一层先.
但是首先,需要对 /all/project.xml 中需要增加对ItemQueryService的支持:
并在/biz/project.xml和/web/project.xml中增加:
............
命令行模式下执行: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中增加
至此,我们已经在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 {
//
// 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中增加:
7.至此,开发完成
命令行模式下执行:antx reactor goals=clean,default来对项目重新编译打包.重启本地服务器进行测试.
对/item/query接口进行post的时候触发此servlet.