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

本文深入剖析了Dubbo的RPC框架核心组件,包括Protocol、Exporter和Invoker接口的作用及其实现原理,展示了这些组件如何协作完成服务的发布和调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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();

 

    /**

     * 暴露远程服务:<br>

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

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

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

     *

     * @param <T> 服务的类型

     * @param invoker 服务的执行体

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

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

     */

    @Adaptive

    <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;

 

    /**

     * 引用远程服务:<br>

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

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

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

     *

     * @param <T> 服务的类型

     * @param type 服务的类型

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

     * @return invoker 服务的本地代理

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

     */

    @Adaptive

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

 

    /**

     * 释放协议:<br>

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

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

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

     */

    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<T> {

     

    /**

     * get invoker.

     *

     * @return invoker

     */

    Invoker<T> getInvoker();

     

    /**

     * unexport.

     *

     * <code>

     *     getInvoker().destroy();

     * </code>

     */

    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<T> extends Node {

 

    /**

     * get service interface.

     *

     * @return service interface.

     */

    Class<T> 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.

     *

     * <code>

     * if (hasException()) {

     *     throw getException();

     * } else {

     *     return getValue();

     * }

     * </code>

     *

     * @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<String, String> 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<String, String> 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.youkuaiyun.com/quhongwei_zhanqiu/article/details/41701689

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值