dubbo源碼分析- 集羣容錯之Cluster(一)

一、集羣容錯的配置項

  • failover - 失敗自動切換,當出現失敗,重試其餘服務器(缺省),一般用於讀操做,但重試會帶來更長的延時。
  • failfast - 快速失效,只發起一次調用,失敗當即報錯。一般用於非冪等性寫操做,好比說新增記錄
  • failsafe - 失敗安全,出現異常時,直接忽略,一般用於寫入審計日誌等操做
  • failback - 失敗自動恢復,後臺記錄失敗請求,定時重發,一般用於消息通知操做
  • forking - 並行調用多個服務器,只要一個成功即返回。一般用於實時性要求較高的讀操做,但須要浪費更多的服務器資源。

若是沒有設置集羣的cluster,則默認值爲:failover;在cluster默認爲failover時若是沒有設置retries的值,則默認使用default.retries+1 = 0+1,即重試1次,若是設置了retries的值,則使用配置的值(好比:retries=2則重試2次)。數據庫

若是dubbo的provider所提供的服務中涉及到數據庫操做,最好使用failfast,避免冪等操做拋出異常,或者使用默認cluster時可能致使的數據重試插入多條等狀況。安全

FailoverCluster相關代碼:
    @SuppressWarnings({"unchecked", "rawtypes"})
    public Result doInvoke(Invocation invocation, final List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
        List<Invoker<T>> copyinvokers = invokers;
        checkInvokers(copyinvokers, invocation);
        int len = getUrl().getMethodParameter(invocation.getMethodName(), Constants.RETRIES_KEY, Constants.DEFAULT_RETRIES) + 1; if (len <= 0) {
            len = 1;
        }
        // retry loop.
        RpcException le = null; // last exception.
        List<Invoker<T>> invoked = new ArrayList<Invoker<T>>(copyinvokers.size()); // invoked invokers.
        Set<String> providers = new HashSet<String>(len);
        for (int i = 0; i < len; i++) {
            //Reselect before retry to avoid a change of candidate `invokers`.
            //NOTE: if `invokers` changed, then `invoked` also lose accuracy.
            if (i > 0) {
                checkWhetherDestroyed();
                copyinvokers = list(invocation);
                // check again
                checkInvokers(copyinvokers, invocation);
            }
            Invoker<T> invoker = select(loadbalance, invocation, copyinvokers, invoked);
            invoked.add(invoker);
            RpcContext.getContext().setInvokers((List) invoked);
            try {
                Result result = invoker.invoke(invocation);
                if (le != null && logger.isWarnEnabled()) {
                    logger.warn("Although retry the method " + invocation.getMethodName()
                            + " in the service " + getInterface().getName()
                            + " was successful by the provider " + invoker.getUrl().getAddress()
                            + ", but there have been failed providers " + providers
                            + " (" + providers.size() + "/" + copyinvokers.size()
                            + ") from the registry " + directory.getUrl().getAddress()
                            + " on the consumer " + NetUtils.getLocalHost()
                            + " using the dubbo version " + Version.getVersion() + ". Last error is: "
                            + le.getMessage(), le);
                }
                return result;
            } catch (RpcException e) {
                if (e.isBiz()) { // biz exception.
                    throw e;
                }
                le = e;
            } catch (Throwable e) {
                le = new RpcException(e.getMessage(), e);
            } finally {
                providers.add(invoker.getUrl().getAddress());
            }
        }
        throw new RpcException(le != null ? le.getCode() : 0, "Failed to invoke the method "
                + invocation.getMethodName() + " in the service " + getInterface().getName()
                + ". Tried " + len + " times of the providers " + providers
                + " (" + providers.size() + "/" + copyinvokers.size()
                + ") from the registry " + directory.getUrl().getAddress()
                + " on the consumer " + NetUtils.getLocalHost() + " using the dubbo version "
                + Version.getVersion() + ". Last error is: "
                + (le != null ? le.getMessage() : ""), le != null && le.getCause() != null ? le.getCause() : le);
    }

二、集羣容錯的配置

  • failover
<!-- Provider side -->
<dubbo:service retries="2" />

<!-- Consumer side -->
<dubbo:reference retries="2" />

<!-- Consumer side,Method -->
<dubbo:reference>
    <dubbo:method name="findFoo" retries="2" />
</dubbo:reference>
  • failfast
<!-- Provider side -->
<dubbo:service cluster="failfast"/>

<!-- Consumer side -->
<dubbo:reference cluster="failfast"/>
  • failsafe
<!-- Provider side -->
<dubbo:service cluster="failsafe"/>

<!-- Consumer side -->
<dubbo:reference cluster="failsafe"/>
  • failback
<!-- Provider side -->
<dubbo:service cluster="failback"/>

<!-- Consumer side -->
<dubbo:reference cluster="failback"/>
  • forking
<!-- Provider side -->
<dubbo:service cluster="forking"/>

<!-- Consumer side -->
<dubbo:reference cluster="forking"/>
相關文章
相關標籤/搜索