From 7bd9a7507ffcf754d8139fb68661d136b3bf6e7a Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Thu, 23 Jan 2025 15:10:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=99=90=E6=B5=81=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=EF=BC=8C=E4=BF=AE=E6=94=B9=E6=A8=A1=E6=9D=BFonlyIf?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ycwl/basic/constant/FaceConstant.java | 1 - .../ycwl/basic/mapper/FaceSampleMapper.java | 2 + .../faceDetectLog/resp/MatchLocalRecord.java | 3 ++ .../pc/template/entity/TemplateEntity.java | 4 ++ .../pc/template/resp/TemplateRespVO.java | 4 +- .../ratelimiter/SlidingWindowRateLimiter.java | 26 ++++++++++++ .../ycwl/basic/repository/FaceRepository.java | 4 ++ .../task/impl/TaskFaceServiceImpl.java | 40 ++++++------------- .../resources/mapper/FaceSampleMapper.xml | 5 +++ src/main/resources/mapper/TemplateMapper.xml | 7 +++- 10 files changed, 64 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/ycwl/basic/ratelimiter/SlidingWindowRateLimiter.java diff --git a/src/main/java/com/ycwl/basic/constant/FaceConstant.java b/src/main/java/com/ycwl/basic/constant/FaceConstant.java index 2c6fdf0..d8c8082 100644 --- a/src/main/java/com/ycwl/basic/constant/FaceConstant.java +++ b/src/main/java/com/ycwl/basic/constant/FaceConstant.java @@ -3,6 +3,5 @@ package com.ycwl.basic.constant; public class FaceConstant { public static final String FACE_DB_NAME_PFX="face:db:"; public static final String USER_FACE_DB_NAME="userFace"; - public static final String FACE_SAMPLE_URL_PFX="face:sample:url:"; public static final String FACE_USER_URL_PFX="face:user:url:"; } diff --git a/src/main/java/com/ycwl/basic/mapper/FaceSampleMapper.java b/src/main/java/com/ycwl/basic/mapper/FaceSampleMapper.java index 068effd..63a6411 100644 --- a/src/main/java/com/ycwl/basic/mapper/FaceSampleMapper.java +++ b/src/main/java/com/ycwl/basic/mapper/FaceSampleMapper.java @@ -23,4 +23,6 @@ public interface FaceSampleMapper { int update(FaceSampleEntity faceSample); List listByIds(List list); + + FaceSampleEntity getEntity(Long faceSampleId); } diff --git a/src/main/java/com/ycwl/basic/model/pc/faceDetectLog/resp/MatchLocalRecord.java b/src/main/java/com/ycwl/basic/model/pc/faceDetectLog/resp/MatchLocalRecord.java index 9b0b9e7..c50e368 100644 --- a/src/main/java/com/ycwl/basic/model/pc/faceDetectLog/resp/MatchLocalRecord.java +++ b/src/main/java/com/ycwl/basic/model/pc/faceDetectLog/resp/MatchLocalRecord.java @@ -2,6 +2,8 @@ package com.ycwl.basic.model.pc.faceDetectLog.resp; import lombok.Data; +import java.util.Date; + @Data public class MatchLocalRecord { private Long faceSampleId; @@ -9,4 +11,5 @@ public class MatchLocalRecord { private Float score; private Float confidence; private String idStr; + private Date shotDate; } diff --git a/src/main/java/com/ycwl/basic/model/pc/template/entity/TemplateEntity.java b/src/main/java/com/ycwl/basic/model/pc/template/entity/TemplateEntity.java index 9c06719..335bbae 100644 --- a/src/main/java/com/ycwl/basic/model/pc/template/entity/TemplateEntity.java +++ b/src/main/java/com/ycwl/basic/model/pc/template/entity/TemplateEntity.java @@ -72,5 +72,9 @@ public class TemplateEntity { private Integer status; private Date createTime; private Date updateTime; + + private Integer sort; + private Integer cropEnable; + private String onlyIf; private List children; } diff --git a/src/main/java/com/ycwl/basic/model/pc/template/resp/TemplateRespVO.java b/src/main/java/com/ycwl/basic/model/pc/template/resp/TemplateRespVO.java index a2497fa..a05b411 100644 --- a/src/main/java/com/ycwl/basic/model/pc/template/resp/TemplateRespVO.java +++ b/src/main/java/com/ycwl/basic/model/pc/template/resp/TemplateRespVO.java @@ -83,8 +83,10 @@ public class TemplateRespVO { private Date createTime; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date updateTime; - private List children; private BigDecimal price; private BigDecimal slashPrice; private Integer sort; + private Integer cropEnable; + private String onlyIf; + private List children; } diff --git a/src/main/java/com/ycwl/basic/ratelimiter/SlidingWindowRateLimiter.java b/src/main/java/com/ycwl/basic/ratelimiter/SlidingWindowRateLimiter.java new file mode 100644 index 0000000..68db5ff --- /dev/null +++ b/src/main/java/com/ycwl/basic/ratelimiter/SlidingWindowRateLimiter.java @@ -0,0 +1,26 @@ +package com.ycwl.basic.ratelimiter; + +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + + +public class SlidingWindowRateLimiter { + private final Semaphore semaphore; + private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1); + + public SlidingWindowRateLimiter(int maxRequestsPerSecond) { + this.semaphore = new Semaphore(maxRequestsPerSecond); + // Schedule a task to release all permits every second + scheduler.scheduleAtFixedRate(() -> semaphore.release(maxRequestsPerSecond - semaphore.availablePermits()), 1, 1, TimeUnit.SECONDS); + } + + public void allowRequest() throws InterruptedException { + semaphore.acquire(); + } + + public void shutdown() { + scheduler.shutdown(); + } +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/repository/FaceRepository.java b/src/main/java/com/ycwl/basic/repository/FaceRepository.java index e24a618..55ab3f5 100644 --- a/src/main/java/com/ycwl/basic/repository/FaceRepository.java +++ b/src/main/java/com/ycwl/basic/repository/FaceRepository.java @@ -60,4 +60,8 @@ public class FaceRepository { redisTemplate.delete(String.format(FACE_CACHE_KEY, faceId)); redisTemplate.delete(String.format(FACE_SAMPLE_CACHE_KEY, faceId)); } + + public FaceSampleEntity getFaceSample(Long faceSampleId) { + return faceSampleMapper.getEntity(faceSampleId); + } } diff --git a/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java b/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java index ec1ada4..e94526b 100644 --- a/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java @@ -37,6 +37,7 @@ import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity; import com.ycwl.basic.model.pc.source.entity.SourceEntity; import com.ycwl.basic.model.task.resp.AddFaceSampleRespVo; import com.ycwl.basic.model.task.resp.SearchFaceRespVo; +import com.ycwl.basic.ratelimiter.SlidingWindowRateLimiter; import com.ycwl.basic.repository.FaceRepository; import com.ycwl.basic.service.task.TaskFaceService; import com.ycwl.basic.storage.StorageFactory; @@ -86,6 +87,7 @@ public class TaskFaceServiceImpl implements TaskFaceService { private SourceMapper sourceMapper; @Autowired private OrderBiz orderBiz; + private SlidingWindowRateLimiter limiter = new SlidingWindowRateLimiter(5); // 阿里云人脸检索限制qps=5 private IAcsClient getClient() { DefaultProfile profile = DefaultProfile.getProfile( @@ -180,7 +182,11 @@ public class TaskFaceServiceImpl implements TaskFaceService { record.setIdStr(item.getExtraData()); record.setFaceSampleId(Long.parseLong(item.getExtraData())); if (StringUtils.isNumeric(item.getDbName())) { - record.setFaceUrl(getFaceSampleUrl(record.getFaceSampleId())); + FaceSampleEntity faceSample = faceRepository.getFaceSample(record.getFaceSampleId()); + if (faceSample != null) { + record.setFaceUrl(faceSample.getFaceUrl()); + record.setShotDate(faceSample.getCreateAt()); + } } else { record.setFaceUrl(getFaceUrl(record.getFaceSampleId())); } @@ -218,7 +224,6 @@ public class TaskFaceServiceImpl implements TaskFaceService { } faceSampleEntity.setUpdateAt(new Date()); faceSampleMapper.update(faceSampleEntity); - addFaceSampleUrlCache(faceSampleId, faceSampleRespVO.getFaceUrl()); return respVo; } @@ -229,6 +234,11 @@ public class TaskFaceServiceImpl implements TaskFaceService { request.setDbName(dbName); request.setEntityId(entityId); IAcsClient client = getClient(); + try { + limiter.allowRequest(); + } catch (InterruptedException e) { + return null; + } try { client.getAcsResponse(request); } catch (ClientException e) { @@ -465,30 +475,4 @@ public class TaskFaceServiceImpl implements TaskFaceService { } redisTemplate.opsForValue().set(FaceConstant.FACE_USER_URL_PFX + faceId, faceUrl, 3, TimeUnit.DAYS); } - public String getFaceSampleUrl(Long faceSampleId) { - if (faceSampleId == null) { - return null; - } - if (redisTemplate.hasKey(FaceConstant.FACE_SAMPLE_URL_PFX + faceSampleId)) { - return redisTemplate.opsForValue().get(FaceConstant.FACE_SAMPLE_URL_PFX + faceSampleId); - } - FaceSampleRespVO faceSampleRespVO = faceSampleMapper.getById(faceSampleId); - if (faceSampleRespVO == null) { - return null; - } - String faceUrl = faceSampleRespVO.getFaceUrl(); - if (StringUtils.isNotBlank(faceUrl)) { - addFaceSampleUrlCache(faceSampleId, faceUrl); - } - return faceUrl; - } - public void addFaceSampleUrlCache(Long faceSampleId, String faceUrl) { - if (faceSampleId == null) { - return; - } - if (StringUtils.isBlank(faceUrl)) { - return; - } - redisTemplate.opsForValue().set(FaceConstant.FACE_SAMPLE_URL_PFX + faceSampleId, faceUrl, 3, TimeUnit.DAYS); - } } diff --git a/src/main/resources/mapper/FaceSampleMapper.xml b/src/main/resources/mapper/FaceSampleMapper.xml index b1dfc5d..1453042 100644 --- a/src/main/resources/mapper/FaceSampleMapper.xml +++ b/src/main/resources/mapper/FaceSampleMapper.xml @@ -96,4 +96,9 @@ ) order by create_at desc + diff --git a/src/main/resources/mapper/TemplateMapper.xml b/src/main/resources/mapper/TemplateMapper.xml index b10c58b..826dbed 100644 --- a/src/main/resources/mapper/TemplateMapper.xml +++ b/src/main/resources/mapper/TemplateMapper.xml @@ -2,8 +2,8 @@ - insert into template(id, scenic_id, `name`, pid, is_placeholder, source_url, luts, overlays, audios, cover_url, frame_rate, speed, price, slash_price) - values (#{id}, #{scenicId}, #{name}, #{pid}, #{isPlaceholder}, #{sourceUrl}, #{luts}, #{overlays}, #{audios}, #{coverUrl}, #{frameRate}, #{speed}, #{price}, #{slashPrice}) + insert into template(id, scenic_id, `name`, pid, is_placeholder, source_url, luts, overlays, audios, cover_url, frame_rate, speed, price, slash_price, crop_enable, only_if) + values (#{id}, #{scenicId}, #{name}, #{pid}, #{isPlaceholder}, #{sourceUrl}, #{luts}, #{overlays}, #{audios}, #{coverUrl}, #{frameRate}, #{speed}, #{price}, #{slashPrice}, #{cropEnable}, #{onlyIf}) insert into template_config(id, template_id, create_time) @@ -25,6 +25,9 @@ price = #{price}, slash_price = #{slashPrice}, speed = #{speed}, + sort = #{sort}, + crop_enable = #{cropEnable}, + only_if = #{onlyIf}, where id = #{id}