dubbo source code analysis - Cluster cluster fault tolerance (a)

1, fault-tolerant cluster configuration items

  • failover - failure automatic switching, when a failure occurs, retry another server (the default), usually used for read operations, but retry will bring a longer delay.
  • failfast - fail fast, only to launch a call immediately fails error. Generally used for non-idempotency write operation, for example, new record
  • failsafe - security failure, abnormal, direct ignored, usually audit logs and other operations for writing
  • failback - automatic failure recovery, the background recording request fails, a retransmission timer, the message is typically used to notify the operator
  • forking - call multiple servers in parallel, that is, as long as a successful return. Typically used for higher real-time requirements of a read operation, but more need to waste server resources.

If no cluster Cluster, the default value: failover; if the value of retries is not set, the default is to use the default failover in Cluster default.retries + 0 + 1 = 1, i.e. 1 retry , if set retries values, the configured value is used (for example: retries = 2 retry 2 times).

If the service provider is provided dubbo involved in database operations, Failfast preferably used, to avoid idempotent operation exception is thrown, or the data may lead to the use of the default retry to insert multiple cluster and so on.

FailoverCluster relevant code:
    @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 "

2, fault-tolerant cluster configuration

  • 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"/>

 

Guess you like

Origin www.cnblogs.com/frankyou/p/11419885.html