• 用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/    

  • 相关阅读:
    docker学习笔记(一)-vagrant/docker machine安装docker,阿里云通过docker machine安装docker
    docker安装 centos7
    Robot Framework user guide
    Powershell 备忘
    如何在linux系统内用openssl 生成 过期的证书
    同时装了Python3和Python2,怎么用pip?
    python 基础笔记三
    python 基础笔记二
    python对文件的操作
    3-4 字典的嵌套
  • 原文地址:https://www.cnblogs.com/xingjunli/p/5045155.html
Copyright © 2020-2023  润新知