1. Once you get the InvokeInvocationHandle, call the invoke () method

2. Execute if the invoke method is an Object method, and then call MockClusterInvoker’s invoke () method

MockClusterInvoker contains it

  • Directory– “RegistryDirectory”
  • The next invoker – > FailOverClusterInvoker
  • Encapsulate the method name and parameters as RpcInvocation

3. Enter the MockClusterInvoker Invoke () method (this class does service degradation)

  • Get “mock” configuration items that can be configured in a variety of ways
  • Without mock, the invoke () method of the next Invoker is called
  • If the mock value starts with force, call mock Invoker directly to perform the local mock logic
  • The original Invoker is invoked, and an RPC call is made, which is thrown if it is a business exception, or fail-mock logic is executed if it is a non-business exception, and mock Invoker is invoked to execute the local logic

4. The next Invoker is FailOverClusterInvoker

  • First go to the invoke method of the parent class AbstractClusterInvoker, the template method
  • Get the LoadBalance object

4.1 How do I Obtain load Balancing Objects?

  • The list (invocation) gets all service provider Invoker collections in the service RegistryDirectory

4.1.1 How do I put all Invoker collections of service providers in the service catalog?

  • The list method is in the parent class AbstractDirectory, the template method, and then the doList(Invocation) method calls the specific policy (RegistryDirectory– doList() method).

4.1.1.1 Access to the RegistryDirectory doList method (which contains urls and collections of all invokers, methods and two maps of all invokers)

  • Get methodInvokerMap, which is a mapping of methods to Invoker,

First according to: method name. The first argument gets all invokers, if empty, from the map using the method name, if empty, gets * all of the Invokers, if empty, loop through the map, get the first one, and return so all of the Invokers are retrieved, return the previous step

4.1.1.2 All Invoker sets are obtained according to the service directory, then Route. Route (List Invokers) Route filtering is performed

ConditionRoute = conditionroute. route = conditionroute. route = conditionroute. route = conditionroute. route = conditionroute. route

4.1.2 Spi is used to obtain the load balancing policy from the method, which is random by default

  • Set the invocation number (id, atom-increment) to the Attachment for the invocation asynchronously
  • Invocation of doInvoker (Invocation of Invokers, loadBalance)

5. Enter the doInvoker of FailOverClusterInvoker

public Result doInvoke(Invocation invocation, final List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException { List<Invoker<T>> copyinvokers = invokers; // Check whether the CopyInvokers invocation is empty. If it is empty, then raise the checkInvokers(Copyinvokers, Invocation) exception; Constants.DEFAULT_RETRIES = 2 int len = getUrl().getMethodParameter(invocation.getMethodName(), Constants.RETRIES_KEY, Constants.DEFAULT_RETRIES) + 1; if (len <= 0) { len = 1; } // Retry loop. // Save the last call exception RpcException = null; Invoked = new ArrayList<Invoker<T>>(copyInvokers.size ())); 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: Invoked - If 'invokers' changed, then' invokers' also lose accuracy. // Re-select while retry to avoid the invoker list being changed while retry. The invoked judgment fails if the list changes because the Invoker example has changed if (I > 0) {checkWhetherDestroyed(); // Get all available invokers from Directory based on the Invocation information copyinvokers = list(Invocation); // Check again // Check checkInvokers(Vice versa); } // select an Invoker Invoker<T> Invoker = select(loadbalance, invocation, copyinvokers, invoked) based on the load balancing mechanism; // Save the Invoker invoked. Add (Invoker) for each invocation; Invoked; // Set the invoked Invoker collection into the Context rpcContext.getContext ().setInvokers((List) invoked); Invocation Result Result = invocation. Invoke (Invocation); // During the retry process, the last call exception information is output as a WARN level log 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) {RpcException = new RpcException(LLDB message (), e); } finally { providers.add(invoker.getUrl().getAddress()); Throw new RpcException(le!) 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); }Copy the code