Tomcat集群下获取memcached缓存对象数量,统计在线用户数据量

项目需要统计在线用户数量,系统部署在集群环境下,使用会话粘贴的方式解决Session问题。要想得到真实在线用户数,必须是所有节点的总和。
这里考虑使用memcached存放用户登录数据,key为userid统计在线用户数据,只需要统计key的总数。memcached因为性能的缘故,
没有提供遍历整个缓存当中对象的功能,不过memcached也提供了很多命令来监控memcached的状态,例如stats命令就有:

Java代码  收藏代码
  1. stats    
  2. stats reset    
  3. stats malloc    
  4. stats maps    
  5. stats sizes    
  6. stats slabs    
  7. stats items    
  8. stats cachedump slab_id limit_num    
  9. stats detail [on|off|dump]    



使用命令【stats items】查询查询到所有的slab,再使用命令【cachedump 1 0】命令找出所有的Key信息。但过期的key也会被查询出来,所以需要对all keys执行一遍查询,过滤掉过期的key。也可以通过【cachedump 1 0】命令查询出来的key过期时间与当前时间进行比较。判断是否过期。这里的过期时间为 session.getMaxInactiveInterval()的值。

Java代码  收藏代码
    Iterator<Map<String, String>> iterSlabs = client.getStats("items").values().iterator();  
    Set<String> set = new HashSet<String>();  
    while(iterSlabs.hasNext()) {  
        Map<String, String> slab = iterSlabs.next();  
        for(String key : slab.keySet()) {  
            String index = key.split(":")[1];  
            set.add(index);  
        }  
    }  
      
    //统计  
    List<String> list = new LinkedList<String>();  
    for(String v : set) {  
        String commond = "cachedump ".concat(v).concat(" 0");  
        Iterator<Map<String, String>> iterItems = client.getStats(commond).values().iterator();  
        while(iterItems.hasNext()) {  
            Map<String, String> items = iterItems.next();  
            list.addAll(items.keySet());  
        }  
    }  
      
    return client.getBulk(list);  

 



接下来说说,用户信息怎么放入memcached中。主要利用HttpSessionListener和HttpSessionAttributeListener来监听对Session的操作。
不多写了,贴上代码就很清楚了:

Java代码  收藏代码
        HttpSessionAttributeListener:  
        public void attributeReplaced(HttpSessionBindingEvent event) {  
            HttpSession session = event.getSession();  
            if(SESSION_KEY.endsWith(event.getName())) {  
                MemcachedClient client = (MemcachedClient)SpringBeanHolder.getBean(MEMCACEHD_BEAN_NAME);  
                SessionContext context = (SessionContext)session.getAttribute(SESSION_KEY);  
                  
                String username = "";  
                try {  
                    username = context.getDocument().getElementsByTagName("operatorName").item(0).getFirstChild().getNodeValue();  
                      
                    String json = "{username: '"+username+"'}";  
                    client.set(context.getUserID(), session.getMaxInactiveInterval(), json);  
                } catch (Exception e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
          
        public class UserSessionListener implements HttpSessionListener {   
            private static final String SESSION_KEY = "sessionContext";  
            private static final String MEMCACEHD_BEAN_NAME = "memcachedClient";   
          
            public void sessionCreated(HttpSessionEvent event) {   
            }   
          
            public void sessionDestroyed(HttpSessionEvent event) {   
                HttpSession session = event.getSession();   
                MemcachedClient client = (MemcachedClient)SpringBeanHolder.getBean(MEMCACEHD_BEAN_NAME);  
                  
                SessionContext context = (SessionContext)session.getAttribute(SESSION_KEY);  
                System.out.println("【Destroy Session】 User:"+context.getUserID());  
                  
                //删除对应用户在memcached的数据  
                client.delete(context.getUserID());  
            }  
          
        } 

 

posted @ 2014-11-11 17:50  锐洋智能  阅读(1279)  评论(0编辑  收藏  举报