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连接池的更多相关文章

  1. 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 ...

  2. Java--对象池化技术 org.apache.commons.pool2.ObjectPool

    org.apache.commons.pool2.ObjectPool提供了对象池,开发的小伙伴们可以直接使用来构建一个对象池 使用该对象池具有两个简单的步骤: 1.创建对象工厂,org.apache ...

  3. common-pool2 学习:thrift连接池的另一种实现

    对象池是一种很实用的技术,经典的例子就是数据库连接池.去年曾经从零开始写过一个thrift客户端连接池.如果不想重造轮子,可以直接在apache开源项目commons-pool的基础上开发. 步骤: ...

  4. Apache Commons Pool2 源码分析 | Apache Commons Pool2 Source Code Analysis

    Apache Commons Pool实现了对象池的功能.定义了对象的生成.销毁.激活.钝化等操作及其状态转换,并提供几个默认的对象池实现.在讲述其实现原理前,先提一下其中有几个重要的对象: Pool ...

  5. springboot集成redis报错-ClassNotFoundException: org.apache.commons.pool2.impl.GenericObjectPoolConfig

    当使用Springboot 2.0以上版本集成redis的时候遇到报错信息如下: Application run failed org.springframework.beans.factory.Un ...

  6. rpc框架之 thrift连接池实现

    接前一篇rpc框架之HA/负载均衡构架设计 继续,写了一个简单的thrift 连接池: 先做点准备工作: package yjmyzz; public class ServerInfo { publi ...

  7. Caused by: java.lang.NoClassDefFoundError: org/apache/commons/pool2/impl/GenericObjectPoolConfig

    Caused by: java.lang.NoClassDefFoundError: org/apache/commons/pool2/impl/GenericObjectPoolConfig at ...

  8. 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 ...

  9. java.lang.ClassNotFoundException: org.apache.commons.pool2.impl.GenericObjectPoolConfig

    问题描述: Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with n ...

随机推荐

  1. 让ansbile和docker愉快的在一起

    引自: http://cloud.51cto.com/art/201510/494328.htm

  2. codeforces B. Roma and Changing Signs 解题报告

    题目链接:http://codeforces.com/problemset/problem/262/B 题目意思:给出 n 个数和恰好一共要做的操作总数k.通过对n个数进行k次操作,每次操作可以把a[ ...

  3. linux应用之openssh server安装及配置(centos)

    安装OpenSSH Server 首先,我们搜索一下CentOS的软件库里面有没有已经定义好的SSH服务器包: $ yum search ssh ... ... openssh.x86_64 : An ...

  4. android中requestFocus

    标签用于指定屏幕内的焦点View. 例如我们点击tab键或enter键焦点自动进入下一个输入框用法: 将标签置于Views标签内部 <EditText id="@+id/text&qu ...

  5. RAM的分类

    转载自:http://wenku.baidu.com/view/b17d73244b35eefdc8d333ab.html RAM(随机存储器)可以分为SRAM(静态随机存储器)和DRAM(动态随机存 ...

  6. Windows_Program_Via_C_Translate_Win32编程的背景知识/基础知识_包括基本输入输出机制介绍

    Some Basic Background Story of The Win32 APIs Win32 API背景故事/背景知识 The Win32 application programming i ...

  7. Flexpaper二次开发入门教程》(十) Flexpaper简单使用-第一个Flexpaper例子

    4. Flexpaper简单使用 通过上面三章的内容,大家对Flexpaper.SWFTools应该有大概的了解了,SWF文件也已经生成了,我们开始进入Flexpaper的使用的介绍. 本章中只演示F ...

  8. asp.net mvc5 使用百度ueditor 本编辑器完整示例(下)

    一.百度ueditor 本编辑器 一个最大的优点是快速导入word文档的内容,特别 是导入word文档的图文混排效果. 操作步骤: 1.先打开word文档,Crtl +C复制 ,Ctrl+V粘贴到Ue ...

  9. Flutter实战视频-移动电商-57.购物车_在Model中增加选中字段

    57.购物车_在Model中增加选中字段 先修改model类 model/cartInfo.dart类增加是否选中的属性 修改provide 修改UI部分pages/cart_page/cart_it ...

  10. UVa 658 It's not a Bug, it's a Feature! (状态压缩+Dijstra)

    题意:首先给出n和m,表示有n个bug和m个补丁.一开始存在n个bug,用1表示一个bug存在0表示不存在,所以一开始就是n个1,我们的目的是要消除所有的bug, 所以目标状态就是n个0.对于每个补丁 ...