同步Redis中PV&UV数据到MongoDB的定时任务

实体类

package com.gaiaworks;

import lombok.Data;

/**
 * 请求地址访问量
 */
@Data
public class MPv {

    /** 请求地址 */
    private String requestURL;

    /** 访问量 */
    private Long count;

}
package com.gaiaworks;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;
import java.util.List;

/**
 * 权益商城PV统计
 */
@Document(collection = "shop_pv_statistic")
@Data
public class MShopPvStatistic {

    /** id */
    @Id
    private String id;

    /** appId */
    private String appId;

    /** 日期 */
    private String day;

    /** 总访问量 */
    private Long total;

    /** 请求地址访问量集合 */
    private List<MPv> pvList;

    /** 创建时间 */
    private Date createTime;

    /** 更新时间 */
    private Date updateTime;

}
package com.gaiaworks;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;

/**
 * 权益商城UV统计
 */
@Document(collection = "shop_uv_statistic")
@Data
public class MShopUvStatistic {

    /** id */
    @Id
    private String id;

    /** appId */
    private String appId;

    /** 日期 */
    private String day;

    /** 总访问量 */
    private Long total;

    /** 创建时间 */
    private Date createTime;

    /** 更新时间 */
    private Date updateTime;

}

Job

package net.baiqu.shop.data.core.job;

import lombok.extern.slf4j.Slf4j;
import net.baiqu.shop.data.core.util.DateUtils;
import net.baiqu.shop.data.core.util.RedisUtil;
import net.baiqu.shop.data.dal.entity.document.MPv;
import net.baiqu.shop.data.dal.entity.document.MShopPvStatistic;
import net.baiqu.shop.data.dal.entity.document.MShopUvStatistic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * 同步redis和mongodb中pv uv统计数据的定时任务
 */
@Component
@EnableScheduling
@Slf4j
public class PvUvJob {

    /** 权益商城appId */
    private static final String SHOP_APP_ID = "500000";

    /** redis片区 */
    private static final int REDIS_INDEX = 0;

    /** 权益商城PV统计collection */
    private static final String SHOP_PV_COLLECTION = "shop_pv_statistic";

    /** 权益商城UV统计collection */
    private static final String SHOP_UV_COLLECTION = "shop_uv_statistic";

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 同步Redis中PV数据到MongoDB定时任务
     */
    @Scheduled(fixedRate = 10 * 60 * 1000)
    public void redisPvToMongodbTask() {
        String day = DateUtils.formatToString(new Date(), "yyyy-MM-dd");
        String key = SHOP_APP_ID + "_pv_" + day;

        log.info("PvUvJob.redisPvToMongodbTask: 开始同步{}数据", key);
        // 查询mongodb中是否有当天的pv统计数据,有则更新,无则插入
        MShopPvStatistic shopPvStatistic = mongoTemplate.findOne(
                Query.query(
                        Criteria.where("day").is(day)
                ), MShopPvStatistic.class);
        List<MPv> pvList = new ArrayList<>();
        // 查询redis中的pv数据
        long total = this.queryPvByRedis(key, pvList);
        if (shopPvStatistic == null) {
            // 插入
            // 封装pv统计数据
            shopPvStatistic = new MShopPvStatistic();
            shopPvStatistic.setAppId(SHOP_APP_ID);
            shopPvStatistic.setDay(day);
            shopPvStatistic.setPvList(pvList);
            shopPvStatistic.setTotal(total);
            shopPvStatistic.setCreateTime(new Date());
            shopPvStatistic.setUpdateTime(new Date());
            // 将pv统计数据存入mongo中
            mongoTemplate.insert(shopPvStatistic, SHOP_PV_COLLECTION);
            log.info("PvUvJob.redisPvToMongodbTask: 插入{}数据到mongo", key);
        } else {
            // 更新
            mongoTemplate.updateFirst(
                    Query.query(
                            new Criteria("day").is(day)
                    ),
                    Update.update("total", total)
                            .set("pvList", pvList)
                            .set("updateTime", new Date()),
                    MShopPvStatistic.class
            );
            log.info("PvUvJob.redisPvToMongodbTask: 更新{}数据到mongo", key);
        }
        log.info("PvUvJob.redisPvToMongodbTask: 完成同步{}数据", key);
    }

    /**
     * 同步Redis中UV数据到MongoDB定时任务
     */
    @Scheduled(fixedRate = 10 * 60 * 1000)
    public void redisUvToMongodbTask() {
        String day = DateUtils.formatToString(new Date(), "yyyy-MM-dd");
        String key = SHOP_APP_ID + "_uv_" + day;

        log.info("PvUvJob.redisUvToMongodbTask: 开始同步{}数据", key);
        // 查询mongodb中是否有当天的uv统计数据,有则更新,无则插入
        MShopUvStatistic shopUvStatistic = mongoTemplate.findOne(
                Query.query(
                        Criteria.where("day").is(day)
                ), MShopUvStatistic.class);

        // 查询redis中的uv数据
        long total = this.queryUvByRedis(key);
        if (shopUvStatistic == null) {
            // 插入
            // 封装uv统计数据
            shopUvStatistic = new MShopUvStatistic();
            shopUvStatistic.setAppId(SHOP_APP_ID);
            shopUvStatistic.setDay(day);
            shopUvStatistic.setTotal(total);
            shopUvStatistic.setCreateTime(new Date());
            shopUvStatistic.setUpdateTime(new Date());
            // 将pv统计数据存入mongo中
            mongoTemplate.insert(shopUvStatistic, SHOP_UV_COLLECTION);
            log.info("PvUvJob.redisUvToMongodbTask: 插入{}数据到mongo", key);
        } else {
            // 更新
            mongoTemplate.updateFirst(
                    Query.query(
                            new Criteria("day").is(day)
                    ),
                    Update.update("total", total)
                            .set("updateTime", new Date()),
                    MShopUvStatistic.class
            );
            log.info("PvUvJob.redisUvToMongodbTask: 更新{}数据到mongo", key);
        }
        log.info("PvUvJob.redisUvToMongodbTask: 完成同步{}数据", key);
    }

    /**
     * 查询Redis中PV数据
     */
    private long queryPvByRedis(String key, List<MPv> pvList) {
        Jedis jedis = redisUtil.getJedis();
        long total = 0;
        jedis.select(REDIS_INDEX);
        Set<Tuple> tuples = jedis.zrevrangeWithScores(key, 0, Long.MAX_VALUE);
        if (! CollectionUtils.isEmpty(tuples)) {
            for (Tuple tuple : tuples) {
                MPv pv = new MPv();
                pv.setRequestURL(tuple.getElement());
                pv.setCount((long) tuple.getScore());
                total = total + (long) tuple.getScore();
                pvList.add(pv);
            }
        }
        return total;
    }

    /**
     * 查询Redis中UV数据
     */
    private long queryUvByRedis(String key) {
        Jedis jedis = redisUtil.getJedis();
        jedis.select(REDIS_INDEX);
        Set<Tuple> tuples = jedis.zrevrangeWithScores(key, 0, Long.MAX_VALUE);
        return tuples.size();
    }

}

 

posted on 2018-09-03 17:27  动物管理猿  阅读(450)  评论(0编辑  收藏  举报

导航