wealoha thrift-client-pool 总结

DefaultEvictionPolicy类是EvictionPolicy接口的实现主要描述,pool中那些idel对象会被Evict,回收。
关键代码如下:
public boolean evict(EvictionConfig config, PooledObject<T> underTest,
            int idleCount) {

        if ((config.getIdleSoftEvictTime() < underTest.getIdleTimeMillis() &&
                config.getMinIdle() < idleCount) ||
                config.getIdleEvictTime() < underTest.getIdleTimeMillis()) {
            return true;
        }
        return false;
    }

ObjectPool 接口:

Object obj = null
try{
  obj = pool.borrowObject();
  try{
    //...use the object...
    }catch(Exception e) {
      pool.invalidateObject(obj);// invalidate the object
      // do not return the object to the pool twice
      obj = null
    }finally{
      // make sure the object is returned to the pool
      if(null!= obj) pool.returnObject(obj);
    } 
}
catch(Exception e) { // failed to borrow an object }
PooledObjectState 定义池对象的所有可能状态:
public enum PooledObjectState {
    /**
     * In the queue, not in use.
     */
    IDLE,

    /**
     * In use.
     */
    ALLOCATED,

    /**
     * In the queue, currently being tested for possible eviction.
     */
    EVICTION,

    /**
     * Not in the queue, currently being tested for possible eviction. An
     * attempt to borrow the object was made while being tested which removed it
     * from the queue. It should be returned to the head of the queue once
     * eviction testing completes.
     * TODO: Consider allocating object and ignoring the result of the eviction
     *       test.
     */
    EVICTION_RETURN_TO_HEAD,

    /**
     * In the queue, currently being validated.
     */
    VALIDATION,

    /**
     * Not in queue, currently being validated. The object was borrowed while
     * being validated and since testOnBorrow was configured, it was removed
     * from the queue and pre-allocated. It should be allocated once validation
     * completes.
     */
    VALIDATION_PREALLOCATED,

    /**
     * Not in queue, currently being validated. An attempt to borrow the object
     * was made while previously being tested for eviction which removed it from
     * the queue. It should be returned to the head of the queue once validation
     * completes.
     */
    VALIDATION_RETURN_TO_HEAD,

    /**
     * Failed maintenance (e.g. eviction test or validation) and will be / has
     * been destroyed
     */
    INVALID,

    /**
     * Deemed abandoned, to be invalidated.
     */
    ABANDONED,

    /**
     * Returning to the pool.
     */
    RETURNING
}
View Code

ThriftClientPool 类剖析:

  • 设置配置
    • TestOnReturn= true
    • TestOnBorrow=true
  • GenericObjectPool对象池构建:关键代码如下:
  • new GenericObjectPool<>(new BasePooledObjectFactory<ThriftClient<T>>() {
    
                @Override
                public ThriftClient<T> create() throws Exception {
    
                    // get from global list first
                    List<ServiceInfo> serviceList = ThriftClientPool.this.services;
                    ServiceInfo serviceInfo = getRandomService(serviceList);
                    TTransport transport = getTransport(serviceInfo);
    
                    try {
                        transport.open();
                    } catch (TTransportException e) {
                        logger.info("transport open fail service: host={}, port={}",
                                serviceInfo.getHost(), serviceInfo.getPort());
                        if (poolConfig.isFailover()) {
                            while (true) {
                                try {
                                    // mark current fail and try next, until none service available
                                    serviceList = removeFailService(serviceList, serviceInfo);
                                    serviceInfo = getRandomService(serviceList);
                                    transport = getTransport(serviceInfo); // while break here
                                    logger.info("failover to next service host={}, port={}",
                                            serviceInfo.getHost(), serviceInfo.getPort());
                                    transport.open();
                                    break;
                                } catch (TTransportException e2) {
                                    logger.warn("failover fail, services left: {}", serviceList.size());
                                }
                            }
                        } else {
                            throw new ConnectionFailException("host=" + serviceInfo.getHost() + ", ip="
                                    + serviceInfo.getPort(), e);
                        }
                    }
    
                    ThriftClient<T> client = new ThriftClient<>(clientFactory.createClient(transport),
                            pool, serviceInfo);
    
                    logger.debug("create new object for pool {}", client);
                    return client;
                }
    
                @Override
                public PooledObject<ThriftClient<T>> wrap(ThriftClient<T> obj) {
                    return new DefaultPooledObject<>(obj);
                }
    
                @Override
                public boolean validateObject(PooledObject<ThriftClient<T>> p) {
                    ThriftClient<T> client = p.getObject();
    
                    // check if return client in current service list if 
                    if (serviceReset) {
                        if (!ThriftClientPool.this.services.contains(client.getServiceInfo())) {
                            logger.warn("not return object cuase it's from previous config {}", client);
                            client.closeClient();
                            return false;
                        }
                    }
    
                    return super.validateObject(p);
                }
    
                @Override
                public void destroyObject(PooledObject<ThriftClient<T>> p) throws Exception {
                    p.getObject().closeClient();
                    super.destroyObject(p);
                }
            }
    View Code
     X iface 返回TServiceClient的代理对象关键代码如下:可以看到首先从池中借对象,然后生成TServiceClient的代理对象,代理handler主要实际执行thrift方法,成功时归还到池,失败时需要关闭TServiceClient,并在池中invalidateObject(ThriftClient)
    • View Code

UML类关系图:

posted on 2017-11-20 00:12  踏雪扬尘-wx  阅读(690)  评论(0编辑  收藏  举报