Skip to content

Instantly share code, notes, and snippets.

@yangl
Last active January 12, 2017 03:48
Show Gist options
  • Save yangl/6247712 to your computer and use it in GitHub Desktop.
Save yangl/6247712 to your computer and use it in GitHub Desktop.
黑名单过滤器,启动一个线程定时同步远程redis黑名单数据至本地JVM内存;
package com.jd.couponservice.service.aspect;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import com.alibaba.dubbo.common.utils.NamedThreadFactory;
import com.jd.couponservice.client.dict.CouponResultCodeDict;
import com.jd.couponservice.client.domain.coupon.CouponResult;
import com.jd.couponservice.client.domain.coupon.CouponSopResult;
import com.jd.data.redis.RedisUtils;
/**
* 黑名单过滤器
*
* @author YANGLiiN
* @date 13-6-17 上午11:28
*/
@Aspect
@Component
public class BlackFilterAspect implements InitializingBean {
/**
* 黑名单缓存key,注意和管理后台一致
*
* com.jd.couponservice.test.controller.BlackUserController
*/
private final String BLACK_USER_KEY = "couponOrderServices:black_users";
private final String ERROR_MSG = "the user %s in the black user list";
// 本地jvm黑名单
private static Set<String> blackUsers = new HashSet<String>();
@Resource
private RedisUtils redisUtils;
private boolean enable = true;
Logger logger = LoggerFactory.getLogger(BlackFilterAspect.class);
@Pointcut("execution(public * com.jd.couponservice.client.service.CouponService.*(..)) || execution(public * com.jd.couponservice.cxfservice.CxfCouponService.getCouponsByPin(..))")
public void blackFilterPointcut() {}
@Around("blackFilterPointcut()")
public Object execDegrade(ProceedingJoinPoint jp) throws Throwable {
MethodSignature ms = (MethodSignature) jp.getSignature();
String methodName = ms.getName();
// 只拦截getAllCouponsWithCheck,getAvailableCoupons这两个优惠券列表api方法
if (enable
&& ("getAllCouponsWithCheck".equals(methodName)
|| "getAvailableCoupons".equals(methodName) || "getCouponsByPin".equals(methodName))) {
Object[] pns = jp.getArgs();
String pin = (String) pns[0];
if (blackUsers.contains(pin)) {
if ("getAllCouponsWithCheck".equals(methodName)) {
CouponSopResult rs = new CouponSopResult();
rs.setSuccess(false);
rs.setResultCode(CouponResultCodeDict.SystemError);
rs.setErrorMsg(String.format(ERROR_MSG, pin));
return rs;
}
if ("getAvailableCoupons".equals(methodName)
|| "getCouponsByPin".equals(methodName)) {
CouponResult rs = new CouponResult();
rs.setSuccess(false);
rs.setResultCode(CouponResultCodeDict.SystemError);
rs.setErrorMsg(String.format(ERROR_MSG, pin));
return rs;
}
}
}
return jp.proceed();
}
@Override
public void afterPropertiesSet() throws Exception {
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("--black user thread factory--",
true));
scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
public void run() {
// 30秒同步一次数据
try {
Set<String> remoteBlackUsers = redisUtils.smembers(BLACK_USER_KEY);
if (remoteBlackUsers != null) {
blackUsers = remoteBlackUsers;
}
}
catch (Throwable t) { // 防御性容错
logger.error("Unexpected error occur at sync black user data, cause: "
+ t.getMessage(),
t);
}
}
},
3,
30,
TimeUnit.SECONDS);
}
public void setEnable(boolean enable) {
this.enable = enable;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment