用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 ...
随机推荐
- 周期性计划(一个cron守护进程):
周期性计划(一个cron守护进程): root@ubuntu:/etc# ps -ef | grep cron root 903 1 0 16:25 ? 00:00:00 /usr/sbin/cron ...
- php设计模式之--组合模式
php组合模式主要用于上下级关系,可以新增叶子和树枝,分析如下代码即可明白组合模式的含义: <?php header('Content-Type:text/html;charset=utf-8' ...
- [bzoj 1449] 球队收益(费用流)
[bzoj 1449] 球队收益(费用流) Description Input Output 一个整数表示联盟里所有球队收益之和的最小值. Sample Input 3 3 1 0 2 1 1 1 1 ...
- 模拟等待事件:db file sequential read
相关知识: db file sequential read 单块读 optimizer_index_cost_adj 这个初始化参数代表一个百分比,取值范围在1到10000之间.该参数表示索引扫描和 ...
- WPF-初始屏幕(SplashScreen)
本主题介绍如何将启动窗口(也称为“初始屏幕”)添加到 Windows Presentation Foundation (WPF) 应用程序. 添加现有图像作为初始屏幕 创建或查找要用于初始屏幕的图像. ...
- 插入排序(InsertionSort)
位置p上的元素存储于tmp(第一趟p通常取1),而(位置p之前)所有更大的元素都向右移动一个位置. 然后tmp被放在正确的位置上. 代码: public class InsertionSort { p ...
- 当数据库中的字段与javabean中对应的属性名不同
当数据库中的字段与javabean中对应的属性名不同时: 在查询语句中对不同的字段起别名,例如: 数据库中的字段名为last_name , javabean中为lastName则:select las ...
- MongoDB 2.6复制集单节点部署(三)
MongoDB在单节点中也可以做复制集,但是仅限于测试实验,最大的好处就是部署方便快速,可以随便添加新节点,节省资源.在这里我使用的是MongoDB 2.6版本进行复制集实验(但MongoDB配置文件 ...
- servlet里的forward和redirect的区别
forward方式:request.getRequestDispatcher("/somePage.jsp").forwardrequest, response); red ...
- ZipHelper
using ICSharpCode.SharpZipLib.Zip; using System.Collections.Generic; using System.IO; namespace WLYD ...