Dubbo Provider 处理请求流程 (2)

开篇

  • 这篇是Dubbo Provider 处理请求流程 (1)的下篇内容,建议有兴趣可以先阅读之前的Dubbo Provider 处理请求流程 (1),能够更好的进行串联。

Dubbo Protocol调用链

Dubbo Provider 处理请求流程 (2)_第1张图片
DubboProtocol调用链
Dubbo Provider 处理请求流程 (2)_第2张图片
DubboProtocol调用栈
  • 调用链核心在于DubboProtocol => xxxFilter => AbstractProxyInvoker。

DubboProtocol调用分析

DubboProtocol

public class DubboProtocol extends AbstractProtocol {

    public static final String NAME = "dubbo";

    public static final int DEFAULT_PORT = 20880;
    private static final String IS_CALLBACK_SERVICE_INVOKE = "_isCallBackServiceInvoke";
    private static DubboProtocol INSTANCE;
    private final Map serverMap = new ConcurrentHashMap(); // 
    private final Map referenceClientMap = new ConcurrentHashMap(); // 
    private final ConcurrentMap ghostClientMap = new ConcurrentHashMap();
    private final ConcurrentMap locks = new ConcurrentHashMap();
    private final Set optimizers = new ConcurrentHashSet();
    //consumer side export a stub service for dispatching event
    //servicekey-stubmethods
    private final ConcurrentMap stubServiceMethodsMap = new ConcurrentHashMap();
    private ExchangeHandler requestHandler = new ExchangeHandlerAdapter() {

        @Override
        public Object reply(ExchangeChannel channel, Object message) throws RemotingException {
            if (message instanceof Invocation) {
                Invocation inv = (Invocation) message;
                // 查找对应的invoker
                Invoker invoker = getInvoker(channel, inv);
               
                // 省略一些无关代码
                RpcContext.getContext().setRemoteAddress(channel.getRemoteAddress());
                return invoker.invoke(inv);
            }
            throw new RemotingException(channel, "Unsupported request: "
                    + (message == null ? null : (message.getClass().getName() + ": " + message))
                    + ", channel: consumer: " + channel.getRemoteAddress() + " --> provider: " + channel.getLocalAddress());
        }
    }


    Invoker getInvoker(Channel channel, Invocation inv) throws RemotingException {

        // 省略非核心代码
        String serviceKey = serviceKey(port, path, inv.getAttachments().get(Constants.VERSION_KEY), inv.getAttachments().get(Constants.GROUP_KEY));

        DubboExporter exporter = (DubboExporter) exporterMap.get(serviceKey);

        if (exporter == null)
            throw new RemotingException(channel, "Not found exported service: " + serviceKey + " in " + exporterMap.keySet() + ", may be version or group mismatch " + ", channel: consumer: " + channel.getRemoteAddress() + " --> provider: " + channel.getLocalAddress() + ", message:" + inv);

        return exporter.getInvoker();
    }
}


public class ProtocolUtils {
    public static String serviceKey(int port, String serviceName, String serviceVersion, String serviceGroup) {
        StringBuilder buf = new StringBuilder();
        if (serviceGroup != null && serviceGroup.length() > 0) {
            buf.append(serviceGroup);
            buf.append("/");
        }
        buf.append(serviceName);
        if (serviceVersion != null && serviceVersion.length() > 0 && !"0.0.0".equals(serviceVersion)) {
            buf.append(":");
            buf.append(serviceVersion);
        }
        buf.append(":");
        buf.append(port);
        return buf.toString();
    }
}
  • DubboProtocol的getInvoker通过serviceKey()方法生成key从exproterMap获取对应的exporter,进而通过exporter.getInvoker获取对应的invoker对象。
  • 通过invoker.invoke()调用,开始进入各类Filter的调用。

ProtocolFilterWrapper

public class ProtocolFilterWrapper implements Protocol {

    private final Protocol protocol;

    public ProtocolFilterWrapper(Protocol protocol) {
        if (protocol == null) {
            throw new IllegalArgumentException("protocol == null");
        }
        this.protocol = protocol;
    }

    private static  Invoker buildInvokerChain(final Invoker invoker, String key, String group) {
        Invoker last = invoker;
        List filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
        if (!filters.isEmpty()) {
            for (int i = filters.size() - 1; i >= 0; i--) {
                final Filter filter = filters.get(i);
                final Invoker next = last;
                // 匿名函数类的写法
                last = new Invoker() {
                    
                    // 省略一些非核心代码

                    @Override
                    public Result invoke(Invocation invocation) throws RpcException {
                        return filter.invoke(next, invocation);
                    }

                    // 省略一些非核心代码
                };
            }
        }
        return last;
    }
}


public class EchoFilter implements Filter {
    @Override
    public Result invoke(Invoker invoker, Invocation inv) throws RpcException {
        if (inv.getMethodName().equals(Constants.$ECHO) && inv.getArguments() != null && inv.getArguments().length == 1)
            return new RpcResult(inv.getArguments()[0]);
        return invoker.invoke(inv);
    }

}
  • ProtocolFilterWrapper通过buildInvokerChain()方法构建调用链,通过调用链层层调用。
  • ProtocolFilterWrapper的Filter链的构造过程使用了匿名函数的一些特性。
  • 以EchoFilter为例子说明Filter的调用方式。

JavassistProxyFactory

public abstract class AbstractProxyInvoker implements Invoker {

    private final T proxy;
    private final Class type;
    private final URL url;

    @Override
    public Result invoke(Invocation invocation) throws RpcException {
        try {
            return new RpcResult(doInvoke(proxy, invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments()));
        } catch (InvocationTargetException e) {
            return new RpcResult(e.getTargetException());
        } catch (Throwable e) {
            throw new RpcException("Failed to invoke remote proxy method " + invocation.getMethodName() + " to " + getUrl() + ", cause: " + e.getMessage(), e);
        }
    }

    protected abstract Object doInvoke(T proxy, String methodName, Class[] parameterTypes, Object[] arguments) throws Throwable;
}


public class JavassistProxyFactory extends AbstractProxyFactory {

    @Override
    @SuppressWarnings("unchecked")
    public  T getProxy(Invoker invoker, Class[] interfaces) {
        return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
    }

    @Override
    public  Invoker getInvoker(T proxy, Class type, URL url) {
        // TODO Wrapper cannot handle this scenario correctly: the classname contains '$'
        final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type);
        return new AbstractProxyInvoker(proxy, type, url) {
            @Override
            protected Object doInvoke(T proxy, String methodName,
                                      Class[] parameterTypes,
                                      Object[] arguments) throws Throwable {
                return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
            }
        };
    }

}
  • JavassistProxyFactory的getInvoker()方法返回AbstractProxyInvoker对象。
  • AbstractProxyInvoker内部调用wrapper对象的invokeMethod()方法进行处理。

Wrapper

package org.apache.dubbo.common.bytecode;

import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import org.apache.dubbo.common.bytecode.ClassGenerator;
import org.apache.dubbo.common.bytecode.NoSuchMethodException;
import org.apache.dubbo.common.bytecode.NoSuchPropertyException;
import org.apache.dubbo.common.bytecode.Wrapper;
import org.apache.dubbo.demo.provider.DemoServiceImpl;

public class Wrapper1 extends Wrapper implements ClassGenerator.DC {
    public static String[] pns;
    public static Map pts;
    public static String[] mns;
    public static String[] dmns;
    public static Class[] mts0;

    public Object invokeMethod(Object object, String string, Class[] arrclass, Object[] arrobject) throws InvocationTargetException {
        DemoServiceImpl demoServiceImpl;
        try {
            demoServiceImpl = (DemoServiceImpl)object;
        }
        catch (Throwable throwable) {
            throw new IllegalArgumentException(throwable);
        }
        try {
            if ("sayHello".equals(string) && arrclass.length == 1) {
                return demoServiceImpl.sayHello((String)arrobject[0]);
            }
        }
        catch (Throwable throwable) {
            throw new InvocationTargetException(throwable);
        }
        throw new NoSuchMethodException(new StringBuffer().append("Not found method \"").append(string).append("\" in class org.apache.dubbo.demo.provider.DemoServiceImpl.").toString());
    }
}
  • wrapper对象是动态生成的类对象,内部直接调用serviceImpl的对象进行处理。

你可能感兴趣的:(Dubbo Provider 处理请求流程 (2))