|
|
package com.yoho.search.common.downgrade.persional;
|
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
import org.aspectj.lang.ProceedingJoinPoint;
|
|
|
import org.aspectj.lang.annotation.Around;
|
|
|
import org.aspectj.lang.annotation.Aspect;
|
|
|
import org.aspectj.lang.reflect.MethodSignature;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
|
|
|
import com.yoho.search.common.cache.impls.SearchRedis;
|
|
|
import com.yoho.search.common.filter.YohoHttpServletRequestWrapper;
|
|
|
|
|
|
@Component
|
|
|
@Aspect
|
|
|
public class AutoDownGradePersionalAspect {
|
|
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(AutoDownGradePersionalAspect.class);
|
|
|
|
|
|
@Autowired
|
|
|
private SearchRedis searchRedis;
|
|
|
|
|
|
@Around("@annotation(com.yoho.search.common.downgrade.persional.AutoDownGradePersional)")
|
|
|
public Object downGrade(ProceedingJoinPoint pjp) throws Throwable {
|
|
|
String autoDownGradeKey = this.getAutoDownGradeKey(pjp);
|
|
|
boolean isPersional = false;
|
|
|
try {
|
|
|
MethodSignature signature = (MethodSignature) pjp.getSignature();
|
|
|
AutoDownGradePersional autoDownGrade = signature.getMethod().getAnnotation(AutoDownGradePersional.class);
|
|
|
Object[] arges = pjp.getArgs();
|
|
|
for (Object object : arges) {
|
|
|
if (this.dealPersional(object, autoDownGrade, autoDownGradeKey)) {
|
|
|
isPersional = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
return pjp.proceed();
|
|
|
} catch (Exception e) {
|
|
|
logger.error(e.getMessage());
|
|
|
throw e;
|
|
|
} finally {
|
|
|
if (isPersional) {
|
|
|
this.decrease(autoDownGradeKey);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private boolean dealPersional(Object object, AutoDownGradePersional autoDownGrade, String autoDownGradeKey) {
|
|
|
if (!(object instanceof YohoHttpServletRequestWrapper)) {
|
|
|
return false;
|
|
|
}
|
|
|
YohoHttpServletRequestWrapper yohoHttpServletRequestWrapper = (YohoHttpServletRequestWrapper) object;
|
|
|
String uid = yohoHttpServletRequestWrapper.getParameter("uid");
|
|
|
if (StringUtils.isBlank(uid) || "0".equalsIgnoreCase(uid)) {
|
|
|
return false;
|
|
|
}
|
|
|
if (StringUtils.isNotBlank(yohoHttpServletRequestWrapper.getParameter("order"))) {
|
|
|
return false;
|
|
|
}
|
|
|
if (autoDownGrade == null) {
|
|
|
return false;
|
|
|
}
|
|
|
int count = this.increase(autoDownGradeKey, autoDownGrade.timeInSecond());
|
|
|
if (count >= autoDownGrade.maxCount()) {
|
|
|
logger.error("AutoDownGradePersionalAspect,autoDownGradeKey is [{}]", autoDownGradeKey);
|
|
|
yohoHttpServletRequestWrapper.addParams("uid", new String[] { "0" });
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
private String getAutoDownGradeKey(ProceedingJoinPoint pjp) {
|
|
|
Method targetMethod = ((MethodSignature) (pjp.getSignature())).getMethod();
|
|
|
Class<?> clazz = targetMethod.getDeclaringClass();
|
|
|
|
|
|
String classRequestMappingValue = "";
|
|
|
RequestMapping classRequestMapping = clazz.getDeclaredAnnotation(RequestMapping.class);
|
|
|
if (classRequestMapping != null && classRequestMapping.value() != null && classRequestMapping.value().length > 0) {
|
|
|
classRequestMappingValue = classRequestMapping.value()[0];
|
|
|
}
|
|
|
|
|
|
String methodRequestMappingValue = "";
|
|
|
RequestMapping methodRequestMapping = targetMethod.getDeclaredAnnotation(RequestMapping.class);
|
|
|
if (methodRequestMapping != null && methodRequestMapping.value() != null && methodRequestMapping.value().length > 0) {
|
|
|
methodRequestMappingValue = methodRequestMapping.value()[0];
|
|
|
}
|
|
|
|
|
|
if (StringUtils.isNotBlank(classRequestMappingValue) || StringUtils.isNotBlank(methodRequestMappingValue)) {
|
|
|
return classRequestMappingValue + methodRequestMappingValue;
|
|
|
} else {
|
|
|
return clazz.getName() + '_' + targetMethod.getName();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private int increase(String autoDownGradeKey, long expireInSeconds) {
|
|
|
if (!searchRedis.searchRedisTemplate.hasKey(autoDownGradeKey)) {
|
|
|
// 回调 计数器使用者, 初始化计数器
|
|
|
String initialValue = String.valueOf(0);
|
|
|
// 如果已经被初始化过, 则不用再初始化, 因为其他线程可能已经进行了 increase, 所以必须使用 setIfAbsent
|
|
|
searchRedis.searchValueOperations.setIfAbsent(autoDownGradeKey, initialValue);
|
|
|
// 设置有效期, redis所有的key, 必须设置有效期
|
|
|
searchRedis.searchRedisTemplate.longExpire(autoDownGradeKey, expireInSeconds, TimeUnit.SECONDS);
|
|
|
}
|
|
|
// 原子性对值修改delta数值
|
|
|
return searchRedis.searchValueOperations.increment(autoDownGradeKey, 1).intValue();
|
|
|
}
|
|
|
|
|
|
private int decrease(String autoDownGradeKey) {
|
|
|
return searchRedis.searchValueOperations.increment(autoDownGradeKey, -1).intValue();
|
|
|
}
|
|
|
|
|
|
} |
...
|
...
|
|