添加限流工具,修改模板onlyIf
This commit is contained in:
parent
1aa1ae5e2b
commit
7bd9a7507f
@ -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:";
|
||||
}
|
||||
|
@ -23,4 +23,6 @@ public interface FaceSampleMapper {
|
||||
int update(FaceSampleEntity faceSample);
|
||||
|
||||
List<FaceSampleEntity> listByIds(List<Long> list);
|
||||
|
||||
FaceSampleEntity getEntity(Long faceSampleId);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<TemplateEntity> children;
|
||||
}
|
||||
|
@ -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<TemplateRespVO> children;
|
||||
private BigDecimal price;
|
||||
private BigDecimal slashPrice;
|
||||
private Integer sort;
|
||||
private Integer cropEnable;
|
||||
private String onlyIf;
|
||||
private List<TemplateRespVO> children;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -96,4 +96,9 @@
|
||||
)
|
||||
order by create_at desc
|
||||
</select>
|
||||
<select id="getEntity" resultType="com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity">
|
||||
select *
|
||||
from face_sample
|
||||
where id = #{id}
|
||||
</select>
|
||||
</mapper>
|
||||
|
@ -2,8 +2,8 @@
|
||||
<!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">
|
||||
<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)
|
||||
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>
|
||||
<insert id="addConfig">
|
||||
insert into template_config(id, template_id, create_time)
|
||||
@ -25,6 +25,9 @@
|
||||
<if test="price!= null">price = #{price}, </if>
|
||||
<if test="slashPrice!= null">slash_price = #{slashPrice}, </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>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
Loading…
x
Reference in New Issue
Block a user