/**
* 定时任务类
* 每天0点取出数据实例化道数据库中
*/
@Component
public class MyJob {
@Resource
private RedisTemplate redisTemplate;
private RedisTemplate<String, Integer> intRedisTemplate;
@Resource
private FwltjService fwltjService;
private Logger logger = LoggerFactory.getLogger(MyJob.class);
//PV,UV头缀
String pVKeyPrefix = WebConstant.PV_KEY_PREFIX;
String uVKeyPrefix = WebConstant.UV_KEY_PREFIX;
/**
* cron表达式
* 每天 17:30:00 执行一次定时任务
* @Scheduled(cron = "0 30 17 * * ?")
* 每天 00:00:00执行一次定时任务
*/
@Scheduled(cron = "0 0 0 * * ? ")
public void cron() {
logger.info(new Date() + " 进入定时任务");
deleteKeyAndSaveDatabase();
logger.info(new Date() + " 定时任务结束");
}
/**
* 实例化到数据库中
*/
public void deleteKeyAndSaveDatabase() {
Fwltj fwltj = new Fwltj();
logger.info(new Date() + " 实例化Redis缓存");
RedisTemplate<String, Integer> intRedis = getIntRedisTemplate();
//查询以此开头所有的key,工具替换keys
Set<String> keysPv = scan(intRedis, pVKeyPrefix);
Set<String> keysUv = scan(intRedis, uVKeyPrefix);
//遍历所有的key,线程排队
Vector<Thread> threadVector = new Vector<>();
Thread childThread = new Thread(new Runnable() {
@Override
public void run() {
for (String pvRedisKey : keysPv) {
String visitIp = pvRedisKey.split("_")[1];
int pVNum = intRedis.opsForValue().get(pvRedisKey);
//uvKey为头缀+IP
String uvRedisKey = WebConstant.UV_KEY + visitIp;
Boolean pvKeyBoolean = intRedis.hasKey(uvRedisKey);
if (pvKeyBoolean) {
int uVNum = intRedis.opsForValue().get(uvRedisKey);
//将key,value实例化到数据库中
//访问时间,IP,PV,UV
fwltj.setTjrq(new Date());
fwltj.setIp(visitIp);
fwltj.setPv(pVNum + "");
fwltj.setUv(uVNum + "");
fwltjService.addF(fwltj);
logger.info("visitIp: " + visitIp + " , pVNum: " + pVNum + " , uVNum: " + uVNum);
}
}
}
});
threadVector.add(childThread);
childThread.start();
//线程排序
for (Thread thread : threadVector) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//0点清除redis
if (!keysPv.isEmpty() & !keysUv.isEmpty()) {
//删除redis中所对应的值
redisTemplate.delete(keysPv);
redisTemplate.delete(keysUv);
logger.info(new Date() + " 清除Redis缓存");
}
}
/**
* scan 实现批量查找key
*
* @param redisTemplate redisTemplate
* @param pattern 表达式,如:abc*,找出所有以abc开始的键
*/
public Set<String> scan(RedisTemplate<String, Integer> redisTemplate, String pattern) {
return redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
Set<String> keysTmp = new HashSet<>();
try (Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder()
.match(pattern)
.count(10000).build())) {
while (cursor.hasNext()) {
keysTmp.add(new String(cursor.next(), "Utf-8"));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return keysTmp;
});
}
/**
* redis实例化
*
* @return
*/
private RedisTemplate<String, Integer> getIntRedisTemplate() {
if (intRedisTemplate == null) {
intRedisTemplate = initTemplate();
}
return intRedisTemplate;
}
private RedisTemplate<String, Integer> initTemplate() {
RedisTemplate<String, Integer> template = new RedisTemplate<String, Integer>();
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericToStringSerializer<Integer>(Integer.class));
template.setExposeConnection(true);
template.setConnectionFactory(redisTemplate.getConnectionFactory());
template.afterPropertiesSet();
return template;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/192858.html