关于调用远程服务超时, 重复执行的问题。

关于调用远程服务超时, 重复执行的问题。
如图,我在controller层调用微服务的dubboService层,超时时间设置为6秒。
为什么只要超时,service的方法就会重复执行?而且看样子还是多线程执行。
为什么重复执行3次以后就结束了?

img

img

img

dubbo自带了服务超时机制,默认好像是3次吧,可以通过retries修改一下。

【相关推荐】



  • 这篇博客: 自定义异常在service层抛出使用@ControllerAdvice全局捕获不到的问题中的 此篇仅针对使用dubbo远程调用 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:

    近日在service层抛出自定义异常,全局异常捕获一直捕获不到,打了几次断点发现频繁跳到dubbo的ExceptionFilter类中进行解读后才发现问题的所在,下面是源码。

    @Activate(group = Constants.PROVIDER)
    public class ExceptionFilter implements Filter {
    
        private final Logger logger;
    
        public ExceptionFilter() {
            this(LoggerFactory.getLogger(ExceptionFilter.class));
        }
    
        public ExceptionFilter(Logger logger) {
            this.logger = logger;
        }
    
        public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
            try {
                Result result = invoker.invoke(invocation);
                if (result.hasException() && GenericService.class != invoker.getInterface()) {
                    try {
                        Throwable exception = result.getException();
    
                        // directly throw if it's checked exception
                        if (!(exception instanceof RuntimeException) && (exception instanceof Exception)) {
                            return result;
                        }
                        // directly throw if the exception appears in the signature
                        try {
                            Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
                            Class<?>[] exceptionClassses = method.getExceptionTypes();
                            for (Class<?> exceptionClass : exceptionClassses) {
                                if (exception.getClass().equals(exceptionClass)) {
                                    return result;
                                }
                            }
                        } catch (NoSuchMethodException e) {
                            return result;
                        }
    
                        // for the exception not found in method's signature, print ERROR message in server's log.
                        logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()
                                + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()
                                + ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);
    
                        // directly throw if exception class and interface class are in the same jar file.
                        String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());
                        String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());
                        if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)) {
                            return result;
                        }
                        // directly throw if it's JDK exception
                        String className = exception.getClass().getName();
                        if (className.startsWith("java.") || className.startsWith("javax.")) {
                            return result;
                        }
                        // directly throw if it's dubbo exception
                        if (exception instanceof RpcException) {
                            return result;
                        }
    
                        // otherwise, wrap with RuntimeException and throw back to the client
                        return new RpcResult(new RuntimeException(StringUtils.toString(exception)));
                    } catch (Throwable e) {
                        logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost()
                                + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()
                                + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
                        return result;
                    }
                }
                return result;
            } catch (RuntimeException e) {
                logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()
                        + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()
                        + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
                throw e;
            }
        }
    
    }
    

    看完之后就发现dubbo把自定义的异常封装成RuntimeException抛出去了,怪不得我的全局异常处理捕捉不到,至于解决方式就一目了然了,看这几个判断语句就清楚了。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^