日期:2014-05-20 浏览次数:21133 次
package net.b2bcenter.framework.modules.objectpool; import java.security.NoSuchAlgorithmException; import java.util.Date; import java.util.Map; import net.b2bcenter.entity15.base.IdEntity; import net.b2bcenter.framework.modules.utils.EncodeUtils; import org.apache.log4j.BasicConfigurator; import com.danga.MemCached.MemCachedClient; import com.danga.MemCached.SockIOPool; public class ObjectPool { private boolean enable; private ObjectPoolLogger logger = new ObjectPoolLogger(); public final static int ONE_MINUTE = 60; // 1m public final static int ONE_HOUR = 60 * 60; // 1h public final static int ONE_DAY = 60 * 60 * 24; // 1day public final static int DEFAULT_LIFE = 60 * 60; // 1h private PoolConfig config = new PoolConfig(); private MemCachedClient mcc = null; private String[] servers = {"localhost:11211"}; private synchronized MemCachedClient _init() { return _init(servers); } private synchronized static MemCachedClient _init(String[] servers) { // memcached should be running on port 11211 but NOT on 11212 BasicConfigurator.configure(); SockIOPool pool = SockIOPool.getInstance(); pool.setServers( servers ); pool.setFailover( true ); pool.setInitConn( 10 ); pool.setMinConn( 5 ); pool.setMaxConn( 250 ); 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 ); // Tcp的规则就是在发送一个包之前,本地机器会等待远程主机 // 对上一次发送的包的确认信息到来;这个方法就可以关闭套接字的缓存, // 以至这个包准备好了就发; pool.setNagle( false ); //连接建立后对超时的控制 pool.setSocketTO( 3000 ); //连接建立时对超时的控制 pool.setSocketConnectTO( 0 ); pool.setAliveCheck( true ); pool.initialize(); MemCachedClient mcc = new MemCachedClient(); // turn off most memcached client logging: //Logger.getLogger( MemCachedClient.class.getName() ).setLevel( com.schooner.MemCached.Logger. ); return mcc; } public void setLogFile(String logFile) { this.logger.setLogFile(logFile); } public void setEnable(boolean enable) { this.enable = enable; } public boolean isEnable() { return enable; } public void setLogEnable(boolean logEnable) { this.logger.setEnable(logEnable); } public void setServers(String servers) { this.servers = servers.split(","); } public void init() { mcc = _init(); } public void init(String[] servers) { mcc = _init(servers); } /** * @return true if success */ public boolean set(IdEntity obj) { return set(KeyGenerator.getKey(obj), obj); } /** * @return true if success */ public boolean set(String key, Object value) { if (!enable) { return true; } if (mcc == null) { mcc = _init(); } // value = convert(value); return mcc.set(encodeKey(key), value); } private boolean _set(String key, Object value) { if (!enable) { return true; } if (mcc == null) { mcc = _init(); } return mcc.set(encodeKey(key), value); } /* * @return true if success */ public boolean set(IdEntity obj, int lifeSeconds) { return set(KeyGenerator.getKey(obj), obj, lifeSeconds); } /** * @param lifeSeconds the data will be discard after the given seconds. * @return true if success */ public boolean set(String key, Object value, int lifeSeconds) { if (!enable) { return true; } if (mcc == null) { mcc = _init(); } // value = convert(value); return mcc.set(encodeKey(key), value, new Date(lifeSeconds * 1000)); } public IdEntity get(Class model, Long id) { return (IdEntity)get(KeyGenerator.getKey(model, id)); } public IdEntity[] get(Class model, String[] ids) { String[] keys = new String[ids.length]; for (int i = 0 ; i < ids.length ; i++) { keys[i] = KeyGenerator.getKey(model, new Long(ids[i])); } Object[] values = get(keys); IdEntity[] ret = new IdEntity[values.length]; for (int i = 0 ; i < values.length ; i++) { ret[i] = (IdEntity)values[i]; } return ret; } public Object[] get(String[] keys) { if (!enable) { return null; } if (mcc == null) { mcc = _init(); } for (int i = 0 ; i < keys.length ; i++) { keys[i] = encodeKey(keys[i]); } Map<String, Object> values = mcc.getMulti(keys); Object[] ret = new Object[keys.length]; for (int i = 0 ; i < keys.length ; i++) { ret[i] = values.get(keys[i]); if (ret[i] != null) { // ret[i] = convert(ret[i]); } } return ret; } public Object get(String key) { if (!enable) { return null; } if (mcc == null) { mcc = _init(); } Object value = mcc.get(encodeKey(key)); if (value != null) { // value = convert(value); logger.writeHitLog(key); // System.out.println("Object pool hit: " + key); } else { logger.writeMissedLog(key); // System.out.println("Object pool missed: " + key); } return value; } public void remove(IdEntity obj) { remove(KeyGenerator.getKey(obj), false); } public void remove(IdEntity obj, boolean force) { remove(KeyGenerator.getKey(obj), force); } public void remove(Class model, String id) { remove(model, id, false); } public void remove(Class model, String id, boolean force) { remove(KeyGenerator.getKey(model, new Long(id)), force); } public void remove(String key) { remove(key, false); } public void remove(String key, boolean force) { if (!enable) { return; } if (mcc == null) { mcc = _init(); } String encodedKey = encodeKey(key); Object o = mcc.get(encodedKey); if (o != null) { if (force) { mcc.delete(encodedKey); } else { // 在数据发生改变后,会删掉cache里的值。但这时事务还没提交,数据库里的值还没变,如果有人这时读数据,发现cache里 // 没值就会去数据库读,这样就会产生脏数据。为了避免这种现象,这里延迟1s再删数据以等待事务提交完成,可以降低产生 // 脏数据的可能 mcc.set(encodedKey, o, new Date(1 * 1000)); } } } public boolean isCachable(Class cls) { if (cls.getName().contains("$$")) { cls = cls.getSuperclass(); } return config.isCachable(cls); } public int getLife(Class cls) { return config.getLife(cls); } // key maybe include some char invalid for memcache, so we need to encode it private String encodeKey(String key) { try { java.security.MessageDigest md5 = java.security.MessageDigest.getInstance( "MD5" ); md5.update(key.getBytes()); byte tmp[] = md5.digest(); key = EncodeUtils.base64Encode(tmp); return key; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return key; } } public static void main(String[] args) { long t1 = new Date().getTime(); ObjectPool pool = new ObjectPool(); pool.setEnable(true); pool.set("kkk", "OOOO"); Object o = pool.get("kkk"); System.out.println("o:"+o); // for (int i = 0 ; i < 1000000 ; i++) { // pool.set(""+i, ""+i); // } // // long t2 = new Date().getTime(); // // System.out.println("set time:"+(t2-t1)); // // for (int i = 0 ; i < 1000000 ; i++) { // pool.get(""+i); // } // long t3 = new Date().getTime(); // // System.out.println("set time:"+(t3-t2)); } }