Package org.dayatang.cache.memcached

Source Code of org.dayatang.cache.memcached.MemcachedBasedCache

package org.dayatang.cache.memcached;

import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;

import org.apache.commons.lang3.StringUtils;
import org.dayatang.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.Set;

/**
* 基于Memcached的缓存实现
*
* @author chencao
*
*/
public class MemcachedBasedCache implements Cache {

  private static final Logger LOGGER = LoggerFactory
      .getLogger(MemcachedBasedCache.class);

  private MemCachedClient mcc;

  private String[] servers;

  private int initConn = 100;

  private int minConn = 100;

  private int maxConn = 250;

  private int connectTimeout = 3000;

  private String poolName;

  private boolean initialized = false;

  public Object get(String key) {
    init();
    Object obj = mcc.get(key);
    debug("命中缓存:{},key:{}", new Object[] { (obj != null), key });
    return obj;
  }

  @Override
  public Map<String, Object> get(String... keys) {
    init();
    Map<String, Object> map = mcc.getMulti(keys);
    return map;
  }

  public boolean containsKey(String key) {
    init();
    return mcc.keyExists(key);
  }

  public void put(String key, Object value) {
    init();
    mcc.set(key, value);
    debug("缓存数据,key:{}", key);
  }

  public void put(String key, Object value, Date expiry) {
    init();
    mcc.set(key, value, expiry);
    debug("缓存数据,key:{},过期日期:{}", key, expiry);
  }

  public void put(String key, Object value, long living) {
    init();
    Date now = new Date();
    Date expiry = new Date(now.getTime() + living);
    put(key, value, expiry);
  }

  public boolean remove(String key) {
    init();
    boolean result = mcc.delete(key);
    debug("删除缓存,key:{}", key);
    return result;
  }

  @SuppressWarnings("rawtypes")
  protected void prepareClient() {

    // grab an instance of our connection pool
    SockIOPool pool = null;
    if (StringUtils.isBlank(getPoolName())) {
      pool = SockIOPool.getInstance();
      mcc = new MemCachedClient();
    } else {
      pool = SockIOPool.getInstance(getPoolName());
      mcc = new MemCachedClient(getPoolName());
    }

    // Integer[] weights = { 5, 1 };

    // set the servers and the weights
    pool.setServers(servers);
    // pool.setWeights(weights);

    // set some basic pool settings
    // 5 initial, 5 min, and 250 max conns
    // and set the max idle time for a conn
    // to 6 hours
    pool.setInitConn(getInitConn());
    pool.setMinConn(getMinConn());
    pool.setMaxConn(getMaxConn());
    pool.setMaxIdle(1000 * 60 * 60 * 6);

    // set the sleep for the maint thread
    // it will wake up every x seconds and
    // maintain the pool size
    pool.setMaintSleep(30);
//    pool.setBufferSize(1024);

    // set some TCP settings
    // disable nagle
    // set the read timeout to 3 secs
    // and don't set a connect timeout
    pool.setNagle(false);
    pool.setSocketTO(3000);
    pool.setSocketConnectTO(getConnectTimeout());

    // initialize the connection pool
    pool.initialize();

    // lets set some compression on for the client
    // compress anything larger than 64k
    // mcc.setCompressEnable(true);
    // mcc.setCompressThreshold(64 * 1024);

    Map map = mcc.stats(servers);
    Set keys = map.keySet();
    if (keys.size() == 0) {
      error("客户端创建遇到错误,无法创建。");
    }
    for (Object key : keys) {
      // logger.info("客户端创建完成。key = 【{}】, status = 【{}】", key, map
      // .get(key));
      info("客户端创建完成。key = 【{}】", key);
    }

  }

  public String[] getServers() {
    return servers;
  }

  public void setServers(String... servers) {
    this.servers = Arrays.copyOf(servers, servers.length);
  }

  /**
   * 获取初始化连接数
   *
   * @return 初始化连接数
   */
  public int getInitConn() {
    return initConn;
  }

  /**
   * 设置初始化连接数
   *
   * @param initConn
   *            初始化连接数
   */
  public void setInitConn(int initConn) {
    this.initConn = initConn;
  }

  /**
   * 获取最小连接数
   *
   * @return 最小连接数
   */
  public int getMinConn() {
    return minConn;
  }

  /**
   * 设置最小连接数
   *
   * @param minConn
   *            最小连接数
   */
  public void setMinConn(int minConn) {
    this.minConn = minConn;
  }

  /**
   * 获取最大连接数
   *
   * @return 最大连接数
   */
  public int getMaxConn() {
    return maxConn;
  }

  /**
   * 设置最大连接数
   *
   * @param maxConn
   *            最大连接数
   */
  public void setMaxConn(int maxConn) {
    this.maxConn = maxConn;
  }

  /**
   * 获取连接超时时间(毫秒)
   *
   * @return 连接超时时间(毫秒)
   */
  public int getConnectTimeout() {
    return connectTimeout;
  }

  /**
   * 设置连接超时时间(毫秒)
   *
   * @param connectTimeout
   *            连接超时时间(毫秒)
   */
  public void setConnectTimeout(int connectTimeout) {
    this.connectTimeout = connectTimeout;
  }

  /**
   * 获取socket pool名称
   *
   * @return socket pool名称
   */
  public String getPoolName() {
    return poolName;
  }

  /**
   * 设置socket pool名称
   *
   * @param poolName
   *            socket pool名称
   */
  public void setPoolName(String poolName) {
    this.poolName = poolName;
  }

  public void init() {

    if (initialized) {
      return;
    }
    if (servers == null || servers.length == 0) {
      throw new IllegalStateException("Must assign memcached server address");
    }

    for (String server : servers) {
      info("准备为Memcached服务器{}创建客户端...", server);
      info("最小连接数为:{}", minConn);
      info("最大接数为:{}", maxConn);
      info("初始化连接数为:{}", initConn);
      info("连接超时时间为:{}毫秒", connectTimeout);
    }
    prepareClient();
    // if (logger.isDebugEnabled()) {
    // logger.debug("客户端创建完成。...");
    // }
    initialized = true;

  }

  private void debug(String message, Object... params) {
    if (LOGGER.isDebugEnabled()) {
      LOGGER.debug(message, params);
    }
  }

  private void info(String message, Object... params) {
    if (LOGGER.isInfoEnabled()) {
      LOGGER.info(message, params);
    }
  }

  private void error(String message, Object... params) {
    if (LOGGER.isErrorEnabled()) {
      LOGGER.error(message, params);
    }
  }

}
TOP

Related Classes of org.dayatang.cache.memcached.MemcachedBasedCache

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.