/** * Copyright (c) 2005-2010 springside.org.cn * * Licensed under the Apache License, Version 2.0 (the "License"); * * $Id: SpyTokyotyrantClientPool.java 1211 2010-09-10 16:20:45Z calvinxiu $ */ package org.springside.modules.tokyotyrant; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Random; import net.spy.memcached.AddrUtil; import net.spy.memcached.ConnectionFactoryBuilder; import net.spy.memcached.FailureMode; import net.spy.memcached.HashAlgorithm; import net.spy.memcached.MemcachedClient; import net.spy.memcached.ConnectionFactoryBuilder.Locator; import net.spy.memcached.ConnectionFactoryBuilder.Protocol; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; /** * 对SpyMemcached Client的二次封装. * * 1.建立SpyMemcached Client池,负责初始化与关闭. * 2.提供常用的Get/GetBulk/Set/Delete/Incr/Decr函数的封装. * * 未提供封装的函数可直接调用getClient()取出Spy的原版MemcachedClient来使用. * * @author calvin */ public class SpyTokyotyrantClientPool implements InitializingBean, DisposableBean { private static Logger logger = LoggerFactory.getLogger(SpyTokyotyrantClientPool.class); private List<SpyTokyotyrantClient> clientPool; private int poolSize = 1; private Random random = new Random(); private String memcachedNodes = "localhost:11211"; private boolean isConsistentHashing = false; private long operationTimeout = 1000; //default value in Spy is 1000ms @Override public void afterPropertiesSet() throws Exception { clientPool = new ArrayList<SpyTokyotyrantClient>(poolSize); for (int i = 0; i < poolSize; i++) { ConnectionFactoryBuilder cfb = new ConnectionFactoryBuilder(); cfb.setFailureMode(FailureMode.Redistribute); cfb.setDaemon(true); cfb.setProtocol(Protocol.TEXT); if (isConsistentHashing) { cfb.setLocatorType(Locator.CONSISTENT); cfb.setHashAlg(HashAlgorithm.KETAMA_HASH); } cfb.setOpTimeout(operationTimeout); try { MemcachedClient spyClient = new MemcachedClient(cfb.build(), AddrUtil.getAddresses(memcachedNodes)); clientPool.add(new SpyTokyotyrantClient(spyClient)); } catch (IOException e) { logger.error("MemcachedClient initilization error: ", e); throw e; } } } @Override public void destroy() throws Exception { for (SpyTokyotyrantClient spyClient : clientPool) { if (spyClient != null) { spyClient.getMemcachedClient().shutdown(); } } } /** * 随机取出Pool中的SpyMemcached Client. */ public SpyTokyotyrantClient getClient() { return clientPool.get(random.nextInt(poolSize)); } public void setPoolSize(int poolSize) { this.poolSize = poolSize; } /** * 支持多节点, 以","分割. * eg. "localhost:11211,localhost:11212" */ public void setMemcachedNodes(String memcachedNodes) { this.memcachedNodes = memcachedNodes; } public void setConsistentHashing(boolean isConsistentHashing) { this.isConsistentHashing = isConsistentHashing; } public void setOperationTimeout(long operationTimeout) { this.operationTimeout = operationTimeout; } }