简介

Thrift是Facebook的核心框架之一,使不同的开发语言开发的系统可以通过该框架实现彼此的通信,类似于webservice,但是Thrift提供了近乎变态的效率和开发的方便性,是webservice所不能比拟的。给分布式开发带来了极大的方便。但是这柄利器也有一些不完美。

问题

首先文档相当的少,只有一个wiki网站提供相应的帮助。这对于Thrift的推广极为不利。

其次框架本身实现有一些缺陷,就Thrift的java部分来说,没有提供连接池的支持,对RPC的调用效率有所影响。

对于文档稀少的问题,只能是通过一些Thrift的开发者和使用者多供献一些自己的心得来解决。这得需要一个过程。而连接池的问题的解决则可以快速一些。

提到池一般做过Java开发的肯定会想到ObjectPool,Apache Commons项目确实给我们的开发得来了很大的便利性,其中的pool项目正是我们实现thrift连接池的基础,当然也少不了神器spring framework。

实现

一,定义thrift连接池接口

ConnectionProvider Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->/** @(#)ConnectionProvider.java    0.1 05/11/17** Copyright 2010 QISI, Inc. All rights reserved.* QISI PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*/
package com.qidea.thrift.pool;
import org.apache.thrift.transport.TSocket;
/*** * @author sunwei* @version 2010-8-6* @since JDK1.5*/
public interface ConnectionProvider
{/*** 取链接池中的一个链接* * @return*/public TSocket getConnection();/*** 返回链接* * @param socket*/public void returnCon(TSocket socket);
}

二,实现连接池

GenericConnectionProvider Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->/** @(#)DefaultConnectionProviderImpl.java    0.1 05/11/17** Copyright 2010 QISI, Inc. All rights reserved.* QISI PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*/
package com.qidea.thrift.pool;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.thrift.transport.TSocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
/*** * @author sunwei* @version 2010-8-10* @since JDK1.5*/
public class GenericConnectionProvider implements ConnectionProvider,InitializingBean, DisposableBean
{public static final Logger logger = LoggerFactory.getLogger(GenericConnectionProvider.class);/** 服务的IP地址 */private String serviceIP;/** 服务的端口 */private int servicePort;/** 连接超时配置 */private int conTimeOut;/** 可以从缓存池中分配对象的最大数量 */private int maxActive = GenericObjectPool.DEFAULT_MAX_ACTIVE;/** 缓存池中最大空闲对象数量 */private int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE;/** 缓存池中最小空闲对象数量 */private int minIdle = GenericObjectPool.DEFAULT_MIN_IDLE;/** 阻塞的最大数量 */private long maxWait = GenericObjectPool.DEFAULT_MAX_WAIT;/** 从缓存池中分配对象,是否执行PoolableObjectFactory.validateObject方法 */private boolean testOnBorrow = GenericObjectPool.DEFAULT_TEST_ON_BORROW;private boolean testOnReturn = GenericObjectPool.DEFAULT_TEST_ON_RETURN;private boolean testWhileIdle = GenericObjectPool.DEFAULT_TEST_WHILE_IDLE;/** 对象缓存池 */private ObjectPool objectPool = null;/*** */@Overridepublic void afterPropertiesSet() throws Exception{// 对象池objectPool = new GenericObjectPool();//
        ((GenericObjectPool) objectPool).setMaxActive(maxActive);((GenericObjectPool) objectPool).setMaxIdle(maxIdle);((GenericObjectPool) objectPool).setMinIdle(minIdle);((GenericObjectPool) objectPool).setMaxWait(maxWait);((GenericObjectPool) objectPool).setTestOnBorrow(testOnBorrow);((GenericObjectPool) objectPool).setTestOnReturn(testOnReturn);((GenericObjectPool) objectPool).setTestWhileIdle(testWhileIdle);((GenericObjectPool) objectPool).setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);// 设置factoryThriftPoolableObjectFactory thriftPoolableObjectFactory = new ThriftPoolableObjectFactory(serviceIP, servicePort, conTimeOut);objectPool.setFactory(thriftPoolableObjectFactory);}@Overridepublic void destroy(){try{objectPool.close();}catch (Exception e){throw new RuntimeException("erorr destroy()", e);}}@Overridepublic TSocket getConnection(){try{TSocket socket = (TSocket) objectPool.borrowObject();return socket;}catch (Exception e){throw new RuntimeException("error getConnection()", e);}}@Overridepublic void returnCon(TSocket socket){try{objectPool.returnObject(socket);}catch (Exception e){throw new RuntimeException("error returnCon()", e);}}public String getServiceIP(){return serviceIP;}public void setServiceIP(String serviceIP){this.serviceIP = serviceIP;}public int getServicePort(){return servicePort;}public void setServicePort(int servicePort){this.servicePort = servicePort;}public int getConTimeOut(){return conTimeOut;}public void setConTimeOut(int conTimeOut){this.conTimeOut = conTimeOut;}public int getMaxActive(){return maxActive;}public void setMaxActive(int maxActive){this.maxActive = maxActive;}public int getMaxIdle(){return maxIdle;}public void setMaxIdle(int maxIdle){this.maxIdle = maxIdle;}public int getMinIdle(){return minIdle;}public void setMinIdle(int minIdle){this.minIdle = minIdle;}public long getMaxWait(){return maxWait;}public void setMaxWait(long maxWait){this.maxWait = maxWait;}public boolean isTestOnBorrow(){return testOnBorrow;}public void setTestOnBorrow(boolean testOnBorrow){this.testOnBorrow = testOnBorrow;}public boolean isTestOnReturn(){return testOnReturn;}public void setTestOnReturn(boolean testOnReturn){this.testOnReturn = testOnReturn;}public boolean isTestWhileIdle(){return testWhileIdle;}public void setTestWhileIdle(boolean testWhileIdle){this.testWhileIdle = testWhileIdle;}public ObjectPool getObjectPool(){return objectPool;}public void setObjectPool(ObjectPool objectPool){this.objectPool = objectPool;}
}

ThriftPoolableObjectFactory Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->/** @(#)ThriftPoolableObjectFactory.java    0.1 05/11/17** Copyright 2010 QISI, Inc. All rights reserved.* QISI PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*/
package com.qidea.thrift.pool;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*** * @author sunwei* @version 2010-8-10* @since JDK1.5*/
public class ThriftPoolableObjectFactory implements PoolableObjectFactory
{/** 日志记录器 */public static final Logger logger = LoggerFactory.getLogger(ThriftPoolableObjectFactory.class);/** 服务的IP */private String serviceIP;/** 服务的端口 */private int servicePort;/** 超时设置 */private int timeOut;/*** * @param serviceIP* @param servicePort* @param timeOut*/public ThriftPoolableObjectFactory(String serviceIP, int servicePort,int timeOut){this.serviceIP = serviceIP;this.servicePort = servicePort;this.timeOut = timeOut;}@Overridepublic void destroyObject(Object arg0) throws Exception{if (arg0 instanceof TSocket){TSocket socket = (TSocket) arg0;if (socket.isOpen()){socket.close();}}}/*** */@Overridepublic Object makeObject() throws Exception{try{TTransport transport = new TSocket(this.serviceIP,this.servicePort, this.timeOut);transport.open();return transport;}catch (Exception e){logger.error("error ThriftPoolableObjectFactory()", e);throw new RuntimeException(e);}}@Overridepublic boolean validateObject(Object arg0){try{if (arg0 instanceof TSocket){TSocket thriftSocket = (TSocket) arg0;if (thriftSocket.isOpen()){return true;}else{return false;}}else{return false;}}catch (Exception e){return false;}}@Overridepublic void passivateObject(Object arg0) throws Exception{// DO NOTHING
    }@Overridepublic void activateObject(Object arg0) throws Exception{// DO NOTHING
    }public String getServiceIP(){return serviceIP;}public void setServiceIP(String serviceIP){this.serviceIP = serviceIP;}public int getServicePort(){return servicePort;}public void setServicePort(int servicePort){this.servicePort = servicePort;}public int getTimeOut(){return timeOut;}public void setTimeOut(int timeOut){this.timeOut = timeOut;}
}

  三,定义连接的管理类 

ConnectionManager Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->/** @(#)ConnectionManager.java    0.1 05/11/17** Copyright 2010 QISI, Inc. All rights reserved.* QISI PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*/
package com.qidea.thrift.pool;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.thrift.transport.TSocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*** * @author sunwei* @version 2010-8-10* @since JDK1.5*/
public class ConnectionManager implements MethodInterceptor
{/** 日志记录器 */public Logger logger = LoggerFactory.getLogger(ConnectionManager.class);/** 保存local对象 */ThreadLocal<TSocket> socketThreadSafe = new ThreadLocal<TSocket>();/** 连接提供池 */public ConnectionProvider connectionProvider;@Overridepublic Object invoke(MethodInvocation arg0) throws Throwable{TSocket socket = null;try{socket = connectionProvider.getConnection();socketThreadSafe.set(socket);Object ret = arg0.proceed();return ret;}catch (Exception e){logger.error("error ConnectionManager.invoke()", e);throw new Exception(e);}finally{connectionProvider.returnCon(socket);socketThreadSafe.remove();}}/*** 取socket* * @return*/public TSocket getSocket(){return socketThreadSafe.get();}public ConnectionProvider getConnectionProvider(){return connectionProvider;}public void setConnectionProvider(ConnectionProvider connectionProvider){this.connectionProvider = connectionProvider;}
}

四,定义spring配置,对受管的bean提供thrift连接

Thrift连接池spring配置 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:flex="http://www.springframework.org/schema/flex" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsdhttp://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsdhttp://www.springframework.org/schema/flex http://www.springframework.org/schema/flex/spring-flex-1.0.xsd"><!-- thrift连接池配置 --><bean id="connectionProvider" class="com.qidea.thrift.pool.GenericConnectionProvider"><property name="serviceIP" value="localhost" /><property name="servicePort" value="9090" /><property name="maxActive" value="10" /><property name="maxIdle" value="10" /><property name="testOnBorrow" value="true" /><property name="testOnReturn" value="true" /><property name="testWhileIdle" value="true" /><property name="conTimeOut" value="2000" /></bean><!-- thrift连接管理配置  --><bean id="connectionManager" class="com.qidea.thrift.pool.ConnectionManager"><property name="connectionProvider" ref="connectionProvider" /></bean><!-- 客户端接口配置  --><bean class="com.qidea.pushserver.rpc.client.PushServiceClient"><property name="connectionManager" ref="connectionManager" /></bean><!-- thrift连接AOP配置  --><aop:config proxy-target-class="true"><aop:pointcut id="clientMethods"expression="execution(* com.qidea.pushserver.rpc.client.*.*(..))" /><aop:advisor advice-ref="connectionManager" pointcut-ref="clientMethods" /></aop:config>
</beans>

五,使用连接池

PushRPCClient Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->/** @(#)PushRPCClient.java    0.1 05/11/17** Copyright 2010 QISI, Inc. All rights reserved.* QISI PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*/
package com.qidea.pushserver.rpc;
import java.util.ArrayList;
import java.util.List;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.qidea.pushserver.ServiceException;
import com.qidea.thrift.pool.ConnectionManager;
/*** * @author sunwei* @version 2010-8-11* @since JDK1.5*/
public class PushRPCClient
{public static Logger logger = LoggerFactory.getLogger(PushRPCClient.class);private ConnectionManager connectionManager;/*** 取在线玩家列表* * @param roleIdList* @return* @throws ServiceException*/public List<Long> getOnLineRoleIdList(List<Long> roleIdList){TProtocol protocol = new TBinaryProtocol(connectionManager.getSocket());PushRPCService.Client client = new PushRPCService.Client(protocol);try{List<Long> onLineIdList = client.getOnLineRoleIdList(roleIdList);return onLineIdList;}catch (TException e){logger.error("error getOnLineRoleIdList()", e);}return new ArrayList<Long>();}/*** 解散联盟* * @param allianceId*/public void dismissAlliance(long allianceId){TProtocol protocol = new TBinaryProtocol(connectionManager.getSocket());PushRPCService.Client client = new PushRPCService.Client(protocol);try{client.dismissAlliance(allianceId);}catch (TException e){logger.error("error dismissAlliance()", e);}}/*** 加入联盟* * @param roleId* @param allianceId*/public void joinAlliance(long roleId, long allianceId){TProtocol protocol = new TBinaryProtocol(connectionManager.getSocket());PushRPCService.Client client = new PushRPCService.Client(protocol);try{client.joinAlliance(roleId, allianceId);}catch (TException e){logger.error("error joinAlliance()", e);}}/*** 解散联盟* * @param roleId* @param allianceId*/public void getOutAlliance(long roleId, long allianceId){TProtocol protocol = new TBinaryProtocol(connectionManager.getSocket());PushRPCService.Client client = new PushRPCService.Client(protocol);try{client.getOutAlliance(roleId, allianceId);}catch (Exception e){logger.error("error getOutAlliance()", e);}}public ConnectionManager getConnectionManager(){return connectionManager;}public void setConnectionManager(ConnectionManager connectionManager){this.connectionManager = connectionManager;}
}

转载于:https://www.cnblogs.com/lihaozy/archive/2013/04/22/3035113.html

[转]Thrift连接池实现相关推荐

  1. 用apache commons-pool2建立thrift连接池

    Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的远程服务调用的框架.具体的介绍可以看Apache的官方网站:http://thrift.apache.org/ . ...

  2. java thrift连接池_由浅入深了解Thrift之客户端连接池化

    一.问题描述 在上一篇<由浅入深了解Thrift之服务模型和序列化机制>文章中,我们已经了解了thrift的基本架构和网络服务模型的优缺点.如今的互联网圈中,RPC服务化的思想如火如荼.我 ...

  3. python连接池框架_Python中的连接池是非常重要的!神级程序员详解!

    概述 连接池的作用就是为了提高性能,将已经创建好的连接保存在池中,当有请求来时,直接使用已经创建好的连接对Server端进行访问.这样 省略了创建连接和销毁连接的过程(TCP连接建立时的三次握手和销毁 ...

  4. common pool2 mysql_连接池Commons Pool2的使用

    客户端这边,如果每次都临时建立一个新的连接,那么连接的开销非常大. 业内常用的连接池组件是 Commons Pool2---版本 2.4.2 packageservice.pool; importor ...

  5. python socketpool:通用连接池

    简介 在软件开发中经常要管理各种"连接"资源,通常我们会使用对应的连接池来管理,比如mysql数据库连接可以用sqlalchemy中的池来管理,thrift连接可以通过thrift ...

  6. 基于 Netty 如何实现高性能的 HTTP Client 的连接池

    使用netty作为http的客户端,pool又该如何进行设计.本文将会进行详细的描述. 1. 复用类型的选型 1.1 channel 复用 多个请求可以共用一个channel 模型如下: 模型 特点: ...

  7. java cassandra连接池_java操作cassandra(连接池)

    package com.chu.cassandratest; import java.util.concurrent.Semaphore; import java.util.concurrent.Ti ...

  8. 自己写的grpc简单连接池,基于common pool2

    17年的时候写的证券的项目,当时交易端是另外一批同事开发的,他们强烈要求用grpc,当时这个东西还不那么成熟,在网上也搜索不到比较完美的第三方的连接池搭配使用,索性就自己写了一个,因为之前thrift ...

  9. java连接池详解与自定义es连接池

    目录 1 版本选择 2 依赖选择 3 使用commons-pool构造连接池 3.1 pom.xml 3.2 对象池类 GenericObjectPool普通对象池 GenericKeyedObjec ...

  10. java dbcp连接池 使用_Java使用DBCP连接池

    DBCP 是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件.单独使用dbcp需要3个包:common-dbcp.jar,common-pool.jar,commo ...

最新文章

  1. Python之两个列表一起打乱
  2. UIKit框架使用总结--看看你掌握了多少
  3. IBatis.Net学习笔记四--数据库的缓存模式
  4. Spring Boot Admin 2.5.5 发布,支持在线重启服务
  5. 区域内点的个数_JAVA
  6. SQL重复记录查询(转载)
  7. python怎么下载安装mac_Mac下内置python2.7如何安装模块?
  8. 计算机等级考试机试试题,计算机等级考试二级VFP机试试题18
  9. JS switch 分支语句
  10. Dynamic programming
  11. 2017年10月9日 冒泡去重复习
  12. eclipse二进制编辑器插件
  13. web前端职业生涯路线
  14. 问卷调查系统 简易版
  15. 青果教务系统API(Java版)
  16. 区间dp入门——总结+习题+解析
  17. linux usb信息查看工具,Linux下,查看USB设备信息
  18. 安卓虚拟键盘_安卓手机开启全局手势导航的方法,拯救老设备
  19. marktext安装配置-设置中文语言包
  20. python群发邮件_python smtp 群发邮件

热门文章

  1. presto 正则提取函数
  2. Visual Studio2013配置安装Opencv2.4.9详细过程
  3. Mysql--Auto_increment详解
  4. 使用idea练习springmvc时,出现404错误总结
  5. 保护自己之手机定位信息收集
  6. Java-P: 1、程序设计语言的分类
  7. win10 当前操作环境不支持支付宝控件 完美解决办法
  8. Android程序开发初级教程(一)
  9. 双链表 c teacher-double-nohead-noloop
  10. Delphi编译后的程序图标无法修改一例