zoukankan      html  css  js  c++  java
  • redis-缓存设计-记录前一个小时和最新的日志

    需求

    记录最新的日志 99条

    同时记录上一个小时和最近一个小时的 日志出现次数

    记录日志代码

     /**
         *
         * @param conn 连接
         * @param name 模块名字
         * @param message 日志信息
         * @param level 日志等级
         * @param timeout 重试时间
         */
        public static void logCommon(
                Jedis conn, String name, String message, String level, int timeout,Date date) {
            //日志出现数量的key
            String commonDest = "common:" + name + ':' + level;
            //记录当前所处小时数
            String startKey = commonDest + ":start";
            //上一次所属小时数
            String  pstartkey= commonDest + ":pstart";
            //计算重试后时间
            long end = System.currentTimeMillis() + timeout;
            //获得当前所处小时数
            String existing = conn.get(startKey);
            //yyyy-mm-dd  HH:00:00
            String hourStart = ISO_FORMAT.format(date);
            //是否需要重试
            while (System.currentTimeMillis() < end) {
                //对当前所处小时数进行监视 避免其他地方在下一小时切换 比如多线程调用
                conn.watch(startKey);
    
                Transaction trans = conn.multi();
                //表示第一次运行 进行初始化
                if (existing == null) {
                    //保存当前最新小时数
                    trans.set(startKey, hourStart);
                    existing=hourStart;
                }
                //如果是下一个小时了 将原来的日志的key重新命名
                if (existing != null && COLLATOR.compare(existing, hourStart) < 0) {
                    //通过重命名记录当前记录的key 归档到上一个小时
                    trans.rename(commonDest, pstartkey);
                    //记录最新的小时数
                    trans.set(startKey, hourStart);
                }
    
                //记录日志出现次数 对日志出现数进行+1  这里只是记录日志出现次数
                trans.zincrby("common:" + name + ':' + level,1,message);
                //存储日志
                String recentDest = "recent:" + name + ':' + level;
                //消息追加到队列
                trans.lpush(recentDest,  message);
                //只保留0-99条
                trans.ltrim(recentDest, 0, 99);
                List<Object> results = trans.exec();
                // null response indicates that the transaction was aborted due to
                // the watched key changing.
                if (results == null) {
                    continue;
                }
                return;
            }
        }

    返回上一次或者下一次日志

     /**
         * 打印日志信息
         * @param conn 连接
         * @param type top为上一次  current为当前
         */
        public static void printLog(Jedis conn,String name, String level,String type){
            String hourStart=null;
            String commonDest = "common:" + name + ':' + level;
            if(type=="top"){
                commonDest=commonDest+":pstart";
            }
            Set<Tuple> common = conn.zrevrangeWithScores(commonDest, 0, -1);
            for (Tuple tuple : common) {
                System.out.println("消息:  " + tuple.getElement() + ",出现次数 " + tuple.getScore());
            }
        }

    测试

     public static final Collator COLLATOR = Collator.getInstance();
    
        /**
         * 用于比较是否是上一小时了
         */
        public static final SimpleDateFormat TIMESTAMP =
                new SimpleDateFormat("EEE MMM dd HH:00:00 yyyy");
        /**
         * 用于格式化为yyyy-MM-dd hh:00:00
         */
        private static final SimpleDateFormat ISO_FORMAT =
                new SimpleDateFormat("yyyy-MM-dd'T'HH:00:00");
        static {
            ISO_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
        }
    
        public static void main(String[] args)
                throws Exception {
            Jedis conn = new Jedis("127.0.0.1", 6379);
            conn.flushDB();
            //录入100条日志信息
            for(int i=0;i<10;i++){
                logCommon(conn,"促销","前一个小时测试嗷嗷"+i,"info",2000,new Date());
            }
            //模拟切换到下一小时i
            Calendar calendar=Calendar.getInstance();
            calendar.setTime(new Date());
            //追加一个小时
            calendar.add(Calendar.HOUR,1);
            for(int i=0;i<3;i++){
                logCommon(conn,"促销","当前一个小时测试嗷嗷"+i,"info",2000,calendar.getTime());
                //测试重复消息
                logCommon(conn,"促销","我是重复数据"+i,"info",2000,calendar.getTime());
                //
                logCommon(conn,"促销","我是重复数据"+i,"info",2000,calendar.getTime());
            }
            //===================获得前一个小时的日志信息====================
            System.out.println("获得前一个小时的日志信息");
            printLog(conn,"促销","info","top");
            //===================获取当前的日志新====================
            System.out.println("获得当前最新的日志信息");
            printLog(conn,"促销","info","current");
    
        }

    打印

    得前一个小时的日志信息
    消息:  前一个小时测试嗷嗷9,出现次数 1.0
    消息:  前一个小时测试嗷嗷8,出现次数 1.0
    消息:  前一个小时测试嗷嗷7,出现次数 1.0
    消息:  前一个小时测试嗷嗷6,出现次数 1.0
    消息:  前一个小时测试嗷嗷5,出现次数 1.0
    消息:  前一个小时测试嗷嗷4,出现次数 1.0
    消息:  前一个小时测试嗷嗷3,出现次数 1.0
    消息:  前一个小时测试嗷嗷2,出现次数 1.0
    消息:  前一个小时测试嗷嗷1,出现次数 1.0
    消息:  前一个小时测试嗷嗷0,出现次数 1.0
    获得当前最新的日志信息
    消息:  我是重复数据2,出现次数 2.0
    消息:  我是重复数据1,出现次数 2.0
    消息:  我是重复数据0,出现次数 2.0
    消息:  当前一个小时测试嗷嗷2,出现次数 1.0
    消息:  当前一个小时测试嗷嗷1,出现次数 1.0
    消息:  当前一个小时测试嗷嗷0,出现次数 1.0
  • 相关阅读:
    BigDecimal精确到几位以及四舍五入
    IDEA配置
    IDEA配置
    IntelliJ IDEA 2018.3.3配置 Tomcat 9,控制台出现中文乱码 “淇℃伅”
    JSP九大内置对象详解
    面试题
    配置编码格式
    SpringAop注解(增强)异常
    springmvc异常
    android保持Session会话
  • 原文地址:https://www.cnblogs.com/LQBlog/p/13323983.html
Copyright © 2011-2022 走看看