今天循环测试从 Memcached 中取数据的性能问题、发现到3000多次就报空指针错误了(Linux 下更惨不到200次就错了)、
搜索了一下这个错误、再结合源码和本地的代码看了下、是因为取数据的时候 连接池的 Socket 连不上了、现在把改过前和改过后的代码贴出、希望大家用的上、
一、改过前:
public static String getMemcachedByKey(String key,String Server,int ind) { String tmpContentStr = null; String[] servers = {Server}; Integer[] weights = {3}; Calendar calendar = Calendar.getInstance();//当前日期 calendar.setTime(new Date()); calendar.add(Calendar.HOUR, 8);//1个小时后 // 获取socke连接池的实例对象 SockIOPool pool = SockIOPool.getInstance("Server"+ind);
// 设置服务器信息 pool.setServers( servers ); pool.setWeights( weights );
// 设置初始连接数、最小和最大连接数以及最大处理时间 pool.setInitConn( 5 ); pool.setMinConn( 5 ); pool.setMaxConn( 250 ); pool.setMaxIdle( 1000 * 60 * 60 * 6 );
// 设置主线程的睡眠时间 pool.setMaintSleep( 30 );
// 设置TCP的参数,连接超时等 pool.setNagle( false ); pool.setSocketTO( 3000 ); pool.setSocketConnectTO( 0 ); // 初始化连接池 pool.initialize(); MemCachedClient mcc = new MemCachedClient("Server"+ind); // 压缩设置,超过指定大小(单位为K)的数据都会被压缩 mcc.setCompressEnable( true ); mcc.setCompressThreshold( 64 * 1024 ); Object obj = null; try{ tmpContentStr = mcc.get(key).toString(); //obj = mcc.get(key); }catch(Exception ex){ } return tmpContentStr; }
上面那个代码还是跟官方网站上提供的一致的呢 真蛋疼
二、改进后(分成2部分)
public static SockIOPool pool = null; public static SockIOPool getPool(int ind,String[] servers,Integer[] weights){ if(pool !=null){ return pool; }else{ // 获取socke连接池的实例对象 pool = SockIOPool.getInstance("Server"+ind); // 设置服务器信息 pool.setServers( servers ); pool.setWeights( weights );
// 设置初始连接数、最小和最大连接数以及最大处理时间 pool.setInitConn( 5 ); pool.setMinConn( 5 ); pool.setMaxConn( 250 ); pool.setMaxIdle( 1000 * 60 * 60 * 6 );
// 设置主线程的睡眠时间 pool.setMaintSleep( 30 );
// 设置TCP的参数,连接超时等 pool.setNagle( false ); pool.setSocketTO( 3000 );//设置读取超时为3秒 pool.setSocketConnectTO( 0 );//0表示不设置连接超时
// 初始化连接池 pool.initialize(); return pool; } }
public static Object getMemcachedByKey(String key,String Server,int ind) { String tmpContentStr = null; String[] servers = {Server}; Integer[] weights = {3}; Calendar calendar = Calendar.getInstance();//当前日期 calendar.setTime(new Date()); calendar.add(Calendar.HOUR, 8);//1个小时后 getPool(ind,servers,weights);//调用连接池对象 MemCachedClient mcc = new MemCachedClient("Server"+ind); // 压缩设置,超过指定大小(单位为K)的数据都会被压缩 mcc.setCompressEnable( true ); mcc.setCompressThreshold( 64 * 1024 ); mcc.setDefaultEncoding("ISO-8859-1");//更改默认编码集 取压缩内容这步很关键 mcc.setSanitizeKeys(false); //取值设置不对key做编码 Object obj = null; try{ obj = mcc.get(key,null,true);//这步很关键 //obj = mcc.get(key); }catch(Exception ex){ System.out.println("错误了............."); ex.printStackTrace(); } return obj; }
对比下 主要就是在改进后创建一个全局的连接池对象、这样就不用每次取数据的时候都实例一个对象了、而且速度也提高了不少
以上均使用 com.danga.MemCached.MemCachedClient 客户端