Thrift RPC實戰(五) thrift鏈接池

Thrift自己沒有提供鏈接池,咱們能夠用Apache Commons Pool2來實現一個socket

1、定義對象工廠ide

BasePooledObjectFactory<T> extends BaseObject implements PooledObjectFactory<T>
public class TProtocolFactory extends BasePooledObjectFactory<TProtocol> {

    private String host;
    private  int port;
    private  boolean keepAlive =true;

    public TProtocolFactory(String host, int port, boolean keepAlive) {
        this.host = host;
        this.port = port;
        this.keepAlive = keepAlive;
    }

    /**
     * 建立對象
     * @return
     * @throws Exception
     */
    @Override
    public TProtocol create() throws Exception {
        TSocket socket = new TSocket(host,port);
        //使用 TFramedTransport傳輸
        TTransport tTransport = new TFramedTransport(socket);
        tTransport.open();
        return new TCompactProtocol(tTransport);
    }

    @Override
    public PooledObject<TProtocol> wrap(TProtocol protocol) {
        return new DefaultPooledObject<TProtocol>(protocol);
    }

    /**
     *  對象鈍化(returnObject時觸發)
     * @param pooledObject
     * @throws Exception
     */
    @Override
    public void passivateObject(PooledObject<TProtocol> pooledObject) throws TTransportException {
        if (keepAlive){
            pooledObject.getObject().getTransport().flush();
            pooledObject.getObject().getTransport().close();
        }
    }

    /**
     * 對象激活(borrowObject時觸發)
     * @param pooledObject
     * @throws TTransportException
     */
    @Override
    public void activateObject(PooledObject<TProtocol> pooledObject) throws TTransportException {
        if (!pooledObject.getObject().getTransport().isOpen()){
            pooledObject.getObject().getTransport().open();
        }
    }

    /**
     * 對象銷燬(clear時會觸發)
     * @param pooledObject
     * @throws TTransportException
     */
    @Override
    public void destroyObject(PooledObject<TProtocol> pooledObject) throws TTransportException{
        passivateObject(pooledObject);
        pooledObject.markAbandoned();
    }

    /**
     * 驗證對象有效性
     * @param pooledObject
     * @return
     */
    @Override
    public boolean validateObject(PooledObject<TProtocol> pooledObject){
        if (pooledObject.getObject() != null){
            if (pooledObject.getObject().getTransport().isOpen()){
                return true;
            }
            try {
                pooledObject.getObject().getTransport().open();
                return  true;
            } catch (TTransportException e) {
                e.printStackTrace();
            }
        }
        return false;
    }
}

須要重寫:activateObject(對象激活) 及 passivateObject(對象鈍化)this

2、定義對象池對象

使用GenericObjectPool的默認實現get

public class AutoClearGenericObjectPool<T> extends GenericObjectPool<T>{

    public AutoClearGenericObjectPool(PooledObjectFactory<T> factory) {
        super(factory);
    }

    public AutoClearGenericObjectPool(PooledObjectFactory<T> factory, GenericObjectPoolConfig config) {
        super(factory, config);
    }

    @Override
    public void returnObject(T obj) {
        super.returnObject(obj);
        //空閒數>=激活數時,清理掉空閒鏈接
        if (getNumIdle() >= getNumActive()) {
            clear();
        }
    }
}

common-pools提供了對象池的默認實現:GenericObjectPool 可是該對象池中,對於處於空閒的對象,須要手動調用clear來釋放空閒對象,若是但願改變這一行爲,能夠本身派生本身的子類,重寫returnObject方法,上面的代碼中,每次歸還對象時,若是空閒的對象比激活的對象還要多(即:一半以上的對象都在打醬油),則調用clear方法。io

相關文章
相關標籤/搜索