SceneCleanServiceImpl.java 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package com.fdkankan.scene.service.impl;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.date.DateTime;
  4. import cn.hutool.core.date.DateUtil;
  5. import cn.hutool.core.io.FileUtil;
  6. import cn.hutool.core.lang.UUID;
  7. import cn.hutool.core.util.RandomUtil;
  8. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  9. import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  10. import com.fdkankan.common.constant.CommonStatus;
  11. import com.fdkankan.common.util.FileUtils;
  12. import com.fdkankan.model.utils.CreateObjUtil;
  13. import com.fdkankan.redis.constant.RedisKey;
  14. import com.fdkankan.redis.constant.RedisLockKey;
  15. import com.fdkankan.redis.util.RedisLockUtil;
  16. import com.fdkankan.redis.util.RedisUtil;
  17. import com.fdkankan.scene.bean.SceneBean;
  18. import com.fdkankan.scene.entity.SceneClean;
  19. import com.fdkankan.scene.mapper.ISceneCleanMapper;
  20. import com.fdkankan.scene.service.ISceneCleanService;
  21. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  22. import com.google.common.collect.Lists;
  23. import com.google.common.collect.Sets;
  24. import java.util.Calendar;
  25. import java.util.Date;
  26. import java.util.HashSet;
  27. import java.util.List;
  28. import java.util.Set;
  29. import java.util.stream.Collectors;
  30. import org.apache.commons.lang3.StringUtils;
  31. import org.springframework.beans.factory.annotation.Autowired;
  32. import org.springframework.beans.factory.annotation.Value;
  33. import org.springframework.cloud.context.config.annotation.RefreshScope;
  34. import org.springframework.stereotype.Service;
  35. import org.springframework.transaction.annotation.Transactional;
  36. import org.springframework.util.CollectionUtils;
  37. /**
  38. * <p>
  39. * 服务实现类
  40. * </p>
  41. *
  42. * @author
  43. * @since 2022-10-09
  44. */
  45. @RefreshScope
  46. @Service
  47. public class SceneCleanServiceImpl extends ServiceImpl<ISceneCleanMapper, SceneClean> implements ISceneCleanService {
  48. @Autowired
  49. private RedisLockUtil redisLockUtil;
  50. @Autowired
  51. private RedisUtil redisUtil;
  52. @Value("${scene.clean.size:10}")
  53. private Integer sceneCleanSize;
  54. @Transactional
  55. @Override
  56. public void sceneCleanResource(){
  57. //这里考虑到日后会集群部署,所以查询需要清理资源的场景的写法是负载均衡写法,为了避免幻读影响到查询结果,所以写库放在循环外层
  58. List<SceneClean> allInsertList = Lists.newArrayList();
  59. Set<String> allUpdateSet = Sets.newHashSet();
  60. DateTime dateTime = DateUtil.beginOfDay(DateUtil.offsetMonth(Calendar.getInstance().getTime(), -6));
  61. while (true){
  62. String uuid = UUID.randomUUID().toString();
  63. boolean lock = redisLockUtil.lock(RedisLockKey.LOCK_SCENE_CLEAN, uuid, RedisKey.EXPIRE_TIME_1_MINUTE);
  64. if(!lock){
  65. try {
  66. Thread.sleep(RandomUtil.randomLong(1000L, 2000L));
  67. continue;
  68. } catch (InterruptedException e) {
  69. e.printStackTrace();
  70. }
  71. }
  72. long index = 0;
  73. String indexStr = redisUtil.get(RedisKey.SCENE_CLEAN_INDEX);
  74. if(StringUtils.isNotBlank(indexStr)){
  75. index = Long.valueOf(indexStr);
  76. }
  77. //下标增加1000
  78. redisUtil.incr(RedisKey.SCENE_CLEAN_INDEX, sceneCleanSize);
  79. //解锁
  80. redisLockUtil.unlockLua(RedisLockKey.LOCK_SCENE_CLEAN, uuid);
  81. //查询需要清理资源的场景
  82. List<SceneBean> sceneBeanList = this.selectNeadCleanScene(index, sceneCleanSize, dateTime);
  83. //如果查出来的场景集合是空,证明已经没有场景资源需要删除,则需要把查询下表删除,等待下一次定时任务执行
  84. if(CollectionUtils.isEmpty(sceneBeanList)){
  85. redisUtil.del(RedisKey.SCENE_CLEAN_INDEX);
  86. break;
  87. }
  88. List<SceneClean> insertList = Lists.newArrayList();
  89. List<String> numList = sceneBeanList.stream().map(scene -> scene.getNum()).collect(Collectors.toList());
  90. List<SceneClean> updateList = this.list(new LambdaQueryWrapper<SceneClean>().in(SceneClean::getNum, numList));
  91. Set<String> updateSet = new HashSet<>();
  92. if(!CollectionUtils.isEmpty(updateList)){
  93. updateList.stream().forEach(item->{
  94. updateSet.add(item.getNum());
  95. });
  96. }
  97. sceneBeanList.stream().forEach(scene -> {
  98. if(StringUtils.isNotBlank(scene.getDataSource())){
  99. try {
  100. CreateObjUtil.deleteFile(scene.getDataSource());
  101. } catch (Exception e) {
  102. e.printStackTrace();
  103. }
  104. }
  105. if(!updateSet.contains(scene.getNum())){
  106. SceneClean sceneClean = new SceneClean();
  107. sceneClean.setNum(scene.getNum());
  108. insertList.add(sceneClean);
  109. }
  110. });
  111. if(!CollectionUtils.isEmpty(insertList)){
  112. allInsertList.addAll(insertList);
  113. }
  114. if(!CollectionUtils.isEmpty(updateSet)){
  115. allUpdateSet.addAll(updateSet);
  116. }
  117. }
  118. //写库
  119. if(CollUtil.isNotEmpty(allInsertList)){
  120. this.saveBatch(allInsertList);
  121. }
  122. if(CollUtil.isNotEmpty(allUpdateSet)){
  123. this.update(new LambdaUpdateWrapper<SceneClean>().set(SceneClean::getState,
  124. CommonStatus.YES.code()).in(SceneClean::getNum, allUpdateSet));
  125. }
  126. }
  127. @Override
  128. public List<SceneBean> selectNeadCleanScene(long index, int size, Date time) {
  129. return this.baseMapper.selectNeadCleanScene(index, size, time);
  130. }
  131. }