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

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

你可能感兴趣的:(黑马头条知识点,java,数据库,开发语言)