用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 ...
随机推荐
- bzoj4486: [Jsoi2015]串分割
肉丝哥哥钦定好题 话说我的blog现在为什么到处都是肉丝哥哥 先来想一个弱化版,假如能够n整除K怎么做? 把每个数字看成一个字符串,按字典序排名,这个可以后缀数组解决,然后暴力枚举每种情况,O(1)判 ...
- 数据结构之 线性表---单链表操作A (删除链表中的指定元素)
数据结构上机测试2-1:单链表操作A Time Limit: 1000MS Memory limit: 4096K 题目描述 输入n个整数,先按照数据输入的顺序建立一个带头结点的单链表,再输入一个数据 ...
- poj3349 Snowflake Snow Snowflakes —— 哈希表
题目链接:http://poj.org/problem?id=3349 题意:雪花有6个瓣,有n个雪花,输入每个雪花的瓣长,判断是否有一模一样的雪花(通过旋转或翻转最终一样,即瓣长对应相等).如果前面 ...
- jmeter中的响应断言
断言就类似LoadRunner中的检查点.对上一个请求返回的信息,做字符串.数据包大小.HTML.XML.图片等做判断,确保返回的信息的准确性. jmeter的断言有好多,下面是一个响应断言 新建一个 ...
- TestNG基本注解
TestNG的注解: 注解 描述 @BeforeSuite 注解的方法将只运行一次,运行所有测试前此套件中. @AfterSuite 注解的方法将只运行一次此套件中的所有测试都运行之后. @Befor ...
- 第二篇:python基础之核心风格
阅读目录 一.语句和语法 二.变量定义与赋值 三.内存管理 内存管理: 引用计数: 简单例子 四.python对象 五.标识符 六.专用下划线标识符 七.编写模块基本风格 八.示范 一.语句和语法 # ...
- Constructing Roads In JGShining's Kingdom
点击打开题目链接 本题目是考察 最长递增子序列的 有n^2 n(logn) n^2 会超时的 下面两个方法的代码 思路 可以百度LIS LCS dp里面存子序列 n(logn) ...
- JavaScript DOM 编程艺术 ---> JavaScript语法
二. JavaScript语法目录 2.1 语法 javaScript代码要通过HTML/XHTML文档才能执行.可以有两种方式完成这一点,第一种是将JavaScript代码放到文档<head ...
- bzoj 4756 [Usaco2017 Jan]Promotion Counting——线段树合并
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4756 线段树合并裸题.那种返回 int 的与传引用的 merge 都能过.不知别的题是不是这 ...
- for循环的一个注意点
unsigned int i =10; for(i;i > 0; i--) { xxxxx } 因为i是unsigned int 类型的,永远不可能小于0,也就是说是个死循环了.