Dubb接口短时间内多次调用

问题:提供的dubbo接口,1s内被多次调用

解决方法,添加dubbo拦截器和方法注解

添加注解

/**
 * @author jeremy.li
 * @date 2021/3/1
 * @description dubbo幂等操作注解
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface DubboIdempotent {

    /**
     * 默认为2秒
     * @return
     */
    int time() default 2;
}

  

添加dubbo filter

/**
 * @author jeremy.li
 * @date 2021/3/1
 * @description
 */
@Slf4j
@Activate(group = {Constants.PROVIDER})
public class DubboIdempotentHandlerFilter implements Filter {

    private JedisCluster jedisCluster;

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Object[] arguments = invocation.getArguments();
        String param = convert(arguments);
        String res = null;
        DubboIdempotent declaredAnnotation = null;
        try {
            res = invoker.getInterface().getName() + invocation.getMethodName() + param;
            declaredAnnotation = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes()).getDeclaredAnnotation(DubboIdempotent.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        if (Objects.nonNull(declaredAnnotation)) {
            String key = MD5Utils.MD5(res);
            validSyncMark(key, declaredAnnotation.time());
            log.info("[{}]该接口有幂等处理", new Object[]{invoker.getInterface(), invocation.getMethodName()});
        }
        Result var3 = invoker.invoke(invocation);
        return var3;
    }

    private String convert(Object[] objs) {
        StringBuffer sb = new StringBuffer();
        if (Objects.nonNull(objs)) {
            Arrays.stream(objs).forEach(o -> {
                sb.append(o);
            });
        }
        return sb.toString();
    }

    /**
     * 验证同步标记并添加
     */
    private void validSyncMark(String key, int time) {
        //判断是否在执行
        Long object = getJedisCluster().setnx(key, "1");
        if (object < 1) {
            log.info("[{}]秒内重复的参数不能调用该接口", time);
            throw new RuntimeException(time + "秒内不能重复调用该接口");
        }
        jedisCluster.expire(key, time);
    }

    private JedisCluster getJedisCluster() {
        if (jedisCluster == null) {
            jedisCluster = SpringContextUtil.getBean(JedisCluster.class);
        }
        return jedisCluster;
    }

}

  

 

配置filter

  src/main/resources/META-INF/dubbo添加文件com.alibaba.dubbo.rpc.Filter,内容:

  

dubboIdempotent=com.jeremy.DubboIdempotentHandlerFilter

  

配置dubbo.xml

  

<dubbo:provider filter="dubboIdempotent" />

 扩展:接口幂等

posted @ 2021-03-03 12:00  一入IT岁月催  阅读(542)  评论(0)    收藏  举报