dubbo集群容错与负载均衡源码解读

https://dubbo.gitbooks.io/dubbo-user-book/preface/architacture.html

首先连接一下概念

整个Dubbo的RPC框架建立在Protocol、Exporter和Invoker这三个接口上,Protocol扩展点定义了一种RPC协议的实现,即如何发布和引用服务,Exporter代表了一个对外暴露的服务,Invoker执行远程调用并返回结果,实现一个协议要同时实现这三个接口。下面先看一下这三个接口,稍微有点抽象。

1. Protocol

Protocol的源码如下,代码的注释已讲的比较清楚,这里可以看到,Dubbo默认使用的协议是dubbo。

 折叠原码

/*

 * Copyright 1999-2011 Alibaba Group.

 

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 

 *      http://www.apache.org/licenses/LICENSE-2.0

 

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */

package com.alibaba.dubbo.rpc;

 

import com.alibaba.dubbo.common.URL;

import com.alibaba.dubbo.common.extension.Adaptive;

import com.alibaba.dubbo.common.extension.SPI;

 

/**

 * Protocol. (API/SPI, Singleton, ThreadSafe)

 *

 * @author william.liangf

 */

@SPI("dubbo")

public interface Protocol {

     

    /**

     * 获取缺省端口,当用户没有配置端口时使用。

     *

     * @return 缺省端口

     */

    int getDefaultPort();

 

    /**

     * 暴露远程服务:

     * 1. 协议在接收请求时,应记录请求来源方地址信息:RpcContext.getContext().setRemoteAddress();

     * 2. export()必须是幂等的,也就是暴露同一个URL的Invoker两次,和暴露一次没有区别。

     * 3. export()传入的Invoker由框架实现并传入,协议不需要关心。

     *

     * @param 服务的类型

     * @param invoker 服务的执行体

     * @return exporter 暴露服务的引用,用于取消暴露

     * @throws RpcException 当暴露服务出错时抛出,比如端口已占用

     */

    @Adaptive

     Exporter export(Invoker invoker) throws RpcException;

 

    /**

     * 引用远程服务:

     * 1. 当用户调用refer()所返回的Invoker对象的invoke()方法时,协议需相应执行同URL远端export()传入的Invoker对象的invoke()方法。

     * 2. refer()返回的Invoker由协议实现,协议通常需要在此Invoker中发送远程请求。

     * 3. 当url中有设置check=false时,连接失败不能抛出异常,并内部自动恢复。

     *

     * @param 服务的类型

     * @param type 服务的类型

     * @param url 远程服务的URL地址

     * @return invoker 服务的本地代理

     * @throws RpcException 当连接服务提供方失败时抛出

     */

    @Adaptive

     Invoker refer(Class type, URL url) throws RpcException;

 

    /**

     * 释放协议:

     * 1. 取消该协议所有已经暴露和引用的服务。

     * 2. 释放协议所占用的所有资源,比如连接和端口。

     * 3. 协议在释放后,依然能暴露和引用新的服务。

     */

    void destroy();

 

}

 

2. Exporter

Exporter代表了一个对外暴露的服务,其源码如下,getInvoker返回调用服务的Invoker,unexport取消该服务的暴露。

 折叠原码

/*

 * Copyright 1999-2011 Alibaba Group.

 

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 

 *      http://www.apache.org/licenses/LICENSE-2.0

 

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */

package com.alibaba.dubbo.rpc;

 

/**

 * Exporter. (API/SPI, Prototype, ThreadSafe)

 *

 * @see com.alibaba.dubbo.rpc.Protocol#export(Invoker)

 * @see com.alibaba.dubbo.rpc.ExporterListener

 * @see com.alibaba.dubbo.rpc.protocol.AbstractExporter

 * @author william.liangf

 */

public interface Exporter {

     

    /**

     * get invoker.

     *

     * @return invoker

     */

    Invoker getInvoker();

     

    /**

     * unexport.

     *

     *

     *     getInvoker().destroy();

     *

     */

    void unexport();

 

}

 

3. Invoker

Invoker用于执行一个RPC调用,其代码如下,getInterface返回它是哪个服务的Invoker,invoker方法用于执行远程调用,并返回执行结果。

 折叠原码

/*

 * Copyright 1999-2011 Alibaba Group.

 

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 

 *      http://www.apache.org/licenses/LICENSE-2.0

 

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */

package com.alibaba.dubbo.rpc;

 

import com.alibaba.dubbo.common.Node;

 

/**

 * Invoker. (API/SPI, Prototype, ThreadSafe)

 *

 * @see com.alibaba.dubbo.rpc.Protocol#refer(Class, com.alibaba.dubbo.common.URL)

 * @see com.alibaba.dubbo.rpc.InvokerListener

 * @see com.alibaba.dubbo.rpc.protocol.AbstractInvoker

 * @author william.liangf

 */

public interface Invoker extends Node {

 

    /**

     * get service interface.

     *

     * @return service interface.

     */

    Class getInterface();

 

    /**

     * invoke.

     *

     * @param invocation

     * @return result

     * @throws RpcException

     */

    Result invoke(Invocation invocation) throws RpcException;

 

}

 

 

Invoker接口扩展自Node接口,Node代表了一个具有URL地址的节点,其源码如下,getUrl返回该节点的URL地址,isAvailable返回该节点当前是否可用,destory用于销毁该节点。

 折叠原码

/*

 * Copyright 1999-2011 Alibaba Group.

 

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 

 *      http://www.apache.org/licenses/LICENSE-2.0

 

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */

package com.alibaba.dubbo.common;

 

import com.alibaba.dubbo.common.URL;

 

/**

 * Node. (API/SPI, Prototype, ThreadSafe)

 *

 * @author william.liangf

 */

public interface Node {

 

    /**

     * get url.

     *

     * @return url.

     */

    URL getUrl();

     

    /**

     * is available.

     *

     * @return available.

     */

    boolean isAvailable();

 

    /**

     * destroy.

     */

    void destroy();

 

}

 

下面看一下Result接口,Result接口代表了RPC调用的执行结果,其源码如下,getValue返回执行结果的值,如果没有执行结果则返回null,getException返回执行过程中发生的异常,如果没有发生异常,则返回null,hasException用于返回是否发生了异常,recreate方法用于重建执行结果,重建的意思就是,模拟执行,然后获取结果,如果执行正常,则返回值,否则抛出异常。三个attachment用于获取执行中的其他附加信息。

 折叠原码

/*

 * Copyright 1999-2011 Alibaba Group.

 

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 

 *      http://www.apache.org/licenses/LICENSE-2.0

 

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */

package com.alibaba.dubbo.rpc;

 

import java.util.Map;

 

/**

 * RPC invoke result. (API, Prototype, NonThreadSafe)

 *

 * @serial Don't change the class name and package name.

 * @see com.alibaba.dubbo.rpc.Invoker#invoke(Invocation)

 * @see com.alibaba.dubbo.rpc.RpcResult

 * @author qianlei

 * @author william.liangf

 */

public interface Result {

 

   /**

    * Get invoke result.

    *

    * @return result. if no result return null.

    */

   Object getValue();

 

   /**

    * Get exception.

    *

    * @return exception. if no exception return null.

    */

   Throwable getException();

 

    /**

     * Has exception.

     *

     * @return has exception.

     */

    boolean hasException();

 

    /**

     * Recreate.

     *

     *

     * if (hasException()) {

     *     throw getException();

     * } else {

     *     return getValue();

     * }

     *

     *

     * @return result.

     * @throws if has exception throw it.

     */

    Object recreate() throws Throwable;

 

    /**

     * @deprecated Replace to getValue()

     * @see com.alibaba.dubbo.rpc.Result#getValue()

     */

    @Deprecated

    Object getResult();

 

 

    /**

     * get attachments.

     *

     * @return attachments.

     */

    Map getAttachments();

 

    /**

     * get attachment by key.

     *

     * @return attachment value.

     */

    String getAttachment(String key);

 

    /**

     * get attachment by key with default value.

     *

     * @return attachment value.

     */

    String getAttachment(String key, String defaultValue);

 

}

 

Invocation表示执行的上下文,其源码如下,getMethodName返回调用的是哪个方法,getParameterTypes返回所要调用的方法的参数类,getArguments返回调用方法时使用的参数,三个attachment方法同样是用于获取一些附加信息,getInvoker返回当前上下文是属于哪个Invoker。

 折叠原码

/*

 * Copyright 1999-2011 Alibaba Group.

 

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 

 *      http://www.apache.org/licenses/LICENSE-2.0

 

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */

package com.alibaba.dubbo.rpc;

 

import java.util.Map;

 

/**

 * Invocation. (API, Prototype, NonThreadSafe)

 *

 * @serial Don't change the class name and package name.

 * @see com.alibaba.dubbo.rpc.Invoker#invoke(Invocation)

 * @see com.alibaba.dubbo.rpc.RpcInvocation

 * @author qian.lei

 * @author william.liangf

 */

public interface Invocation {

 

   /**

    * get method name.

    *

    * @serial

    * @return method name.

    */

   String getMethodName();

 

   /**

    * get parameter types.

    *

    * @serial

    * @return parameter types.

    */

   Class[] getParameterTypes();

 

   /**

    * get arguments.

    *

    * @serial

    * @return arguments.

    */

   Object[] getArguments();

 

   /**

    * get attachments.

    *

    * @serial

    * @return attachments.

    */

   Map getAttachments();

    

   /**

     * get attachment by key.

     *

     * @serial

     * @return attachment value.

     */

   String getAttachment(String key);

    

   /**

     * get attachment by key with default value.

     *

     * @serial

     * @return attachment value.

     */

   String getAttachment(String key, String defaultValue);

 

    /**

     * get the invoker in current context.

     *

     * @transient

     * @return invoker.

     */

    Invoker getInvoker();

 

}

URL

http://www.hiwzc.com/dubbo-url.html

http://youaremoon.iteye.com/blog/2279787

 

调用关系

http://blog.csdn.net/quhongwei_zhanqiu/article/details/41701689

你可能感兴趣的:(dubbo集群容错与负载均衡源码解读)