解决 Memcached的 failed to get SockIO obj for...错误

    技术2025-07-18  9

    今天循环测试从 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 客户端

    最新回复(0)