去年一年的时间中,用Thrift提供服务的方式,开发了一个用户中心系统,以便于与其它的各个业务系统进行相应的集成。
在生产环境中,ThriftServer的选择是很重要的。建议在TThreadPoolServer和 TThreadedSelectorServer中进行相应的选择。个人建议选择TThreadedSelectorServer,因为其支持网络NIO,在一个业务的处理过程中,很大一部分时间会阻塞在网络通信上,并且TThreadedSelectorServer能吞吐更多的网络连接,而ThreadPoolServer吞吐的网络连接数和其启动的线程数量有关,如果存在客户端调用代码未正常关闭Transport时,其网络连接只有在时间超时时才会正常释放掉,造成服务的无法正常提供。
具体的参考资料见:http://www.codelast.com/?p=4824
本人在实际应用的过程中,是使用Spring+Mybatis+Thrift方式。在Spring中,重量级的业务处理Service的创建是非常耗时的,所以对于这些Service,一定要用对象池将期存储起来,防止Thrift在处理业务的过程中,频繁的创建业务对象,消耗系统资源。
默认的情况下,TProcessorFactory是使用了单列的模式,所以要对TProcessorFactory进行扩展,并使其支持对象池技术,增加释放处理对象的方法returnProcessor,如以下代码:
package org.apache.thrift;
import org.apache.thrift.transport.TTransport;
/**
* The default processor factory just returns a singleton instance.
*/
public class TProcessorFactory {
private final TProcessor processor_;
public TProcessorFactory(TProcessor processor) {
processor_ = processor;
}
public TProcessor getProcessor(TTransport trans) {
return processor_;
}
public void returnProcessor(TProcessor _tprocessor) {
}
}
将使用完的对象释放到连接池中,并更改调用getProcessor方法的地方,释放相应的Processor.将业务实现代码中,从对象池中获取处理对象
在业务系统代码中的实现如下:
package com.hoodinn.user.service.thrift;
import org.apache.commons.pool.impl.StackObjectPool;
import org.apache.log4j.Logger;
import org.apache.thrift.TProcessor;
import org.apache.thrift.TProcessorFactory;
import org.apache.thrift.transport.TTransport;
import org.springframework.context.ApplicationContext;
import com.hoodinn.user.connector.thrift.UserAcceptor;
/**
* @author MatrixZhang
* @createTime 2012-8-16 下午7:42:27
* @Description
*/
public class UserProcessorFactory extends TProcessorFactory {
private StackObjectPool<TProcessor> sop;
static Logger log = Logger.getLogger(UserProcessorFactory.class);
public UserProcessorFactory(ApplicationContext applicationContext, Integer poolSize) {
super(null);
sop = new StackObjectPool<TProcessor>(new USPoolFactory(applicationContext) {
@Override
public TProcessor selfMakeObject() {
return new UserAcceptor.Processor<UserAcceptorService>(applicationContext.getBean(UserAcceptorService.class));
}
}, poolSize + 2);
}
@Override
public TProcessor getProcessor(TTransport trans) {
try {
return sop.borrowObject();
} catch (Exception e) {
log.error("获取UserAcceptorService时出错!", e);
return null;
}
}
@Override
public void returnProcessor(TProcessor _tprocessor) {
try {
sop.returnObject(_tprocessor);
} catch (Exception e) {
log.error("归还UserAcceptorService时出错", e);
}
}
}
这样使用对象池技术以后,Thrift接口的数据吞吐量能有一个大幅度的提升。另外,在使用Thrift设计相应的接口时,建议使用字符串对JSON的格式进行相应的数据传输。在接口设计时,只设计上两个接口,一个是前端业务处理,一个是后台业务处理 。如以下的定义方式:
service ThirdSnsAcceptor{
/** 接口服务的处理 */
string businessProcess(1:string param);
/** 后台管理业务的处理 */
string adminProcess(1:string param);
}
在实际的使用过程中,我发现使用纯正的接口对象传输和使用JSON的性能差异不大。因为Jackson的解析性能还是非常可观的,这样,接口定义以后,基本上不需要有任何改动了。对于接口数据的定义,可以使用以下的方式:
{
"name":"addFriend",
"version":"1.0",
"param":{
"appId":1,
"userId":1,
"platform":"WEIBO"
}
}
这样,可以以name和version实现不同的业务处理分支跳转。
这是本人的一点经验总结,如有什么不足之处,欢迎大爱回复,讨论。
附件是我更改过的Thrift的代码,增加对对象池支持。
分享到:
相关推荐
这里对client进行修改,采用GenericKeyedObjectPool线程池和反射的方式对client进行优化。 场景: 项目中有大量的rpc请求,请求的特点时间长。 解决方案: 使用GenericKeyedObjectPool,T>,T为TServiceClient,简单的...
分析Thrift的结构动机是为了实现服务端能取到客户端的IP,因此需要对它的结构、调用流程有些了解。... thrift对网络连接没有使用内存池,最直接简单的性能优化是绑定Google gperftools中的TCMalloc。
7.2.3 ThriftServer使用 54 7.3:小结 56 八:sparkSQL之综合应用 57 8.1:店铺分类 57 8.2:PageRank 59 8.3:小结 61 九:sparkSQL之调优 61 9.1:并行性 62 9.2: 高效的数据格式 62 9.3:内存的使用 63 9.4:...
这是一种替代方法使用从与节俭IDL源文件生成的代码thrift编译器。 ThriftRW支持在有或没有Thrift IDL源的情况下对协议进行编码和解码。 没有源代码,仍然可以使用带编号的字段对结构进行Thrift二进制协议的所有...
技术点38 使用堆转储来查找未优化的用户代码 6.2.5 硬件性能问题 技术点39 查找硬件的失效 技术点40 CPU 竞争 . 技术点41 内存交换 技术点42 磁盘健康 技术点43 网络 6.3 可视化 技术点44 提取并可视化...
优化 RocksDB 的性能,使用 DeleteFilesInRanges 等特性,提升空间回收效率,降低磁盘负载,以及更加平滑地使用磁盘资源等等。 OLAP 性能优化 TiDB 2.0 版本重构了 SQL 优化器和执行引擎,希望能尽可能快的选择最优...
返回的timestamp与现实时间有基本对应关系,为当前Unix time乘以2的18次方(足够使用1115年),由于我们优化了性能,所以如果存在failover就不能保证这种对应关系的可靠性。ChronosClient启动时,通过访问ZooKeeper...
4.4 本章小结5 优化HDFS 处理大数据的技术5.1 处理小文件技术点24 使用Avro 存储大量小文件5.2 通过压缩提高数据存储效率技术点25 选择合适的压缩解码器技术点26 在HDFS、MapReduce、Pig 和Hive 中使用...
Difeye是一款超轻量级PHP框架,前身由Kohana框架演变而来,在企业实践开发中,我们不断对框架做了精简和修改,抽取最核心模块,...◆修正thrift传输编码问题、优化传输速度 ◆增加hadoop、LEMP、Mongodb等配置手册;
Difeye是一款超轻量级PHP框架,前身由Kohana框架演变而来,在企业实践开发中,我们不断对框架做了精简和修改,抽取最核心模块,...◆修正thrift传输编码问题、优化传输速度 ◆增加hadoop、LEMP、Mongodb等配置手册;
接口的性能监控是集成式的,使用者自动获得了接口性能数据,方便优化接口 普通二进制协议示例 Ffrpc实现了一个最基本的二进制序列化方法,基本的原理就是如果是固定长度那么就直接拷贝,如果是字符串,就先拷贝...
我的学士论文的这个迷你代码版本是... 在“加速”分支中,我在每次提交时添加了以下功能: - 具有偶数 ID 的工作代理执行广度优先搜索 - 编译时优化 - 使用启发式而不是单纯形 - 多线程服务器和回调函数来终止求解()
您可以将其视为protobuf,thrift,flatbuffers等,但是可以想象它不是由一组工程师来维护,而是由编写的。 创建Structy是为了在嵌入式设备上基于C的固件与在大型计算机上运行的基于Python和JavaScript的编程,测试...
11.分布式SQL引擎(spakr-sql和Spark ThriftServer) 12.Catalyst 优化器 第四章、离线综合实战 1.综合实战概述(需求、调研、业务) 2.环境搭建(大数据环境和应用开发环境) 3.项目初始化(工具类和属性文件) 4....
Flapps暴露了很少的thrift API给客户端,我们写的Ruby客户端包含更丰富的接口。 我们使用Gizzard库来处理数据分块层。该层将一段源ID映射到物理数据库,对于同一个物理地址的表,通过建立树来处理。写操作在本地登记...