Home  >  Article  >  Java  >  Dubbo source code analysis: Beginner's guide

Dubbo source code analysis: Beginner's guide

Java后端技术全栈
Java后端技术全栈forward
2023-08-23 14:44:32580browse


##If you are already proficient in using Dubbo, then this This article is not suitable for you, but if you want to understand Dubbo and want to learn Dubbo, then it is very suitable for you.

Dubbo source code analysis: Beginner's guide

What is Dubbo?

Dubbo was initially developed by Alibaba and later contributed to Apache, so we will call it ## later. #Apache Dubbo or just call Dubbo.

Dubbo

is a high-performance, lightweight open source service framework.

Correct the pronunciation first:

Incorrect pronunciation: diubo, dubo

Correct pronunciation: |ˈdʌbəʊ|

Dubbo’s six core competencies

  • High performance for interface proxyRPCCall
  • Intelligent fault tolerance and load balancing
  • Service automatic registration and discovery
  • Highly scalable capability
  • Runtime traffic scheduling
  • Visualized service governance and operation and maintenance.

During development, we all like to refer to Dubbo as RPC open source framework.

What is RPC?

RPC is the abbreviation of Remote Procedure Call, which translates to: Remote Procedure Call.

The simple understanding is that one node requests the services provided by another node.

In layman’s terms:

Two servers A and B, deploy an application serverA on server A, and deploy an application serverB on server B. At this time, serverA wants to call a certain method in serverB. Since it is not in the same server, it cannot be called directly. It needs to express the semantics of the call and transmit the call data through the network.

Calling remote methods is just like calling local methods.

Dubbo source code analysis: Beginner's guide

In our development, the calls between two services (services on different servers) are usually Use HTTP REST.

RPC Framework

In fact, there are many RPC frameworks on the market, and Dubbo is just one of them. For example:

  • gRPC is a high-performance, general-purpose open source RPC framework developed by Google. gRPC uses ProtoBuf to define services. ProtoBuf is a data serialization protocol developed by Google with relatively high performance and compression and transmission efficiency. High and the syntax is relatively simple. In addition, gRPC supports multiple languages ​​and can automatically generate client and server function libraries based on languages.
  • Thrift originated at Facebook and, like Dubbo, was later submitted to the Apache Foundation to make Thrift an open source project. Facebook created Thrift to solve the problem of large amounts of data transmission and communication between Facebook systems, as well as the different language environments between systems that require cross-platform issues.
  • Motan is a Java RPC framework open sourced by Sina Weibo. The official document is publicized and has been widely used on the Weibo platform, completing nearly 100 billion calls for hundreds of services every day.
  • ...

Dubbo core character

Let’s do it Take a look at the core roles in the Dubbo architecture:

Dubbo source code analysis: Beginner's guide

This picture comes from the official website. Let’s give a brief introduction to the picture. :

Registry

Registration Center. Responsible for the registration and search of service addresses. The Provider and Consumer of the service only interact with the registration center at startup. The registration center senses the existence of Provider through long connections. When Provider is down, the registration center will immediately push relevant event notifications to Consumer.

Provider

Service provider. When it starts, it will register with the Registry, encapsulate the address of its own service and related configuration information into a URL and add it to ZooKeeper.

Consumer

Service consumer. When it starts, it will subscribe to the Registry. The subscription operation will obtain the Provider registered URL from ZooKeeper and add the corresponding listener in ZooKeeper. After obtaining the Provider URL, Consumer will select one Provider from multiple Provider based on the load balancing algorithm and establish a connection with it, and finally initiate a connection to the Provider 's RPC call. If the Provider URL changes, Consumer will obtain the latest Provider URL information through the listener added in the registration center during the previous subscription process, and make corresponding adjustments, such as disconnection Connect to the downed Provider and establish a connection to the new Provider.Consumer establishes a long connection with Provider, and Consumer will cache Provider information, so once the connection is established, even if the registration center is down, it will not affect the existing connections. Running Provider and Consumer.

Monitor

Monitoring center. Used to count the number of service calls and call time. During the running process, Provider and Consumer will count the number of calls and the call time in the memory, and send statistical data to the monitoring center regularly every minute. The monitoring center does not play a necessary role in the above architecture diagram. The downtime of the monitoring center will not affect the functions of Provider, Consumer and Registry, only the monitoring will be lost. Just data.

It develops obscenely and explodes in the later stage, (you may not pay much attention to it in the early stage, but it is particularly fragrant in the later stage)

Container:

Service running container. It is an independent container because services usually do not require the features of Web containers such as Tomcat and JBoss, so there is no need to use a Web container to load services. The service container is just a simple main method and loads a simple Spring container to expose the service.

Process Description

In the picture above, there are several characters and many lines are drawn. Let’s give a brief explanation of this.

  • The service container is responsible for starting, loading, and running the service provider.
  • When the service provider starts, it registers the services it provides with the registration center.
  • When the service consumer starts, he subscribes to the registration center for the services he needs.
  • The registration center returns the service provider address list to the consumer. If there is a change, the registration center will push the change data to the consumer based on the long connection.
  • The service consumer selects a provider to call from the provider address list based on the soft load balancing algorithm. If the call fails, it selects another provider to call.
  • Service consumers and providers accumulate the number of calls and call times in memory, and regularly send statistical data to the monitoring center every minute.

Dubbo official website

Dubbo’s official website: https://dubbo .apache.org/

Dubbo source code analysis: Beginner's guide

Since Dubbo is developed by Alibaba technical team, so in terms of documentation For us Chinese, it is quite friendly. In one word: cool!

In addition, DubboThere are many things on the official website, so we won’t introduce them one by one here.

It is recommended that everyone go to the official website.

Without further ado, let’s have some fun first!

demo case 1

Let’s start with a case without a registration center.

We build a project and create three module:

  • ##dubbo-demo
  • dubbo-demo-api
  • ##dubbo-demo-provider
  • dubbo-demo-consumer
  • The overall structure of the project is as follows:

Dubbo source code analysis: Beginner's guide

Now, let’s give a brief explanation of the code.

First is the pom dependency:

<!--dubbo的依赖-->
<dependency>
     <groupId>org.apache.dubbo</groupId>
     <artifactId>dubbo</artifactId>
     <version>3.0.4</version>
</dependency>
<!-- provider和consumer共用类-->
<dependency>
     <groupId>com.tian.dubbo</groupId>
     <artifactId>dubbo-demo-api</artifactId>
     <version>1.0-SNAPSHOT</version>
</dependency>

Both the consumer and provider projects need to add these two dependencies.

api

api mainly defines service interfaces and some tool classes, which are mainly shared by consumers and providers.

In the api we only define one service interface: DemoService

package com.tian.dubbo.service;

public interface DemoService {
    String sayHello(String msg);
}

Then type it into a jar and add it to pom.xml in the consumer and provider projects In dependencies, the last two times can be used.

provider

Create a directory META-INF.spring in the resources directory, and then create an application.xml in the directory with the following content :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!--Dubbo服务名称--> 
    <dubbo:application name="dubbo-provider"/>
    <!--不需要注册到服务注册中心--> 
    <dubbo:registry address="N/A"/>
    <!--端口和协议--> 
    <dubbo:protocol name="dubbo" port="20880"/>
    <!--我们的服务--> 
    <dubbo:service interface="com.tian.dubbo.service.DemoService" ref="demoService"/>
    <bean id="demoService" class="com.tian.dubbo.service.DemoServiceImpl"/>
</beans>

Create a log printing configuration file in the resources directory: log4j.properties

###set log levels###
log4j.rootLogger=debug, stdout
###output to the console###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n

Define a business implementation class: DemoServiceImpl

package com.tian.dubbo.service;

public class DemoServiceImpl implements DemoService {
    public String sayHello(String msg) {
        System.out.println("msg= " + msg);
        return "SUCCESS";
    }
}

Then define a provider startup class: ProviderMain

package com.tian.dubbo;

import org.apache.dubbo.container.Main;

public class ProviderMain {
    public static void main(String[] args) {
        Main.main(args);
    }
}

注意:这里的Main类是Dubbo

最后,我们启动ProviderMain类,日志输出:

Dubbo source code analysis: Beginner's guide

好了,已经启动成功了。

我们继续来看看consumer项目,在项目中,也就是调用我们服务的项目。

consumer

在consumer项目中application.xml配置文件和provider有所区别。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!-- 服务名称-->
    <dubbo:application name="dubbo-consumer"/>
    <!--不需要注册到服务注册中心--> 
    <!-- 通过url直接调用-->
    <dubbo:reference id="demoService"
                     interface="com.tian.dubbo.service.DemoService"
     url="dubbo://127.0.0.1:20880/com.tian.dubbo.service.DemoService"/>
</beans>

这个url地址,我们在provider启动的时候,可以从日志中找到。

日志文件和provider一样,然后就是ConsumerMain启动类了。

package com.tian.dubbo;

import com.tian.dubbo.service.DemoService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ConsumerMain {
    public static void main(String[] args) {
        DemoService demoService = null;
        ApplicationContext context = new ClassPathXmlApplicationContext
                ("classpath:META-INF/spring/application.xml");
        demoService = context.getBean(DemoService.class);
        //调用服务
        System.out.println(demoService.sayHello("tian"));
    }
}

前面,我们已经把provider成功启动了,下面我们就来启动ConsumerMain

Dubbo source code analysis: Beginner's guide

从日志可以看出我们已经成功调用了provider,我们再来看看provider的日志输出:

Dubbo source code analysis: Beginner's guide

也成功的输出了我们想要的。

到此,一个简单的入门无注册中心(通过url直接调用)的方式就完成了。

url is still very useful when developing joint debugging, because it gets rid of the dependence on the registration center.

demo case 2

We have demonstrated no registration center before, now we will demonstrate the registration center.

Dubbo Currently supports almost all registration centers on the market:

  • consul
  • ##zookeeper
  • eureka
  • redis
  • etcd
  • nacos
  • ....
In our actual development, most of the

Dubbo registration centers are used Zookeeper and Nacos.

The following is a demonstration based on

Zookeeper (nacos is similar, which will be mentioned below).

Code level

I modified it based on the previous case. The transformation only needs to adjust two places:

  • consumer和provider中添加pom依赖
  • application.xml中添加注册中心
pom依赖

我们需要在前面demo中consumer和provider的pom.xml中添加Zookeeper的依赖:

<dependency>
     <groupId>org.apache.dubbo</groupId>
     <artifactId>dubbo-dependencies-zookeeper</artifactId>
     <version>3.0.4</version>
     <type>pom</type>
</dependency>
provider端

在provider项目中我们需要调整:

<dubbo:registry address="N/A"/>

改成:

<dubbo:registry address="zookeeper://127.0.0.1:2181" timeout="10000"/>

这个timeout建议配上,我这里其实没必要配,因为dubbo服务和Zookeeper都在我本地。

然后我们启动provider项目:

Dubbo source code analysis: Beginner's guide

看到我们的项目已经启动成功,并且已经注册到Zookeeper上了。

我们可以使用Zookeeper的可视化工具,看看注册上去的信息。

Dubbo source code analysis: Beginner's guide

我们再看看consumer端的调整。

consumer端

我们需要在application.xml中添加

<dubbo:registry address="zookeeper://127.0.0.1:2181" timeout="10000"/>

同时,去掉reference中的url:

<dubbo:reference id="demoService"
                     interface="com.tian.dubbo.service.DemoService"
     url="dubbo://127.0.0.1:20880/com.tian.dubbo.service.DemoService"/>

因为是通过Zookeeper注册中心拿到地址,所以这里的url就可以去掉了。

最后,启动ConsumerMain类:

Dubbo source code analysis: Beginner's guide

可以看到我们也成功调用服务,另外也有大量的Zookeeper日志。

到此,说明,我们的Zookeeper为注册中心的demo案例也成功了。

注意:provider和consumer项目都需要依赖相关jar包(api、zookeeper、dubbo)

其他

关于Nacos,我们这里就不演示了,因为太简单了,如果你把Nacos搭建好了后,直接配置就好了。

<dubbo:registry address="nacos://127.0.0.1:8848" timeout="10000"/>

就是把address地址改一下就可以了。

Nacos 的演示,我们下一篇文章中见。

总结

本文分享了Dubbo入门案例的两个版本:无注册中心和Zookeeper注册中心。

The above is the detailed content of Dubbo source code analysis: Beginner's guide. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:Java后端技术全栈. If there is any infringement, please contact admin@php.cn delete