实体类
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();
}
}