添加限流工具,修改模板onlyIf

This commit is contained in:
Jerry Yan 2025-01-23 15:10:29 +08:00
parent 1aa1ae5e2b
commit 7bd9a7507f
10 changed files with 64 additions and 32 deletions

View File

@ -3,6 +3,5 @@ package com.ycwl.basic.constant;
public class FaceConstant { public class FaceConstant {
public static final String FACE_DB_NAME_PFX="face:db:"; public static final String FACE_DB_NAME_PFX="face:db:";
public static final String USER_FACE_DB_NAME="userFace"; 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:"; public static final String FACE_USER_URL_PFX="face:user:url:";
} }

View File

@ -23,4 +23,6 @@ public interface FaceSampleMapper {
int update(FaceSampleEntity faceSample); int update(FaceSampleEntity faceSample);
List<FaceSampleEntity> listByIds(List<Long> list); List<FaceSampleEntity> listByIds(List<Long> list);
FaceSampleEntity getEntity(Long faceSampleId);
} }

View File

@ -2,6 +2,8 @@ package com.ycwl.basic.model.pc.faceDetectLog.resp;
import lombok.Data; import lombok.Data;
import java.util.Date;
@Data @Data
public class MatchLocalRecord { public class MatchLocalRecord {
private Long faceSampleId; private Long faceSampleId;
@ -9,4 +11,5 @@ public class MatchLocalRecord {
private Float score; private Float score;
private Float confidence; private Float confidence;
private String idStr; private String idStr;
private Date shotDate;
} }

View File

@ -72,5 +72,9 @@ public class TemplateEntity {
private Integer status; private Integer status;
private Date createTime; private Date createTime;
private Date updateTime; private Date updateTime;
private Integer sort;
private Integer cropEnable;
private String onlyIf;
private List<TemplateEntity> children; private List<TemplateEntity> children;
} }

View File

@ -83,8 +83,10 @@ public class TemplateRespVO {
private Date createTime; private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime; private Date updateTime;
private List<TemplateRespVO> children;
private BigDecimal price; private BigDecimal price;
private BigDecimal slashPrice; private BigDecimal slashPrice;
private Integer sort; private Integer sort;
private Integer cropEnable;
private String onlyIf;
private List<TemplateRespVO> children;
} }

View File

@ -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();
}
}

View File

@ -60,4 +60,8 @@ public class FaceRepository {
redisTemplate.delete(String.format(FACE_CACHE_KEY, faceId)); redisTemplate.delete(String.format(FACE_CACHE_KEY, faceId));
redisTemplate.delete(String.format(FACE_SAMPLE_CACHE_KEY, faceId)); redisTemplate.delete(String.format(FACE_SAMPLE_CACHE_KEY, faceId));
} }
public FaceSampleEntity getFaceSample(Long faceSampleId) {
return faceSampleMapper.getEntity(faceSampleId);
}
} }

View File

@ -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.pc.source.entity.SourceEntity;
import com.ycwl.basic.model.task.resp.AddFaceSampleRespVo; import com.ycwl.basic.model.task.resp.AddFaceSampleRespVo;
import com.ycwl.basic.model.task.resp.SearchFaceRespVo; import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
import com.ycwl.basic.ratelimiter.SlidingWindowRateLimiter;
import com.ycwl.basic.repository.FaceRepository; import com.ycwl.basic.repository.FaceRepository;
import com.ycwl.basic.service.task.TaskFaceService; import com.ycwl.basic.service.task.TaskFaceService;
import com.ycwl.basic.storage.StorageFactory; import com.ycwl.basic.storage.StorageFactory;
@ -86,6 +87,7 @@ public class TaskFaceServiceImpl implements TaskFaceService {
private SourceMapper sourceMapper; private SourceMapper sourceMapper;
@Autowired @Autowired
private OrderBiz orderBiz; private OrderBiz orderBiz;
private SlidingWindowRateLimiter limiter = new SlidingWindowRateLimiter(5); // 阿里云人脸检索限制qps=5
private IAcsClient getClient() { private IAcsClient getClient() {
DefaultProfile profile = DefaultProfile.getProfile( DefaultProfile profile = DefaultProfile.getProfile(
@ -180,7 +182,11 @@ public class TaskFaceServiceImpl implements TaskFaceService {
record.setIdStr(item.getExtraData()); record.setIdStr(item.getExtraData());
record.setFaceSampleId(Long.parseLong(item.getExtraData())); record.setFaceSampleId(Long.parseLong(item.getExtraData()));
if (StringUtils.isNumeric(item.getDbName())) { 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 { } else {
record.setFaceUrl(getFaceUrl(record.getFaceSampleId())); record.setFaceUrl(getFaceUrl(record.getFaceSampleId()));
} }
@ -218,7 +224,6 @@ public class TaskFaceServiceImpl implements TaskFaceService {
} }
faceSampleEntity.setUpdateAt(new Date()); faceSampleEntity.setUpdateAt(new Date());
faceSampleMapper.update(faceSampleEntity); faceSampleMapper.update(faceSampleEntity);
addFaceSampleUrlCache(faceSampleId, faceSampleRespVO.getFaceUrl());
return respVo; return respVo;
} }
@ -229,6 +234,11 @@ public class TaskFaceServiceImpl implements TaskFaceService {
request.setDbName(dbName); request.setDbName(dbName);
request.setEntityId(entityId); request.setEntityId(entityId);
IAcsClient client = getClient(); IAcsClient client = getClient();
try {
limiter.allowRequest();
} catch (InterruptedException e) {
return null;
}
try { try {
client.getAcsResponse(request); client.getAcsResponse(request);
} catch (ClientException e) { } 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); 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);
}
} }

View File

@ -96,4 +96,9 @@
) )
order by create_at desc order by create_at desc
</select> </select>
<select id="getEntity" resultType="com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity">
select *
from face_sample
where id = #{id}
</select>
</mapper> </mapper>

View File

@ -2,8 +2,8 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ycwl.basic.mapper.TemplateMapper"> <mapper namespace="com.ycwl.basic.mapper.TemplateMapper">
<insert id="add"> <insert id="add">
insert into template(id, scenic_id, `name`, pid, is_placeholder, source_url, luts, overlays, audios, cover_url, frame_rate, speed, price, slash_price) 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}) values (#{id}, #{scenicId}, #{name}, #{pid}, #{isPlaceholder}, #{sourceUrl}, #{luts}, #{overlays}, #{audios}, #{coverUrl}, #{frameRate}, #{speed}, #{price}, #{slashPrice}, #{cropEnable}, #{onlyIf})
</insert> </insert>
<insert id="addConfig"> <insert id="addConfig">
insert into template_config(id, template_id, create_time) insert into template_config(id, template_id, create_time)
@ -25,6 +25,9 @@
<if test="price!= null">price = #{price}, </if> <if test="price!= null">price = #{price}, </if>
<if test="slashPrice!= null">slash_price = #{slashPrice}, </if> <if test="slashPrice!= null">slash_price = #{slashPrice}, </if>
<if test="speed!= null">speed = #{speed}, </if> <if test="speed!= null">speed = #{speed}, </if>
<if test="sort!= null">sort = #{sort}, </if>
<if test="cropEnable!= null">crop_enable = #{cropEnable}, </if>
<if test="onlyIf!= null">only_if = #{onlyIf}, </if>
</set> </set>
where id = #{id} where id = #{id}
</update> </update>