consumer:

在NettyChannel.send中加断点,显示调用栈

helloService.sayFuck();

provider:

在方法实现里面,加断点得到调用栈

如以上2图,从consumer到provider的步骤一目了然。

consumer对应NettyClient,provider对应NettyServer。

之前对dubbo method的重试次数有点疑惑,在图1的consumer调用栈中,FailoverClusterInvoker<T>.doInvokede方法中有具体处理逻辑,也就是说重试是从consumer发起的。

ProtocolFilterWrapper的buildInvokerChain方法生成filter链:provider和consumer的filter是不同的

public interface Invoker<T> extends Node {
    //我们主要关心这个方法
    Result invoke(Invocation invocation) throws RpcException;
}

//ProtocolFilterWrapper类
private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {
        //dubbo最终会调用的invoker,或者说是我们的业务servlce的代理
    Invoker<T> last = invoker;
    List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
    if (filters.size() > 0) {
        for (int i = filters.size() - 1; i >= 0; i --) {
            final Filter filter = filters.get(i);
            final Invoker<T> next = last;
            //通过创建匿名内部类对象,生成filter链
            //虽然这只是一个匿名内部类对象,这个类有3个属性需要关注:
            //final Invoker<T> invoker 算是业务对象的代理吧
            //final Filter filter 该invoker的filter,filter中有dubbo框架逻辑
            //final Invoker<T> next 把各个匿名invoker链起来
            last = new Invoker<T>() {
                //省略掉其他代码
                public Result invoke(Invocation invocation) throws RpcException {
                    //各filter实现dubbo框架的逻辑    
                    return filter.invoke(next, invocation);
                }
            };
        }
    }
    return last;
}

/**
假定有两个匿名Invoker对象,invoker1和invoker2,invoker1的filter是TimeoutFilter,next是invoker2,
invoker2的filter是ExceptionFilter,next就是业务service代理了。 *
*/ //TimeoutFilter类 @Activate(group = Constants.PROVIDER) public class TimeoutFilter implements Filter { private static final Logger logger = LoggerFactory.getLogger(TimeoutFilter.class); //对应调用语句filter.invoke(next, invocation) public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { long start = System.currentTimeMillis(); //执行next的调用 Result result = invoker.invoke(invocation); long elapsed = System.currentTimeMillis() - start; //可以看出,timeoutFilter只是打印超时日志,并没其他动作 if (invoker.getUrl() != null && elapsed > invoker.getUrl().getMethodParameter(invocation.getMethodName(), "timeout", Integer.MAX_VALUE)) { if (logger.isWarnEnabled()) { logger.warn("invoke time out. method: " + invocation.getMethodName() + "arguments: " + Arrays.toString(invocation.getArguments()) + " , url is " + invoker.getUrl() + ", invoke elapsed " + elapsed + " ms."); } } return result; } } //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; } //当调用这个filter时,参数invoker已经是业务service的代理了 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(); // 如果是checked异常,直接抛出 if (! (exception instanceof RuntimeException) && (exception instanceof Exception)) { return result; } // 在方法签名上有声明,直接抛出 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; } // 未在方法签名上定义的异常,在服务器端打印ERROR日志 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); // 异常类和接口类在同一jar包里,直接抛出 String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface()); String exceptionFile = ReflectUtils.getCodeBase(exception.getClass()); if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)){ return result; } // 是JDK自带的异常,直接抛出 String className = exception.getClass().getName(); if (className.startsWith("java.") || className.startsWith("javax.")) { return result; } // 是Dubbo本身的异常,直接抛出 if (exception instanceof RpcException) { return result; } // 否则,包装成RuntimeException抛给客户端 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; } } }

 附上一张provider buildFilterChain的变量图:

posted on 2017-09-21 17:54  偶尔发呆  阅读(211)  评论(0编辑  收藏  举报