1, the RPC

1.1 RPC definition

The system of Internet companies consists of thousands of large and small services, which are deployed on different machines. The invocation between services needs network communication, and the service consumer needs to write a pile of code related to network communication for each invocation of a service, which is not only complex but also prone to error. Also consider how the old service is called when the new service depends on it, and how the new service is published when other services depend on the new service for others to call. How to solve this problem? The industry generally adopts RPC remote call to implement.

RPC:

Remote Procedure Call Protocol (RPC) allows us to Call a Remote service as if it were a local service, without the caller being aware of the details of network traffic. Such as the service consumer in the execution helloWorldService. SayHello (” sowhat “), in essence is the remote service call. This method is actually RPC, which is widely used in various Internet companies, such as Alibaba’s Dubbo, Dangdang’s Dubbox, Facebook Thrift, Google’s GRPC, Twitter’s Finagle and so on.

1.2 RPC demo

Having said that, let’s implement a simplified version of RPC demo.

1.2.1 Public Interface

public interface SoWhatService {
    String sayHello(String name);  
} 
Copy the code

1.2.2 Service Providers

Interface class implementation

public class SoWhatServiceImpl implements SoWhatService
{
 @Override
 public String sayHello(String name)
 {
  return "Hello?"+ name; }}Copy the code

The service registers external providers

/** * Service registration external provider */

public class ServiceFramework
{
 public static void export(Object service, int port) throws Exception
 {
  ServerSocket server = new ServerSocket(port);
  while (true)
  {
   Socket socket = server.accept();
   new Thread(() ->
   {
    try
    {
     // deserialize
     ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
     // Read the method name
     String methodName =(String) input.readObject();
     // Parameter typeClass<? >[] parameterTypes = (Class<? >[]) input.readObject();/ / parameters
     Object[] arguments = (Object[]) input.readObject();
     // Find a way
     Method method = service.getClass().getMethod(methodName, parameterTypes);
     // Call the method
     Object result = method.invoke(service, arguments);
     // Return the result
     ObjectOutputStream output = newObjectOutputStream(socket.getOutputStream()); output.writeObject(result); } catch (Exception e) { e.printStackTrace(); } }).start(); }}}Copy the code

Service operation

public class ServerMain
{
 public static void main(String[] args)
 {
  // The service provider exposes the interface
  SoWhatService service = new SoWhatServiceImpl();
  try
  {
   ServiceFramework.export(service, 1412); } catch (Exception e) { e.printStackTrace(); }}}Copy the code

1.2.3 Service caller

Dynamic proxies invoke remote services

/** * @author sowhat * dynamic proxy calls remote service */
public class RpcFunction
{
 public static <T> T refer(Class<T> interfaceClass, String host, int port) throws Exception
 {
  return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), newClass<? >[]{interfaceClass},new InvocationHandler()
    {
     @Override
     public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable
     {
      // Specify the IP address and port of the provider
      Socket socket = new Socket(host, port);
      ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
      // Pass the method name
      output.writeObject(method.getName());
      // Pass the parameter type
      output.writeObject(method.getParameterTypes());
      // Pass the parameter value
      output.writeObject(arguments);
      ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
      // Read the result
      Object result = input.readObject();
      returnresult; }}); }}Copy the code

A method is called

public class RunMain
{
 public static void main(String[] args)
 {
  try
  {
   // The service caller needs to set the dependency
   SoWhatService service = RpcFunction.refer(SoWhatService.class, "127.0.0.1".1412);
   System.out.println(service.sayHello(" sowhat1412")); } catch (Exception e) { e.printStackTrace(); }}}Copy the code

2. Dubbo frame design

2.1 introduction of Dubbo

Dubbo is an open source tool developed by Alibaba, which is mainly divided into 2.6.x and 2.7.x versions. Is a distributed, high-performance, transparent RPC service framework, providing automatic service registration, automatic discovery and other efficient service governance solutions, can be seamlessly integrated with the Spring framework, it provides six core capabilities:

1. High-performance RPC calls for interface proxy

2. Intelligent fault tolerance and load balancing

3. Automatic service registration and discovery

4. Highly scalable

5. Traffic scheduling during runtime

6. Visual service governance and operation and maintenance

Call the process:

  1. The service Provider Provider starts and registers the services it can provide with Registry.
  2. The service Consumer subscribes to Registry for the required service, parses the meta information provided by Registry, and selects Provider calls from the service through load balancing.
  3. Registry pushes changes to the Provider metadata to the Consumer to ensure that the Consumer has the latest available information.

Note:

  1. The Provider and Consumer record the number and time of calls in memory, and periodically send statistics to the Monitor, which is short-connected.
  2. Monitor and Registry are optional and can be written directly in the configuration file. Provider and Consumer are directly connected.
  3. If the Monitor and Registry are suspended, the Consumer caches the Provider information locally.
  4. The Consumer calls the Provider directly without going through Registry. There is a long connection between Provider and Consumer and Registry.

2.2 Dubbo Framework layering

Overall, Dubbo is divided into three layers, as shown above.

  1. Busines layer: The user provides the interface and implementation and some configuration information.
  2. RPC layer: the real RPC call core layer, encapsulating the whole RPC call process, load balancing, cluster fault tolerance, proxy.
  3. Remoting layer: Encapsulates network transport protocols and data transformations.

If each layer is subdivided further, there are ten layers.

  1. Interface Service layer: This layer is related to business logic and designs corresponding interfaces and implementations according to the services of Provider and consumer.
  2. Configuration layer (Config) : External configuration interface, with ServiceConfig and ReferenceConfig as the center for initial configuration.
  3. Service Proxy layer: transparent Proxy of service interface. Provider and Consumer generate Proxy classes to make service interface transparent, and the Proxy layer implements service invocation and result return.
  4. Service Registration layer (Registry) : encapsulates the registration and discovery of service addresses, centered on service urls.
  5. Routing layer (Cluster) : encapsulates routing and load balancing for multiple providers and Bridges registries, centered on Invoker, with extended interfaces for Cluster, Directory, Router, and LoadBlancce.
  6. Monitoring layer (Monitor) : Monitors the number and time of RPC calls. It centers on Statistics and extends interfaces to MonitorFactory, Monitor, and MonitorService.
  7. Protocal (Protocal) : Encapsulates RPC calls with Invocation and Result centered and extends interfaces to Protocal, Invoker, and Exporter.
  8. Information Exchange layer (Exchange) : encapsulates the request response pattern, synchronous to asynchronous. Based on Request and Response, the expansion interfaces are Exchanger, ExchangeChannel, ExchangeClient and ExchangeServer.
  9. Network Transport Layer (Transport) : Abstract MINA and Netty as the unified interface, Message as the center, extended interfaces are Channel, Transporter, Client, Server and Codec.
  10. Serialize: Reusable tools with Serialization, ObjectInput, ObjectOutput, and ThreadPool extensions.

The call relationship between them can be directly seen in the following official website figure.


3. Dubbo SPI mechanism

Dubbo uses microkernel design + SPI extension technology to build the core framework while meeting user customization needs. So let’s focus on SPI.

3.1 the microkernel

Operating system level microkernels and macrokernels:

  1. Microkernel: A design architecture of the kernel, which consists of as few programs as possible, in order to achieve the most basic functions required by an operating system, including low-level addressing space management, thread management, and interprocess communication. Success stories are QNX systems, such as the blackberry and car market.
  2. Monolithic macro kernel: Implement process management, memory management, file system, process communication, and other functions as the kernel, while the microkernel only retains the most basic functions. Linux is the macro kernel architecture.

Generalized microkernels in Dubbo:

  1. The idea is core system + plug-in, to put it bluntly, is to abstract out the unchanged functions as the core, the change of functions as plug-ins to expand, in line with the open and closed principle, easier to expand, maintenance. For example, the body itself as a core system in the Small Overlord game machine, the game is a plug-in. Vscode, Idea, chrome, etc. are all products of the microkernel.
  2. Microkernel architecture is always the idea of architecture, which can be the framework level or a module design. Its essence is to abstract the changing part into plug-ins, so that it can quickly and easily meet various needs without affecting the overall stability.

3.2 SPI meaning

Mainstream databases include MySQL, Oracle, DB2, etc. These databases are developed by different companies, and their underlying protocols are different. How can they be restricted? General is to customize unified interface, no matter the specific implementation, anyway, for the same interface programming. Just use a concrete implementation class when you actually use it, the question is where do you find that implementation class? At this point, the agreed rules are used to write the implementation class to the specified location.

SPI, also known as the Service Provider Interface, is a Service discovery mechanism. It will look for files in the META-INF/services folder of the ClassPath path and automatically load the classes defined in the files.

3.3 SPI demo

Interface:

package com.example.demo.spi;

public interface SPIService {
    void execute();
}
Copy the code

Implementation class 1:

public class SpiImpl1 implements SPIService{
 @Override
    public void execute() {
        System.out.println("SpiImpl1.execute()"); }}Copy the code

Implementation class 2:

public class SpiImpl2 implements SPIService{
 @Override
    public void execute() {
  System.out.println("SpiImpl2.execute()"); }}Copy the code

Configure paths

Call load class

package com.example.demo.spi;
import sun.misc.Service;
import java.util.Iterator;
import java.util.ServiceLoader;

public class Test {
    public static void main(String[] args) {    
        Iterator<SPIService> providers = Service.providers(SPIService.class);
        ServiceLoader<SPIService> load = ServiceLoader.load(SPIService.class);

        while(providers.hasNext()) {
            SPIService ser = providers.next();
            ser.execute();
        }
        System.out.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --"); Iterator<SPIService> iterator = load.iterator(); while(iterator.hasNext()) { SPIService ser = iterator.next(); ser.execute(); }}}Copy the code

3.4 SPI source tracking

Serviceloader. load(SPIService. Class)Iterator.hasnext () and iterator.next() call the following:

3.5 Disadvantages of the Java SPI

  1. Instead of loading on demand, the Java SPI loads all available extension points at once, many of which are not needed and waste system resources.
  2. The method of obtaining an implementation class is not flexible. The method can only be obtained in the form of Iterator. The corresponding implementation class cannot be obtained according to a parameter.
  3. Without SUPPORT for AOP and dependency injection, the JAVA SPI may lose information about loading extension point exceptions, making tracing problems difficult.

3.6 Dubbo SPI

Dubbo implements an SPI that instantiates specified implementation classes by name and implements IOC, AOP, and adaptive extension SPIs.

key = com.sowhat.value
Copy the code

Dubbo’s convention for configuration file directories differs from the Java SPI in that Dubbo has three categories of directories.

  1. Meta-inf /services/ : SPI configuration files in this directory are used for compatibility with Java SPI.
  2. Meta-inf /dubbo/ : This directory stores user-defined SPI configuration files.
  3. Meta-inf /dubbo/internal/ : This directory stores SPI configuration files used internally by dubbo.

Use it is very simple to introduce a dependency, and then baidu tutorial.

@Test
 void sowhat()
 {
  ExtensionLoader<SPIService> spiService = ExtensionLoader.getExtensionLoader(SPIService.class);        // Get the implementation class object on demand
  SPIService demo1 = spiService.getExtension("SpiImpl1");
  demo1.execute();
 }
Copy the code

3.7 Dubbo SPI source tracing

ExtensionLoader.getExtensionThe whole idea of the method is to check if the cache exists, read the SPI file if it doesn’t, create classes by reflection, and set up dependency injection (DI).

Four important parts:

  1. injectExtension  IOC

Find the set method, according to the parameters to find the dependent object is injected.

  1. WrapperClass AOP

Dubbo automatically wraps classes for you. You only need an extension class whose constructor has one argument and is of the extension interface type to be considered a wrapped class.

  1. Activate

Active has three attributes, group indicating which end the modifier is on, provider or consumer, value indicating that the modifier is activated only when it appears in the URL parameter, and Order indicating the order in which the class is implemented.

3.8 Adaptive Adaptive expansion

Requirement: SPI extensions are loaded according to the configuration and do not want the extensions to be loaded at startup. You want to dynamically select the corresponding extensions according to the parameters at request time. Implementation: Dubbo implements adaptive extensions using the proxy mechanism, generating a proxy class for the interface the user wants to extend through JDK or Javassist compilation, and then creating instances through reflection. Instance will be upon the request of the original method, the parameters that need to extend classes, and then through ExtensionLoader. GetExtensionLoader (type. The class). GetExtension (name) to get the real instance to call, look at a website for the sample.

public interface WheelMaker {
    Wheel makeWheel(URL url);
}
// An adaptive implementation class for the WheelMaker interface
public class AdaptiveWheelMaker implements WheelMaker {
    public Wheel makeWheel(URL url) {
        if (url == null) {
            throw new IllegalArgumentException("url == null");
        }
     // 1. Call the getXXX method of the URL to get the parameter value
        String wheelMakerName = url.getParameter("Wheel.maker");
        if (wheelMakerName == null) {
            throw new IllegalArgumentException("wheelMakerName == null");
        }
        // 2. Call ExtensionLoader's getExtensionLoader to get the loader
        // 3. Call ExtensionLoader's getExtension to load the implementation class as the class name based on the parameters obtained from the URL
        WheelMaker wheelMaker = ExtensionLoader.getExtensionLoader(WheelMaker.class).getExtension(wheelMakerName);
        // 4. Call the concrete method of the implementation class to implement the call.
        returnwheelMaker.makeWheel(URL url); }}Copy the code

The Adaptive annotations can be applied to classes or methods, but they have different implementation logic on classes or methods.

7.8.1 Adaptive annotation is on the class

When Adaptive annotations are on a class, Dubbo will not generate a proxy class for the class. Adaptive annotations are rarely on a class. In Dubbo, only two classes are annotated by Adaptive. AdaptiveCompiler and AdaptiveExtensionFactory respectively, meaning that the extended loading logic is manually coded, which is not our focus.

7.8.2 Adaptive annotation is in the method

When Adaptive annotation is in the method, Dubbo will generate proxy logic for the method, indicating that the extended loading logic needs to be automatically generated by the framework. The general implementation mechanism is as follows:

  1. Load an interface annotated with @adaptive annotation. If it does not exist, the Adaptive mechanism is not supported.
  2. Generate subclass code from a template for the target interface, compile the generated code, and then generate objects for that class through reflection;
  3. In combination with the generated object instance, the configuration of the specified key is obtained through the passed URL object, and then the corresponding class object of the key is loaded. Finally, the call is delegated to the class object.
@SPI("apple")
public interfaceFruitGranter { Fruit grant(); @Adaptive String watering(URL url); } -- -- --// Apple growers
public class AppleGranter implements FruitGranter {
  @Override
  public Fruit grant() {
    return new Apple();
  }
  @Override
  public String watering(URL url) {
    System.out.println("watering apple");
    return "watering finished"; }} -// Banana growers
public class BananaGranter implements FruitGranter {
  @Override
  public Fruit grant() {
    return new Banana();
  }
  @Override
  public String watering(URL url) {
    System.out.println("watering banana");
    return "watering success"; }}Copy the code

Call method implementation:

public class ExtensionLoaderTest {
  @Test
  public void testGetExtensionLoader() {
    // Create a mock URL object
    URL url = URL.valueOf("Dubbo: / / 192.168.0.1:1412? fruit.granter=apple");
    // Get a FruitGranter object with ExtensionLoader
    FruitGranter granter = ExtensionLoader.getExtensionLoader(FruitGranter.class)
      .getAdaptiveExtension();
    // Use this FruitGranter to call its "adaptive annotations" method and get the call result
    String result = granter.watering(url);
    System.out.println(result); }}Copy the code

Generate an inner class as described above. The general call process is as follows:

4. Dubbo service exposure process

4.1 Overview of Service Exposure

Dubbo framework is the URL for the bus, run all state in the process of data and information could be obtained via the URL, such as what current system USES serialization, use what communication, use the information, such as what kind of load balancing is presented in the URL parameter, so in the process of framework, operation need data corresponding to a certain stage, Can be obtained from the parameter list of the URL using the corresponding Key. URL parameters are as follows:

Protocol: indicates various protocols in dubbo, such as: dubbo thrift HTTP username/password: indicates the username or password. Host /port: indicates the host or port. Path: indicates the interface name

protocol://username:password@host:port/path? k=v
Copy the code

Service exposure is divided into three parts in terms of code flow:

  1. Check the configuration and finally assemble the URL.
  2. Expose service to local service and remote service.
  3. Services are registered to the registry.

Service exposure is divided into two steps from the object build transformation:

  1. Encapsulate the service as Invoker.
  2. Convert Invoker to Exporter by contract.

4.2 Service exposure source tracing

  1. After the container is started and Spring IOC is refreshed, onApplicationEvent is called to enable service exposure, ServiceBean.
  2. Export and doExport are splicing to construct URL, so as to shield the details of call, an executable is uniformly exposed, and invoker is obtained through ProxyFactory.
  3. Calling the specific Protocol converts the wrapped Invoker to EXPORTER, where SPI is used.
  4. Then start the server Server, listen on the port, and use NettyServer to create a listen server.
  5. The PROVIDER information is made available to consumers by registering the URL to the registry with the RegistryProtocol.

5. Dubbo service reference process

An executable in Dubbo is an Invoker, so both providers and consumers should look like invokers. As you can see from the demo above, in order to call the remote interface without feeling it, you need a proxy class wrapped around invoker.

There are two opportunities for service introduction:

  1. The hungry type:

By implementing the afterPropertiesSet method in Spring’s InitializingBean interface, the container introduces the service by calling the afterPropertiesSet method of the ReferenceBean.

  1. Lazy (default) :

Lazy is to start the import process only when the service is injected into another class.

There are three ways to reference a service:

  1. Local import: The service is exposed locally to avoid network call overhead.
  2. Direct connection To introduce remote services: Do not start the registry, directly write the remote Provider address for direct connection.
  3. Introducing remote services through the registry: The registry decides how to load balance the invocation of remote services.

Service reference process:

  1. Check the configuration to build map, map to build URL, through the protocol on the URL using adaptive extension mechanism to call the corresponding protocol.refer to get the corresponding invoker, here
  2. To register with the registry, subscribe to the registry, obtain the PROVIDER IP address and other information, and connect to the registry through the shared Netty client.
  3. When there are multiple urls, the invoker is iterated and then encapsulated by a StaticDirectory, and then merged through the cluster to expose only one invoker.
  4. It then builds the proxy that encapsulates the invoker return service reference, which Comsumer then calls.

Call method:

  1. Oneway: does not care whether the request is sent successfully.
  2. Async Async call: Dubbo is naturally asynchronous. When the client calls the request, the ResponseFuture returned is stored in the context. The user can call future.get at any time to get the result. An asynchronous invocation identifies the request with a unique ID.
  3. Sync call: Future. get was called in Dubbo source code, and the user felt that the method was blocked and had to wait for the result to return.

6. Dubbo calls the overall process

Here are some things you might want to consider before invoking:

  1. The consumer and provider agree on communication protocols. Dubbo supports multiple protocols, such as Dubbo, RMI, Hessian, HTTP, and WebService. By default, duBBO protocol is used. The connection belongs to a single long connection and NIO asynchronous communication. It is applicable to transfer a small amount of data (less than 100KB for a single request), but high concurrency.
  2. Convention serialization patterns can be broadly divided into two categories, one is character type (XML or JSON is human-readable but inefficient), and the other is binary stream (data compact and machine friendly). Hessian2 is used by default as the serialization protocol.
  3. When the consumer invokes the provider, it provides the interface, method name, parameter type, parameter value, and version number.
  4. The provider list provides services externally. The load balancer selects a provider to provide services.
  5. The consumer and provider periodically send messages to the Monitor.

General call process:

  1. The client makes a request to invoke the interface, which invokes the generated proxy class. The proxy class generates the RpcInvocation and then invokes the invoke method.
  2. ClusterInvoker gets the list of services in the registry and gives an available Invoker through load balancing.
  3. Serialization and deserialization of network transmission data. Call the network service through netttyServer.
  4. The server business thread pool receives parsed data and invokes an Invoker from exportMap.
  5. Call the real Impl to get the results and return.

Call way:

  1. Oneway: does not care whether the request is sent successfully and consumes the least amount.
  2. Sync call: Future. get was called in Dubbo source code, and the user felt that the method was blocked and had to wait for the result to return.
  3. Async Async call: Dubbo is naturally asynchronous. When the client calls the request, the ResponseFuture returned is stored in the context. The user can call future.get at any time to get the result. An asynchronous invocation identifies the request with a unique ID.

7. Dubbo cluster fault tolerant load balancing

Dubbo introduces Cluster, Directory, Router, LoadBalance, and Invoker modules to ensure the robustness of Dubbo system. Their relationship is shown as follows:

 

  1. Service discovery puts multiple remote calls into Directory and then encapsulates them with Cluster into an Invoker that provides fault tolerance.
  2. The consumer substitute gets an available Invoker from Directory through load balancing and then invokes it.
  3. You can think of Cluster in Dubbo as a big encapsulation of this, with all sorts of robust features.

7.1 Cluster fault Tolerance

Cluster fault tolerance is implemented on the consumer side through Cluster subclasses. The Cluster interface has 10 implementation classes, and each Cluster implementation class creates a corresponding ClusterInvoker object. The core idea is to let the user selectively call the Cluster middle layer, shielding the implementation details behind.

 

Cluster Cluster Invoker role
FailoverCluster FailoverClusterInvoker Failure automatic switching function,The default
FailfastCluster FailfastClusterInvoker One call, failed exception
FailsafeCluster FailsafeClusterInvoker Error calls are logged
FailbackCluster FailbackClusterInvoker If no, try again twice
ForkingCluster ForkingClusterInvoker One task is called concurrently, and one OK is OK
BroadcastCluster BroadcastClusterInvoker Call Invoker one by one until all are available
AvailableCluster AvailableClusterInvoker Use whatever works
MergeableCluster MergeableClusterInvoker Press to combine and return the result

7.2 Intelligent fault-tolerant load balancing

There are generally four load balancing policies in Dubbo.

  1. RandomLoadBalance: weighted randomness, its algorithm idea is simple. Assume that there is A set of servers = [A, B, C], corresponding weights = [5, 3, 2], the total weight is 10. Now, these weight values are tiled on the one-dimensional coordinate values. The interval [0, 5) belongs to server A, the interval [5, 8) belongs to server B, and the interval [8, 10) belongs to server C. Then generate a random number in the range of [0, 10) through the random number generator, and calculate which range this random number will fall on. Default implementation.
  2. LeastActiveLoadBalance: A minimum number of active load balancing, the provider of choice now calls for active at least call, active call number indicating that it was easy, now less and active number from 0 to add up to a request to the active number of + 1, a request processing is completed the active number 1, so the number of active less can also be a disguised form of processing.
  3. RoundRobinLoadBalance: Weighted polling load balancing. For example, there are two servers A and B, and the call sequence of the polling is A, B, A, and B. If the weight of A is 2:1, the call sequence is A, A, B, A, and B.
  4. ConsistentHashLoadBalance: consistent Hash Load balancing: generates a Hash value based on server IP addresses, projects the Hash value to the ring as a node, and searches for the first node whose Hash value is greater than or equal to the key clockwise when the key is searched. Generally speaking, virtual nodes are also introduced to make the data more scattered, so as to avoid data tilt to overwhelm a node. Dubbo has 160 virtual nodes by default.

7.3 Intelligent Fault Tolerance Service catalog

You can think of Directory as a collection of the same service Invoker, with the RegistryDirectory class at its core. It has three functions.

  1. Get the invoker list from the registry.
  2. Monitor changes in the registry invoker, invoker up and down.
  3. Refresh the Invokers list to the services directory.

7.4 Intelligent fault tolerant service routing

A service route is a routing rule that specifies which service providers a service consumer can invoke. Conditional routing rules consist of two conditions for matching service consumers and providers, respectively. For example, here’s a rule:

host = 10.20153.14. => host = 10.20153.12.
Copy the code

This rule indicates that a service consumer with IP 10.20.153.14 can only invoke the service on the machine with IP 10.20.153.12, but not on other machines. Conditional routing rules are in the following format:

[Service consumer matching condition] => [Service provider matching condition]Copy the code

If the service consumer match condition is empty, the service consumer is not restricted. If the service provider match condition is empty, the service is disabled for some service consumers.

8. Design RPC

After reading through the general implementation of Dubbo, you can see that an RPC framework needs the following:

  1. Service registration and discovery of the same, you can use ZooKeeper or Redis to implement.
  2. Then when the consumer makes a request, your interface programming uses a dynamic proxy to make the call.
  3. Multiple providers provide the same service.
  4. Finally choose a machine after you agree on a good communication protocol ah, how to serialize and deserialize?
  5. Bottom layer with ready-made high performance Netty framework NIO mode to achieve bai.
  6. There is monitor after the service is started.

PS :

I feel there is nothing particularly easy to write, because Dubbo official documents have everything, you said you can’t read English, then you must understand Chinese.

reference

Dubbo interview questions: sowhat.blog.csdn.net/article/det… The Adaptive tutorial: https://blog.csdn.net/weixin_33967071/article/details/92608993 Dubbo video: https://b23.tv/KVk0xo Dubbo demo: Mp.weixin.qq.com/s/FPbu8rFOH… DoExportUrlsFor1Protocol a: https://www.cnblogs.com/hzhuxin/p/7993860.html


Phase to recommend

Interviewer: Just ask these 13 questions about Spring

JAVA concurrent 12 moves, can you catch?

Big luck: aircast ten JVM core knowledge points, speed pick up the package

Explain the AQS of Java concurrency step by step

Redis: From the application to the bottom, the article will help you get it done