原创

Java-拒绝并发重复请求-判断参数缓存10秒-ngxin返回499

另外可以参考 《Java-异步多线程专题-ConcurrentTaskBySingleKeyExecutor-同一次并发中,只接受1个key的任务》
--------------------------------------------------------------------------------
public Integer saveOrUpdate(EduOfflineCourseVo eduOfflineCourseVo) {
Integer id = eduOfflineCourseVo.getId();
if (id == null) {
checkRepeatV1(eduOfflineCourseVo);
}
if (id == null) {
//新增
long count = eduOfflineCourseMapper.checkRepeat(eduOfflineCourse);
} else {
}
return id;
}
public void checkRepeatV1(Object o) {
JSONObject ob = JSON.parseObject(JSON.toJSONString(o));
if (ob.getInteger("id") == null) {
String md5 = EduMigrateUtils.getMd5(JSON.toJSONString(o));
String key = "RecordCheckRepeatSubmit" + md5;
//最好使用 MapCacheUtil
FIFOCacheProvider fifoCacheProvider = FIFOCacheProvider.getInstance(1000);
String value = (String) fifoCacheProvider.get(key);
if (StringUtils.isNotBlank(value)) {
throw new BizzException("重复提交");
}
//10秒
fifoCacheProvider.put(key, key, 1 * 10 * 1000L);
}
}


nginx grep ./access.log | grep edu | grep 499 ,看前几个出现499的,应该任务太多,处理不过来。

直接使用同步锁导致服务太慢。使用
synchronized (ParamFieldLockUtils.getLock("eduTrainCourseFrontendService#addCourseActualLearningTime", dto.getSynchronizedKey())) {
// 这个能优化,但是不能解决,
// 改用 判断重复请求
public String getSynchronizedKey() {
String key = "";
if (this.getCourseId() != null) {
key += this.getCourseId();
}
if (this.getChapterId() != null) {
key += this.getChapterId();
}
if (this.getSectionId() != null) {
key += this.getSectionId();
}
return key;
}

public void checkRepeat(String prefixKey ,LearningCourseDto dto) {
String md5 = EduMigrateUtils.getMd5(dto.getSynchronizedKey());
String key = prefixKey + md5;
//最好使用 MapCacheUtil
FIFOCacheProvider fifoCacheProvider = FIFOCacheProvider.getInstance(5000);
String value = (String) fifoCacheProvider.get(key);
if (StringUtils.isNotBlank(value)) {
throw new BizzException("重复提交");
}
//5秒
fifoCacheProvider.put(key, key, 1 * 5 * 1000L);
}


另外有token机制

正文到此结束
本文目录