Dubbo廣播機制源碼解讀

總結/朱季謙

先前在測試環境遇到過一個問題,即Dubbo廣播機制,在對各個提供者節點進行廣播操作過程中,存在最前面的兩個節點出現異常的情況,但後邊的其他節點仍能正常同步的情況。我以前就知道Dubbo的Broadcast機制,先前概念裏總以爲這是一個當廣播到某個節點若出現異常時,就會直接停止廣播操作,但在Dubbo的廣播機制裏,卻不是這樣。它會先遍歷所有的Invokers調用,若過程出現異常時,只會先將異常先類似日誌一樣記錄下來,等到Invokers遍歷完成後,最後纔會將最後保留的異常進行拋出。

這就能解釋了,爲啥存在兩個節點出現異常的情況下,後面的節點仍能正常被廣播通知到。

接下來,我們簡單看下Dubbo的Broadcast機制源碼,這裏的代碼很好看懂——

接下來,我們簡單看下Dubbo的broadcast機制源碼——

public class BroadcastClusterInvoker<T> extends AbstractClusterInvoker<T> {

    private static final Logger logger = LoggerFactory.getLogger(BroadcastClusterInvoker.class);

    public BroadcastClusterInvoker(Directory<T> directory) {
        super(directory);
    }

    @Override
    @SuppressWarnings({"unchecked", "rawtypes"})
    public Result doInvoke(final Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
        //通過CollectionUtils.isEmpty(invokers)檢查invokers集合是否爲空,若爲空,拋出異常
        checkInvokers(invokers, invocation);
        //類似上下文操作保存invokers
        RpcContext.getContext().setInvokers((List) invokers);
        RpcException exception = null;
        Result result = null;
        //遍歷invoker遠程調用接口服務
        for (Invoker<T> invoker : invokers) {
            try {
                result = invoker.invoke(invocation);
            } catch (RpcException e) {
                //若出現異常,將異常信息進行保存
                exception = e;
                logger.warn(e.getMessage(), e);
            } catch (Throwable e) {
                exception = new RpcException(e.getMessage(), e);
                logger.warn(e.getMessage(), e);
            }
        }
        //等invokers遍歷完成後,若存在異常,再對異常進行拋出
        if (exception != null) {
            throw exception;
        }
        return result;
    }

}

這裏的遍歷操作是單線程進行的,存在一個問題,若invokers數量很龐大,那麼,將會出現廣播耗時的情況,我覺得這裏若invokers數據量過大時,可以通過選擇有返回值的線程池併發執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章