用apache commons-pool2建立thrift连接池
Apache Thrift 是 Facebook 实现的一种高效的、支持多种编程语言的远程服务调用的框架。具体的介绍可以看Apache的官方网站:http://thrift.apache.org/ 。今天并不介绍thrift如何使用,只是演示一下如何使用commons-pool2建立thrift连接池,这样可以快速访问服务端。
我演示的thrift接口如下所示:
public interface Iface {
public String genNewKTVOrder(com.ethank.thrift.iface.service.TOrder torder) throws org.apache.thrift.TException;
public String genWeiXinPreOrder(String orderId, String body) throws org.apache.thrift.TException;
public String genPreKTVGoodsOrder(String reserveGoodsId, String reserveBoxId, String goodsList, String sumPrice, int userId, String ktvId) throws org.apache.thrift.TException;
public String genWeiXinQRCode(String orderId, String body) throws org.apache.thrift.TException;
}
这些代码都是通过thrift自动生成的,具体如何操作可以看网上搜索一些thrift教程。
thrift客户端是这样一个内部类:
public static class Client extends org.apache.thrift.TServiceClient implements Iface
我的思路实在pool中放入org.apache.thrift.transport.TSocket对象,其工厂方法如下:
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.thrift.transport.TSocket; public class ConnectionFactory extends BasePooledObjectFactory<TSocket>{ @Override
public TSocket create() throws Exception {
TSocket transport = new TSocket("192.168.1.222", 34568, 2000); //建立TSocket,根据具体情况可以修改
transport.open();
return transport;
} @Override
public boolean validateObject(org.apache.commons.pool2.PooledObject<TSocket> p){ //校验对象有效性
TSocket transport = p.getObject();return transport.isOpen();
} @Override
public PooledObject<TSocket> wrap(TSocket obj) { //创建包装对象,包装对象是真正放在pool中的对象
return new DefaultPooledObject<TSocket>(obj);
} @Override
public void destroyObject(PooledObject<TSocket> p) throws Exception { //销毁对象,关闭链接
if (p.getObject().isOpen()) {
p.getObject().close();
}
} }
实际调用中并不是用的TSocket,而是Client对象,为此建立ConnectionManager利用TSocket建立Client对象:
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.ethank.thrift.iface.service.EthankOrderService; public class ConnectionManager { private static final Logger LGR = LoggerFactory.getLogger(ConnectionManager.class); private static GenericObjectPool<TSocket> pool; static {
ConnectionFactory connectionFactory = new ConnectionFactory();
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxIdle(10); //最大空闲数量
config.setMaxTotal(20); //连接池最大数量
config.setMinIdle(3); //最小空闲数量
config.setTestOnBorrow(true); //在从pool中去对象时进行有效性检查,会调用工厂中的validateObject
config.setMaxWaitMillis(1000); //提取对象时最大等待时间,超时会抛出异常
config.setMinEvictableIdleTimeMillis(60000); // 最小的空闲对象驱除时间间隔,空闲超过指定的时间的对象,会被清除掉
config.setTimeBetweenEvictionRunsMillis(30000);//后台驱逐线程休眠时间
config.setNumTestsPerEvictionRun(3); //设置驱逐线程每次检测对象的数量
config.setTestWhileIdle(true); //是否对空闲对象使用PoolableObjectFactory的validateObject校验,
pool = new GenericObjectPool<TSocket>(connectionFactory, config);
} public static EthankOrderService.Client getThriftConnetion(){
TSocket socket;
try {
socket = pool.borrowObject();
TProtocol protocol = new TCompactProtocol(socket);
EthankOrderService.Client client= new EthankOrderService.Client(protocol);
client.socket = socket;
return client;
} catch (Exception e) {
e.printStackTrace();
}
return null;
} public static void returnThriftConnetion(EthankOrderService.Client client){
pool.returnObject(client.socket);
} public static int getPoolObjectNum() {
return pool.getNumIdle();
} }
测试类做测试:
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
try {
new Thread(new Runnable() {
public void run() {
EthankOrderService.Client client = null;
try {
client = ConnectionManager.getThriftConnetion();
String re = client.genWeiXinPreOrder("1111111", "222");
System.out.println(re+" "+ client.socket.hashCode());
} catch (Exception e) {
e.printStackTrace();
}finally{
ConnectionManager.returnThriftConnetion(client);
}
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这只是一个最简单的pool使用实例,可以做很多的改进,如优化pool中对象,加入动态代理以屏蔽client其他接口。此实例尽起抛砖引玉!
参考资料:
1. apache commons-pool的配置参数 http://www.thinksaas.cn/group/topic/96620/
用apache commons-pool2建立thrift连接池的更多相关文章
- Lettuce连接池——解决“MXBean already registered with name org.apache.commons.pool2:type=GenericObjectPool,name=pool”
LettuceConfig: package com.youdao.outfox.interflow.config; import io.lettuce.core.support.Connection ...
- Java--对象池化技术 org.apache.commons.pool2.ObjectPool
org.apache.commons.pool2.ObjectPool提供了对象池,开发的小伙伴们可以直接使用来构建一个对象池 使用该对象池具有两个简单的步骤: 1.创建对象工厂,org.apache ...
- common-pool2 学习:thrift连接池的另一种实现
对象池是一种很实用的技术,经典的例子就是数据库连接池.去年曾经从零开始写过一个thrift客户端连接池.如果不想重造轮子,可以直接在apache开源项目commons-pool的基础上开发. 步骤: ...
- Apache Commons Pool2 源码分析 | Apache Commons Pool2 Source Code Analysis
Apache Commons Pool实现了对象池的功能.定义了对象的生成.销毁.激活.钝化等操作及其状态转换,并提供几个默认的对象池实现.在讲述其实现原理前,先提一下其中有几个重要的对象: Pool ...
- springboot集成redis报错-ClassNotFoundException: org.apache.commons.pool2.impl.GenericObjectPoolConfig
当使用Springboot 2.0以上版本集成redis的时候遇到报错信息如下: Application run failed org.springframework.beans.factory.Un ...
- rpc框架之 thrift连接池实现
接前一篇rpc框架之HA/负载均衡构架设计 继续,写了一个简单的thrift 连接池: 先做点准备工作: package yjmyzz; public class ServerInfo { publi ...
- Caused by: java.lang.NoClassDefFoundError: org/apache/commons/pool2/impl/GenericObjectPoolConfig
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/pool2/impl/GenericObjectPoolConfig at ...
- jmeter建立JDBC连接池时遇到“A Test is currently running,stop or shutdown test to execute this command”
1.显示如下图,打开日志可以看到:Variable Name must not be empty for element:JDBC Connection Configuration,即JDBC Con ...
- java.lang.ClassNotFoundException: org.apache.commons.pool2.impl.GenericObjectPoolConfig
问题描述: Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with n ...
随机推荐
- BZOJ 2002 Bounce 弹飞绵羊 —— 分块算法
题目链接:https://vjudge.net/problem/HYSBZ-2002 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Li ...
- the art of seo(chapter three)
SEO Planning: Customizing Your Strategy ***Developing an SEO Plan Prior to Site Development***Determ ...
- TCP连接过程
TCP建立连接与释放连接 最近复习准备<计算机网络>考试,感觉TCP协议建立连接与释放连接这两个过程比较重要,所以把自己理解的部分写下来. 1.建立连接:(三次握手) (1)客户端发 ...
- python中format()方法格式化字符串
format()是python2.6新增的一个格式化字符串的方法,功能非常强大,有可能在未来完全替代%格式化方法,相比 % ,format()的优点有: 1 .格式化时不用关心数据类型的问题,form ...
- bootstrap 学习笔记(5)---- 图片和响应式工具
(一)响应式图片: 在 Bootstrap 版本 3 中,通过为图片添加 .img-responsive 类可以让图片支持响应式布局.其实质是为图片设置了 max-width: 100%;. heig ...
- poj 2069 Super Star —— 模拟退火
题目:http://poj.org/problem?id=2069 仍是随机地模拟退火,然而却WA了: 看看网上的题解,都是另一种做法——向距离最远的点靠近: 于是也改成那样,竟然真的A了...感觉这 ...
- Spring 注释标签@Resource @Autowired 和@Inject的区别
一些spring的开发人员在使用这三个标签进行注入的时候感到困惑.我来尝试解释一下这三个注解的主要区别.事实上,这三者非常相似,只存在一些微小的差别.在稍后的文章中会进行解释. @Resource-在 ...
- web.xml中load-on-startup的作用,web应用写一个InitServlet,这个servlet配置为启动时装载
如下一段配置,熟悉DWR的再熟悉不过了:<servlet> <servlet-name>dwr-invoker</servlet-name> <ser ...
- web.xml报错Cannot resolve class 'StrutsPrepareAndExecuteFilter' (idea创建SSH项目)
原因: xwork-core.jar包已经合并到struts2-core.jar下,并且点开jar包,发现没有 org.apache.struts2.dispatcher.ng.filter.Stru ...
- node本地服务启动报Error: listen EADDRINUSE解决方法
Error: listen EADDRINUSE 127.0.0.1:1337 at Object.exports._errnoException (util.js:1018:11) at expor ...