Motan refer 处理流程

Motan refer 简要处理流程

  • 由AnnotationBean的postProcessBeforeInitialization方法开始
// 调用本类的私有方法refer
Object value = refer(reference, method.getParameterTypes()[0]);
// refer方法中调用RefererConfigBean父类的getRef方法
return referenceConfig.getRef();
  • ReferenceConfig类(RefererConfigBean的父类)继续处理
// getRef()只是做了个检测,主要还在其调用的initRef方法中
// 先获取 SimpleConfigHandler
ConfigHandler configHandler = ExtensionLoader.getExtensionLoader(ConfigHandler.class).getExtension(MotanConstants.DEFAULT_VALUE);
// 然后创建集群支持
ClusterSupport clusterSupport = createClusterSupport(refUrl, configHandler, registryUrls);
// 最后通过configHandler完成refer操作
// 这里的proxy是代理方式,Motan好像只支持jdk的代理,所以proxy的值基本上就是 jdk了
ref = configHandler.refer(interfaceClass, clusters, proxy);
  • 先看下createClusterSupport处理流程
// 对于createClusterSupport中一大片代码为了获取 regUrl,实际处理还是在configHandler中
return configHandler.buildClusterSupport(interfaceClass, regUrls);
// SimpleConfigHandler中的处理
public  ClusterSupport buildClusterSupport(Class interfaceClass, List registryUrls) {
        // 创建集群支持类示例
        ClusterSupport clusterSupport = new ClusterSupport(interfaceClass, registryUrls);
        // 初始化
        clusterSupport.init();
        return clusterSupport;
    }
// clusterSupport.init() 处理
// 先是获取集群、负载均衡、HA策略,默认配置获取的是:
// ClusterSpi  ActiveWeightLoadBalance FailoverHaStrategy
prepareCluster();
// 获取url motan://192.168.3.13:0/com.weibo.motan.demo.service.MotanDemoService?group=motan-demo-rpc
URL subUrl = toSubscribeUrl(url);
// 然后注册
// client 注册自己,同时订阅service列表
// 这里是通过ZookeeperRegistryFactory获取ZookeeperRegistry (Registry接口的实现类之一)
Registry registry = getRegistry(ru); 
// 开始订阅
registry.subscribe(subUrl, this);
  • getRegistry(ru) 处理
// 获取注册url:zookeeper://127.0.0.1:2181/com.weibo.api.motan.registry.RegistryService
String registryUri = getRegistryUri(url);
// 如果不存在则通过ZookeeperRegistryFactory createRegistry来创建注册中心
// 这里同时创建了ZkClient
ZkClient zkClient = new ZkClient(registryUrl.getParameter("address"), sessionTimeout, timeout);
// 创建并返回zk注册中心
return new ZookeeperRegistry(registryUrl, zkClient);
// 创建注册中心时,注册状态变化监听事件
IZkStateListener zkStateListener = new IZkStateListener() {
     @Override
     public void handleStateChanged(Watcher.Event.KeeperState state) throws Exception {
        // do nothing
    }

    @Override
    public void handleNewSession() throws Exception {
        LoggerUtil.info("zkRegistry get new session notify.");
        reconnectService();
        reconnectClient();
    }
};
zkClient.subscribeStateChanges(zkStateListener);
  • registry.subscribe(subUrl, this) 处理,主处理在CommandFailbackRegistry中
// url:motan://192.168.3.13:0/com.weibo.motan.demo.service.MotanDemoService?group=motan-demo-rpc
    protected void doSubscribe(URL url, final NotifyListener listener) {
        LoggerUtil.info("CommandFailbackRegistry subscribe. url: " + url.toSimpleString());
        URL urlCopy = url.createCopy();
        CommandServiceManager manager = getCommandServiceManager(urlCopy);
        manager.addNotifyListener(listener);
// 这里订阅节点变化事件:即服务节点(zkClient.subscribeChildChanges(serverTypePath, zkChildListener))
// /motan/motan-demo-rpc/com.weibo.motan.demo.service.MotanDemoService/server
        subscribeService(urlCopy, manager);
//  这里订阅数据变化事件:即命令节点(zkClient.subscribeDataChanges(commandPath, zkDataListener);)
// /motan/motan-demo-rpc/command
        subscribeCommand(urlCopy, manager);
// 这里会去主动获取服务节点下的所有服务列表
// /motan/motan-demo-rpc/com.weibo.motan.demo.service.MotanDemoService/server
        List urls = doDiscover(urlCopy);
        if (urls != null && urls.size() > 0) {
            this.notify(urlCopy, listener, urls);
        }
    }
  • 上述服务URL准备好后,发通知(事件),继续处理ClusterSupport
// ClusterSupport的notify方法
// refer处理,这里的protocol被ProtocolFilterDecorator包装了一层,实际是DefaultRpcProtocol
referer = protocol.refer(interfaceClass, refererURL, u);
// DefaultRpcProtocol 中创建createReferer
return new DefaultRpcReferer(clz, url, serviceUrl);
// 下面就是传输层的处理了
// 在DefaultRpcReferer中获取NettyEndpointFactory,并创建NettyClient客户端
// 然后执行referer(DefaultRpcReferer)初始化
// 调用client.open(); 完成NettyClient的各种配置初始化等
  • 再看一下configHandler.refer(interfaceClass, clusters, proxy)处理
    @Override
    public  T refer(Class interfaceClass, List> clusters, String proxyType) {
    // Motan这里只有JdkProxyFactory
    ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getExtension(proxyType);
    // 通过JdkProxyFactory获取代理
    return proxyFactory.getProxy(interfaceClass, new RefererInvocationHandler(interfaceClass, clusters));
    }
// 获取代理处理
    private void init() {
        // 这里获取一个开关服务,用于在invoke代理时实现降级功能,实现类LocalSwitcherService
        String switchName =
            this.clusters.get(0).getUrl().getParameter(URLParamType.switcherService.getName(), URLParamType.switcherService.getValue());
        switcherService = ExtensionLoader.getExtensionLoader(SwitcherService.class).getExtension(switchName);
    }
  • 最后将创建的代理赋给ref变量,所以ref实际持有的是Invoke代理类的对象

简单示意图

  • Cluster收到注册中心的全量服务列表后,继续Protocol处理流程
  • Filter 这里对Protocol包装了一层,可以加自己的处理
  • switcher,这是代理层增加的,可用于降级处理
Motan refer 处理流程_第1张图片
client.png

你可能感兴趣的:(Motan refer 处理流程)