• memcache实现公共计数器网站


    在反问题的过程中遇到的最近项目。网上查了很多资料并没有完全实现。

    因此,要找到适合自己的xmemcache client和memcache关联API和说明,我们发现了一个比较完美的实现。
    键类:net.rubyeye.xmemcached.Counter
    相关API
    count类API
    实现思路:
    获取:
    获取的时候默认从memcache中获取,初次获取没获得的话载入数据库获取值,并初始化计数器的值。


    更新
    先从memcache中获取计数器的值,没有获取到得的话载入数据库获取值,并初始化计数器的值。


    然后将计数器加1,获取操作后的返回值,假设是100的整数倍就更新到数据库
    下面是关键实现类的代码

    package com.liu.memcache.tools;
    
    import java.io.IOException;
    
    import net.rubyeye.xmemcached.Counter;
    import net.rubyeye.xmemcached.MemcachedClient;
    import net.rubyeye.xmemcached.MemcachedClientBuilder;
    import net.rubyeye.xmemcached.XMemcachedClientBuilder;
    import net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator;
    import net.rubyeye.xmemcached.utils.AddrUtil;
    
    public class MemCachedTools {
        private static final MemCachedTools instance = new MemCachedTools();
    
        /**
         * instance
         * 
         * @return
         */
        public static MemCachedTools getInstance() {
            return instance;
        }
    
        private static String memcached_address = ConfigUtil.getInstance()
                .getString("memcached_address");
        private static String memcached_head=ConfigUtil.getInstance()
        .getString("memcached_head");
    
    
        /**
         * 值添加1
         * @param key
         * @return 
         */
        public long increaseValue(String key){
            long addResult=0;
            String memKey=memcached_head+":"+Md5Hex.getDigestMD5(key);
            try {
                MemcachedClientBuilder builder = new XMemcachedClientBuilder(
                        AddrUtil.getAddresses(memcached_address));
                builder.setSessionLocator(new KetamaMemcachedSessionLocator());
                MemcachedClient memcachedClient = builder.build();
                Counter counter=memcachedClient.getCounter(memKey);
                addResult=counter.incrementAndGet();
    
                try {
                    // close memcached client
                    memcachedClient.shutdown();
                } catch (IOException e) {
                    System.err.println("Shutdown MemcachedClient fail");
                    e.printStackTrace();
                }
    
            } catch (Exception ex) {
                ex.printStackTrace();
                // return ERROR;
            }
            System.out.println("================"+addResult);
            return addResult;
        }
    
        /**
         * 初始化计数器
         * @param key
         * @param defaultValue
         */
        public void initCounter(String key,long defaultValue){
            String memKey=memcached_head+":"+Md5Hex.getDigestMD5(key);
            try {
                MemcachedClientBuilder builder = new XMemcachedClientBuilder(
                        AddrUtil.getAddresses(memcached_address));
                builder.setSessionLocator(new KetamaMemcachedSessionLocator());
                MemcachedClient memcachedClient = builder.build();
                Counter counter=memcachedClient.getCounter(memKey,defaultValue);
                counter.set(defaultValue);
                try {
                    // close memcached client
                    memcachedClient.shutdown();
                } catch (IOException e) {
                    System.err.println("Shutdown MemcachedClient fail");
                    e.printStackTrace();
                }
    
            } catch (Exception ex) {
                ex.printStackTrace();
                // return ERROR;
            }
        }
    
        /**
         * 获取计数器的值
         * @param key
         * @return
         */
        public long getCounterValue(String key){
            String memKey=memcached_head+":"+Md5Hex.getDigestMD5(key);
            long ret=0;
            try {
                MemcachedClientBuilder builder = new XMemcachedClientBuilder(
                        AddrUtil.getAddresses(memcached_address));
                builder.setSessionLocator(new KetamaMemcachedSessionLocator());
                MemcachedClient memcachedClient = builder.build();
                Counter counter=memcachedClient.getCounter(memKey);
                ret= counter.get();
                try {
                    // close memcached client
                    memcachedClient.shutdown();
                } catch (IOException e) {
                    System.err.println("Shutdown MemcachedClient fail");
                    e.printStackTrace();
                }
    
            } catch (Exception ex) {
                ex.printStackTrace();
                // return ERROR;
            }
            return ret;
        }
    
    }
    

    操作计数器实现类

    package com.liu.counter;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    
    import com.liu.memcache.tools.MemCachedTools;
    
    /**
     * @author chao.liu
     * @date 2015-03-06
     * 
     */
    public class CounterService {
        protected Log log = LogFactory.getLog(getClass());
    
        public long getStatisticsData() {
            String memKey = "count";
            Long count = null;
            try {
                count = (Long) MemCachedTools.getInstance().getCounterValue(memKey);
            } catch (Exception e) {
            }
            if (count == 0) {
                try {
                    // TODO:从数据库载入,此处省略
                    count = 120L;
                } catch (Exception e) {
                }
                MemCachedTools.getInstance().initCounter(memKey, count);
            } else {
                // TODO:输出到前台的处理
                log.info("StatisticsService.getStatisticsData  get data to memcached ...............");
            }
            return count;
        }
    
        /**
         * 更新统计数据
         * 
         * @param channelID
         * @param moduleID
         * @return
         */
        public String updateStatisticsData() {
            String memKey = "count";
            String res = "1";
            Long count = null;
            try {
                count = (Long) MemCachedTools.getInstance().getCounterValue(memKey);
            } catch (Exception e) {
            }
            if (count == 0) {// 空的时候从数据库载入
                // TODO:从数据库载入,此处省略
                count = 120L;
                MemCachedTools.getInstance().initCounter(memKey, count);
            }
            long addRes = MemCachedTools.getInstance().increaseValue(memKey);
            try {
                if (addRes != 0) {
                    if (addRes % 100 == 0) {
                        // 每100条更新到数据库一次
                        // update to DB operation
                    }
                }
            } catch (Exception e) {
                res = "0";
            }
            return res;
        }
    
        public static void main(String[] args) {
            CounterService ss=new CounterService();
            System.out.println("当前计数条数是:"+ss.getStatisticsData());
            ss.updateStatisticsData();
            System.out.println("加1后计数条数是:"+ss.getStatisticsData());
        }
    }
    

    执行效果:
    当前计数条数是:123
    ================124
    加1后计数条数是:124

    代码下载:
    http://download.csdn.net/detail/shanhuhau/8508929

    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    About Face 摘录
    断言的使用
    C#中值传递和引用传递
    C++技巧之断言Assert
    About Face 一 目标导向设计
    About Face 二 设计行为与形态
    C++中引用传递与指针传递区别
    一个新的时代SoLoMo
    离散数学笔记算法部分
    汪教授的离散数学20110308 谓词与量词2
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4891430.html
Copyright © 2020-2023  润新知