Dubbo: The Operation Principle of Dubbo

Preface:

At the beginning of introducing Java web, the basic learning is MVC development mode, a project is basically model, view, controller three layers. However, with the increasing number of services in the system, the SOA model is more suitable for current project development. The SOA model is basically Dubbo and Spring Cloud in the Java development process. So let's look at how Dubbo works today.

I. SOA Patterns

A brief introduction to the SOA pattern is helpful for us to understand Dubbo later.

What is the SOA model?

SQA (Service-Oriented Architecture) is a service-oriented architecture that splits different functional units of an application (understood here as services). Under this architecture, the project does not interact directly with the database, but accesses the database by calling interfaces of different services.

What are the advantages of the model?

The most direct benefit of this approach is to address code redundancy if multiple projects access the same table in the database at the same time. For example, access to user tables. We can directly invoke the interface in the user service for development, without requiring each item to write a user list for addition, deletion and modification. In addition to this, the benefits of SOA are that it enables developers to architect the entire business system in a faster, more reliable and more reusable manner. Compared with the previous MVC development model, the system based on SOA architecture can more calmly face the rapid changes of business.

SOA schematic diagram:

II. Basic Composition of Dubbo

After talking about SOA, let's take a look at Dubbo's internal architecture. I believe you have seen the following picture more or less:

Many people will miss the sketch of the above line. Here's an explanation.

Purple dashed lines: functions completed at Dubbo startup Blue and blue lines: functions performed during program operation, dashed lines are asynchronous operations, solid lines are synchronous operations

Provider: Provider, service publisher. If we adopt the pattern of SOA development, this is the interface to interact with the database, that is, service is mainly on the producer side.

Consumer: Consumer, invoke the server. Front-end-oriented Controller is mainly here, which can call methods in the producer remotely, and update the call list of consumers in real time when the producer changes. See below for details.

Container: Dubbo container, dependent on Spring container. It's important to note that Dubbo relies on Spring containers. So it must be used in conjunction with Spring.

Registry: Registry. When Container starts, register all available services in Registry. Function: Tell Consumer what services are provided and where the service providers are.

Monitor: Monitor

III. Dubbo Operating Principle

See how Dubbo works from the above schematic diagram:

0.Start: Start the container, which is equivalent to the Provider that starts Dubbo, and create the corresponding directory structure, such as the common interface name in the code, com.learnDubbo.demo.DemoService, create the / dubbo/com.learnDubbo.demo.DemoService directory, then create the providers directory and write it in the providers directory. Your own URL address.

1.Register: After startup, it will go to the registry to register all the services it can provide. That is, the URL addresses of all providers and consumers in the subscription/dubbo/com.learnDubbo.demo.DemoService directory.

2.Subscribe: Consumer not only registers itself at startup. / Users / directories, and subscriptions to... / providers directory, real-time access to its Provider's URL string information. When the service consumer starts up: the / consumers directory is created in the / dubbo/com.learnDubbo.demo.DemoService directory and its URL address is written in the / consumers directory.

3.notify: When the Provider is modified, the registry pushes the message to Consummer. That is, the registry observes the Provider, which uses the observer pattern in the design pattern. Take the Zookeeper Registry as an example, Dubbo has the doSubscribe method in Zookeeper Registry, that is, producer subscription and monitoring. Here's an analysis of the source code to see the subscription process

@Override
    protected void doSubscribe(final URL url, final NotifyListener listener) {
        try {
            if (Constants.ANY_VALUE.equals(url.getServiceInterface())) {//according to URL Get the service interface as*,That's all.
                String root = toRootPath();
                ConcurrentMap<NotifyListener, ChildListener> listeners = zkListeners.get(url);//Fetch URL Lower monitor
                if (listeners == null) {//Create if nonexistent
                    zkListeners.putIfAbsent(url, new ConcurrentHashMap<NotifyListener, ChildListener>());
                    listeners = zkListeners.get(url);
                }
                ChildListener zkListener = listeners.get(listener);//A listener to get subdirectories
                if (zkListener == null) {//If a subdirectory listener is not available, a new one will be created.
                    listeners.putIfAbsent(listener, new ChildListener() {
                        @Override
                        public void childChanged(String parentPath, List<String> currentChilds) {
                            for (String child : currentChilds) {
                                child = URL.decode(child);
                                if (!anyServices.contains(child)) {
                                    anyServices.add(child);
                                    //If consumer Of interface by*,Will subscribe to each url,Logic that triggers another branch
                                    //Here's what it's for./dubbo The callbacks from the following providers when they are added are equivalent to increments
                                    subscribe(url.setPath(child).addParameters(Constants.INTERFACE_KEY, child,
                                            Constants.CHECK_KEY, String.valueOf(false)), listener);
                                }
                            }
                        }
                    });
                    zkListener = listeners.get(listener);
                }
                zkClient.create(root, false);
                //Adding listeners returns a collection of child nodes
                List<String> services = zkClient.addChildListener(root, zkListener);//Subscribe root Subelements in a directory, such as:/dubbo/com.learnDubbo.demo.DemoService/providers
                if (services != null && !services.isEmpty()) {
                    for (String service : services) {
                        service = URL.decode(service);
                        anyServices.add(service);
                        subscribe(url.setPath(service).addParameters(Constants.INTERFACE_KEY, service,
                                Constants.CHECK_KEY, String.valueOf(false)), listener);
                    }
                }
            } else {
                //This is for clarity. interface Subscription logic of
                List<URL> urls = new ArrayList<URL>();
                //For each category Path monitoring
                for (String path : toCategoriesPath(url)) {
                    ConcurrentMap<NotifyListener, ChildListener> listeners = zkListeners.get(url);
                    if (listeners == null) {
                        zkListeners.putIfAbsent(url, new ConcurrentHashMap<NotifyListener, ChildListener>());
                        listeners = zkListeners.get(url);
                    }
                    ChildListener zkListener = listeners.get(listener);
                    if (zkListener == null) {
                        //Encapsulation callback logic
                        listeners.putIfAbsent(listener, new ChildListener() {
                            @Override
                            public void childChanged(String parentPath, List<String> currentChilds) {
                                ZookeeperRegistry.this.notify(url, listener, toUrlsWithEmpty(url, parentPath, currentChilds));
                            }
                        });
                        zkListener = listeners.get(listener);
                    }
                    //Create Nodes
                    zkClient.create(path, false);
                    //Increase callback
                    List<String> children = zkClient.addChildListener(path, zkListener);
                    if (children != null) {
                        urls.addAll(toUrlsWithEmpty(url, path, children));
                    }
                }
                //And will subscribe to URL The following services are monitored and updated in real time Consumer Medium invoke List so that calls can be made. This method will not be expanded.
                notify(url, listener, urls);
            }
        } catch (Throwable e) {
            throw new RpcException("Failed to subscribe " + url + " to zookeeper " + getUrl() + ", cause: " + e.getMessage(), e);
        }
    }

4. invoke: Actually call the functions in Provider according to the obtained Provider address. This is the only way to synchronize, because consumers need to get the data from producers to do the next step, but Dubbo is an RPC framework, the core of RPC is only to know the interface can not know the internal implementation. So the agent design pattern is used in the Consumer side to create a proxy object of the Provider square class. The real function of the Provider can be obtained through the proxy object, which can protect the real function of the Provider.

  invoke partial source code analysis

If you're interested, look at the invoke invocation process

Monitor: Consumer and Provider send statistics to Monitor every 1 minute, including the number of visits, frequency, etc.

IV. SUMMARY

Here is just a slight analysis of the principle of Dubbo, to understand the Dubbo also need to look at the source code. Although many times we are only a user, but to understand the internal operation principle can not only make us better use, but also the internal programming ideas, design patterns are what we need to learn. More analysis of Dubbo's principles will be done later.

Keywords: Java Dubbo Spring Database Zookeeper

Added by doobster on Sun, 25 Aug 2019 15:52:34 +0300