• 使用定时任务发布文章的流程


    有3个定时任务:
    A:每秒执行一次消费延迟队列(以topic_命名开头,以list存储的redis)数据,审核文章,存入article数据库中发布成功。
    B:每分钟执行一次未来数据(以future_命名开头,以set存储的redis)定时刷新。(这个刷新就是把未来数据变成延迟队列的数据)
    C:每5分种执行将数据库5分钟之内会被执行的数据同步到缓存。同步后为未来数据。

    ps:只有审核通过,也就是被A执行的文章才能被发布
    发布一个文章:
    先把文章基本信息存入到news数据库。判断发布时间是否在5分钟以内或者更早,
    如果是:直接存入消费延迟队列和tesk数据库,被A消费审核后删除有关的数据。
    如果不是:只存tesk数据库,每5分钟给一次触发C的机会,如果触发成功将会有触发B的机会,成功后就能触发A。

    总结:

    • 这里把5分钟以内的数据认定为近期可能执行的任务,这个时间不能太大,比如10天,那么近10天的数据都会被存入到redis中,很浪费资源。也不能太小,比如1秒,那么就每秒都需要往数据库里找数据看看它们是否符合要求,更浪费资源。
    • 关于B和C分级主要还是为了资源的充分利用,list和set在redis中的效率是差别很大的,在服务集群的时候,不同的C可以随便的向redis中存数据,所以B需要更短的频率取C处理好的数据。同时也造成了一个问题就是B取的时候要加锁,避免出现同时获取到同一个对象的情况。
    • 读取redis的keys时尽量不要使用keys *的方法获取,使用scan在处理大量数据的时候不会造成太大的占用。
    • 批量处理数据时尽量不要一个一个的添加,使用Pipeline管道技术会获得好几十倍的效率提升。数据量越大提升越大。下附测试代码。
         @Autowired
        private CacheService cacheService;
        //耗时338233
        @Test
        public  void testPiple1(){
            long start =System.currentTimeMillis();
            for (int i = 0; i <10000 ; i++) {
                Task task = new Task();
                task.setTaskType(1001);
                task.setPriority(1);
                task.setExecuteTime(new Date().getTime());
                cacheService.lLeftPush("1001_1", JSON.toJSONString(task));
            }
            System.out.println("耗时"+(System.currentTimeMillis()- start));
        }
    
    //使用管道技术执行10000次自增操作共耗时:1784毫秒
    //使用管道技术执行10000次自增操作共耗时:1452毫秒
        @Test
        public void testPiple2(){
            long start  = System.currentTimeMillis();
            //使用管道技术
            List<Object> objectList = cacheService.getstringRedisTemplate().executePipelined(new RedisCallback<Object>() {
                @Nullable
                @Override
                public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
                    for (int i = 0; i <10000 ; i++) {
                        Task task = new Task();
                        task.setTaskType(1002);
                        task.setPriority(1);
                        task.setExecuteTime(new Date().getTime());
                        redisConnection.lPush("1002_1".getBytes(), JSON.toJSONString(task).getBytes());
                    }
                    return null;
                }
            });
            System.out.println("使用管道技术执行10000次自增操作共耗时:"+(System.currentTimeMillis()-start)+"毫秒");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
  • 相关阅读:
    批量--09---批量读文件入表
    【开发技术】SpingBoot数据库与持久化技术,JPA,MongoDB,Redis
    【AT模式连接ONENET】ONENET可视化平台的使用
    AcWing---转圈游戏---快速幂
    小样本学习——匹配网络
    Day 89
    小程序只用云开发,如何发送公众号模板消息?
    业绩走低,毛利率下滑,海外市场能否成为极米科技救命稻草?
    软件设计师_计算机网络——IP地址和子网掩码
    模拟实现二叉搜索树(非kv模式)(上)
  • 原文地址:https://blog.csdn.net/dsafghljk/article/details/127451562