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) + "毫秒");
        }

    }
复制代码

 

posted @   意犹未尽  阅读(550)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示