Scene3dNumServiceImpl.java 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package com.fdkankan.contro.service.impl;
  2. import cn.hutool.core.util.StrUtil;
  3. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  5. import com.fdkankan.common.constant.CommonStatus;
  6. import com.fdkankan.common.constant.ErrorCode;
  7. import com.fdkankan.common.exception.BusinessException;
  8. import com.fdkankan.common.util.RandomUtil;
  9. import com.fdkankan.contro.entity.Scene3dNum;
  10. import com.fdkankan.contro.enums.CameraTypeEnum;
  11. import com.fdkankan.contro.mapper.IScene3dNumMapper;
  12. import com.fdkankan.contro.service.IScene3dNumService;
  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 lombok.extern.slf4j.Slf4j;
  18. import org.springframework.beans.factory.annotation.Autowired;
  19. import org.springframework.beans.factory.annotation.Value;
  20. import org.springframework.stereotype.Service;
  21. import org.springframework.util.CollectionUtils;
  22. import java.util.HashSet;
  23. import java.util.List;
  24. import java.util.Objects;
  25. import java.util.Set;
  26. import java.util.concurrent.CompletableFuture;
  27. import java.util.stream.Collectors;
  28. /**
  29. * <p>
  30. * 八目场景编码表 服务实现类
  31. * </p>
  32. *
  33. * @author dengsixing
  34. * @since 2021-12-23
  35. */
  36. @Slf4j
  37. @Service
  38. public class Scene3dNumServiceImpl extends ServiceImpl<IScene3dNumMapper, Scene3dNum> implements IScene3dNumService {
  39. @Autowired
  40. private RedisUtil redisUtil;
  41. @Autowired
  42. private RedisLockUtil redisLockUtil;
  43. @Value("${scene.num.cachePageSize:500}")
  44. private int cachePageSize;
  45. @Value("${scene.num.threshold:10000}")
  46. private int threshold;
  47. @Value("${scene.num.prefix:V4-}")
  48. private String numPrefix;
  49. @Value("${scene.num.batchSize:100}")
  50. private int batchSize;
  51. @Override
  52. public String generateSceneNum(Integer cameraType){
  53. // 从缓存中获取
  54. String sceneNum = redisUtil.lLeftPop(RedisKey.FDKANKAN_SCENE_NUMS);
  55. if(Objects.nonNull(sceneNum)){
  56. return addPrefix(sceneNum,cameraType);
  57. }
  58. // 分布式加锁
  59. boolean lock = redisLockUtil.lock(RedisLockKey.LOCK_FDKANKAN_SCENE_NUMS, RedisKey.EXPIRE_TIME_10_MINUTE);
  60. if (lock) {
  61. try {
  62. log.info("开始加载场景码缓存");
  63. List<String> nums = this.findSceneNum(cachePageSize);
  64. if(CollectionUtils.isEmpty(nums)){
  65. batchCreateSceneNum(true);
  66. nums = this.findSceneNum(cachePageSize);
  67. }else{
  68. CompletableFuture.runAsync(() -> batchCreateSceneNum(false));
  69. }
  70. redisUtil.lRightPushAll(RedisKey.FDKANKAN_SCENE_NUMS, nums);
  71. this.update(new LambdaQueryWrapper<Scene3dNum>().in(Scene3dNum::getCode, nums));
  72. // this.updateUsedStatus(nums);
  73. log.info("场景码加载缓存完成");
  74. } catch (Exception e) {
  75. log.error("场景码加载缓存失败", e);
  76. } finally {
  77. redisLockUtil.unlockLua(RedisLockKey.LOCK_FDKANKAN_SCENE_NUMS);
  78. }
  79. }else{
  80. // 等待2秒加载缓存
  81. try {
  82. Thread.sleep(2000);
  83. } catch (InterruptedException e) {
  84. e.printStackTrace();
  85. }
  86. }
  87. sceneNum = redisUtil.lLeftPop(RedisKey.FDKANKAN_SCENE_NUMS);
  88. if(StrUtil.isEmpty(sceneNum)){
  89. log.error("场景码加载失败");
  90. throw new BusinessException(ErrorCode.FAILURE_CODE_5053);
  91. }
  92. return addPrefix(sceneNum,cameraType);
  93. }
  94. private static String addPrefix( String num,Integer cameraType){
  95. if(cameraType == null){
  96. return num;
  97. }
  98. return CameraTypeEnum.getSceneNumPrefixByType(cameraType) + num;
  99. }
  100. @Override
  101. public void batchCreateSceneNum(boolean force) {
  102. if (!force) {
  103. long count = this.count(new LambdaQueryWrapper<Scene3dNum>().eq(Scene3dNum::getUsed, CommonStatus.NO.code()));
  104. if (count > threshold) {
  105. return;
  106. }
  107. }
  108. int batchCnt = threshold / batchSize + (threshold % batchSize > 0 ? 1 : 0);
  109. for (int i = 0; i < batchCnt; i++){
  110. Set<String> numSet = this.turnCreateSceneNum(batchSize);
  111. List<Scene3dNum> scene3dNumList = numSet.parallelStream().map(num -> {
  112. Scene3dNum scene3dNum = new Scene3dNum();
  113. scene3dNum.setCode(num);
  114. return scene3dNum;
  115. }).collect(Collectors.toList());
  116. try{
  117. this.saveBatch(scene3dNumList);
  118. }catch (Exception e){
  119. log.error("场景码插入异常!");
  120. e.printStackTrace();
  121. }
  122. }
  123. }
  124. private Set<String> turnCreateSceneNum(int cnt){
  125. Set<String> numSet = new HashSet<>();
  126. for(int i = 0; i < cnt; i++){
  127. numSet.add(numPrefix + RandomUtil.generateShortUuid());
  128. }
  129. return numSet;
  130. }
  131. @Override
  132. public List<String> findSceneNum(int pageSize) {
  133. return baseMapper.findSceneNum(pageSize);
  134. }
  135. @Override
  136. public void updateUsedStatus(List<String> nums) {
  137. baseMapper.updateUsedStatus(nums);
  138. }
  139. }