zoukankan      html  css  js  c++  java
  • redis-缓存设计-用户会话、浏览记录、购物车(二)

    需求

    token校验,以及用户最近访问商品,同时加入购物车和移除购物车

    因为cookie是空间有限制,所以可以通过cookie存一个key 如token 每次请求传递到服务端 通过token找到当前用户对应的访问空间

    获取token信息

    代码

        /**
         * 用户信息json
         *
         * @param conn
         * @param token 客户端传来的token
         * @return
         */
        public static String check_token(Jedis conn, String token) {
            return conn.hget("login:", token);
        }

    新增token更新访问记录

    代码

        /**
         * @param conn
         * @param token       客户端token
         * @param userJson    用户信息json
         * @param productItem 浏览产品
         */
        public static void update_token(Jedis conn, String token, String userJson, String productItem) {
            Long updateTime = System.currentTimeMillis();
            conn.hset("login:", token, userJson);
            //用于快速查出失效token updateTime可以设置成token失效时间
            conn.zadd("recent:", updateTime, token);
            //是否更新商品
            if (productItem != null) {
                //保存最近浏览商品
                conn.zadd("viewed:" + token, updateTime, productItem);
                //只保存最近的25个
                conn.zremrangeByRank("viewed:" + token, 0, -26);
            }
    
        }

    每次保存商品都会删除排名为25以后的商品 减少数量

    数据结构

    加入购物车

    代码

      /**
         * 将商品添加购物车
         * @param conn
         * @param token
         * @param productId
         * @param count
         */
        public void  add_to_card(Jedis conn,String token,String productId,Integer count){
            //用户购买数量设置为0 则从购物车移除
            if(count<=0){
                conn.hdel(String.format("card:%s",token),productId);
            }else{
                //添加到购物车
                conn.hset(String.format("card:%s",token),productId,count.toString());
            }
        }

    剔除失效的token

    类似处理 多久未访问 需要重新登录需求 也是节约内存清除无用数据  我现在是按日清除 也可以清楚30分钟以前的

    代码

        /**
         * 只保留当日token 其他的清除
         * 可以弄成定时任务
         */
        public static void clear(Jedis conn) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        final Calendar monthStar = Calendar.getInstance();
                        monthStar.set(Calendar.MINUTE, 0);
                        monthStar.set(Calendar.SECOND, 0);
                        monthStar.set(Calendar.MILLISECOND, 0);
                        monthStar.set(Calendar.DATE, 1);
                        //每次处理1000条
                        Set<String> keys = conn.zrangeByScore("recent:", String.valueOf(0), String.valueOf(monthStar.getTime().getTime()));
                        if (keys == null || keys.size() <= 0) {
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        } else {
                            String[] keysArr = keys.toArray(new String[keys.size()]);
                            //删除会话信息
                            conn.hdel("login:", keysArr);
                            //从最近访问里面删除
                            conn.zrem("recent:", keysArr);
                            //删除访问记录
                            List<String> viewedKeys = keys.stream().map(c -> "viewed:" + c).collect(Collectors.toList());
                            conn.del(viewedKeys.toArray(new String[viewedKeys.size()]));
                            //删除购物车
                            List<String> cardKeys = keys.stream().map(c -> "card:" + c).collect(Collectors.toList());
                            conn.del(viewedKeys.toArray(new String[cardKeys.size()]));
                        }
                    }
                }
            }).start();
        }

    测试hset时间复杂度

    代码

    /**
         * 测试写了和读500000个都是0毫秒有时1毫秒
         * @param conn
         */
        public static void testHset(Jedis conn) {
            for (int i = 0; i < 5000000; i++) {
                Long start = System.currentTimeMillis();
                conn.hset("hkey", "test"+i, "test2");
                Long end = System.currentTimeMillis();
                System.out.println("写耗时" + (end - start) + "毫秒");
                start = System.currentTimeMillis();
                conn.hget("hkey", "test");
                end = System.currentTimeMillis();
                System.out.println("读耗时" + (end - start) + "毫秒");
            }
    
        }
  • 相关阅读:
    WeakReference(弱引用)
    男人怎么挑选女人
    同步方法和异步方法
    常指针与指针常量的区别(转帖)
    关于WebService的一些注意事项
    ASP.Net缓存技术
    关于GridView手动绑定的一段代码,一切尽在不言中
    基本三层架构的一些代码
    写给自己看的关于DataList的和RePeater
    ASP.Net绑定数据源
  • 原文地址:https://www.cnblogs.com/LQBlog/p/13274606.html
Copyright © 2011-2022 走看看