Detailed introduction to Dubbo, API method and SpringBoot method

Hi I'm Shendi


Detailed introduction to Dubbo, API method and SpringBoot method



I have been using the RPC framework written by myself before, because it is written by myself, and its function is not as good as the open source framework on the market, including the Spring Cloud series later. If I still write it by myself, I need to do integration and the like. Huge workload.

Based on the idea of ​​not making wheels without making wheels, I started to learn about Dubbo



Dubbo

Apache Dubbo is an easy-to-use, high-performance WEB and RPC framework. It also provides capabilities, tools, and best practices for building enterprise-level microservices such as service discovery, traffic governance, observability, and authentication.

The microservices developed using Dubbo have native remote address discovery and communication capabilities with each other. Using the rich service governance features provided by Dubbo, service governance demands such as service discovery, load balancing, and traffic scheduling can be realized. Dubbo is designed to be highly scalable, and users can easily implement various custom logics for traffic interception and location selection.



Official document: https://cn.dubbo.apache.org/zh-cn/index.html



RPC, Distributed, Microservices

Here is a brief introduction, RPC is Remote Procedure Call (Remote Procedure Call), through RPC, you can make a program call the function of other device programs (through the network)

Distributed means that multiple programs communicate through the network to form a system, usually using RPC to achieve distributed

Microservices split a program into multiple programs, and the programs communicate in a distributed manner.



quick start


start zookeeper

Zookeeper is currently used in official documents, so zookeeper needs to be installed first. For the installation and use of zookeeper, please refer to this article

Detailed introduction to Zookeeper installation, easy to use



Develop microservice applications based on Dubbo API

Any Maven project, edit pom.xmland add the following content

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>3.2.0-beta.4</version>
</dependency>

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-x-discovery</artifactId>
    <version>4.3.0</version>
</dependency>
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.8.0</version>
    <exclusions>
        <exclusion>
            <groupId>io.netty</groupId>
            <artifactId>netty-handler</artifactId>
        </exclusion>
        <exclusion>
            <groupId>io.netty</groupId>
            <artifactId>netty-transport-native-epoll</artifactId>
        </exclusion>
    </exclusions>
</dependency>


Note: Most of the dependent packages use org.apache.dubbo


service provider

Create two new packages, one api, which contains the service interface definition, and one provider, which contains the specific implementation of the service interface

Create a new interface under the api package, the content is as follows

public interface ITest {
    
    

	String sayHi(String name);
	
}

Create a new class in the provider package to implement this interface, and publish the server, the content is as follows

import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;

import demo.api.ITest;

public class Test implements ITest {
    
    

	public static void main(String[] args) {
    
    
		// 定义具体的服务
        ServiceConfig<ITest> service = new ServiceConfig<>();
        service.setInterface(ITest.class);
        service.setRef(new Test());

        // 启动 Dubbo
        DubboBootstrap.getInstance()
                .application("first-dubbo-provider")
                .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
                .protocol(new ProtocolConfig("dubbo", -1))
                .service(service)
                .start()
                .await();
	}

	public String sayHi(String name) {
    
    
		return "hi, " + name;
	}
	
}

The above zookeeper is the zookeeper address, if the string above the port is changed, it should be changed accordingly

Now the service provider can be started, and the console will output a lot of information after startup...

Wait for a while, if you see the following information, it means the startup is successful

Got ping response for session id:…

insert image description here


This thing will be output all the time, it is the heartbeat mechanism log of ZK

Briefly describe the functions implemented above, which is equivalent to providing a sayHi interface. The interface receives a name parameter and returns a string. The content of the string is hi, + the passed name parameter



service consumer

Create a new package clientfor storing clients (consumers)

Create a new class Test2 under the package to subscribe to the provided service and call

The content is as follows

import java.io.IOException;

import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;

import com.alibaba.dubbo.config.ReferenceConfig;

import demo.api.ITest;

public class Test2 {
    
    

	public static void main(String[] args) throws IOException {
    
    
		ReferenceConfig<ITest> reference = new ReferenceConfig<>();
        reference.setInterface(ITest.class);

        DubboBootstrap.getInstance()
                .application("first-dubbo-consumer")
                .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
                .reference(reference);
        
        ITest service = reference.get();
        String message = service.sayHi("dubbo");
        System.out.println("Receive result ======> " + message);
        System.in.read();
	}
	
}

After running, a lot of information is output, and finally the following information can be seen

insert image description here


According to the above code, a simple RPC call through service discovery is implemented. The code is simple, and you can basically know what it means at a glance.



Develop microservice applications based on SpringBoot

Similar to API development, but SpringBoot is characterized by an annotation-based configuration method, which enables rapid development

The example of the official website is the use of Maven multi-module, there are three modules, respectively

  1. interface
  2. provider
  3. consumer

In the above, we know that both the provider and the consumer need to define the interface part, the provider implements the interface, and the consumer uses the interface. In order to share the interface part, the multi-module used in the official example


The IDEA used by the official example, I list the Eclipse process here

(Of course, it is also possible not to use multiple modules, or it can be divided into one project or two projects)

Create a new Maven project, select pom for Packaging , and add the following dependencies to pom.xml

	<properties>
        <dubbo.version>3.2.0-beta.4</dubbo.version>
        <spring-boot.version>2.7.8</spring-boot.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Dubbo -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-bom</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>${spring-boot.version}</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

Then create three new modules, namely

  • demo-consumer (consumer)
  • demo-provider (provider)
  • demo-interface (shared interface)

Right click on the project -> New -> Other -> Maven -> Maven Module

insert image description here


Packaging selects jar and creates a module

Change the pom.xml content of demo-provider and demo-consumer, copy in the content required by SpringBoot, and add the following dependencies

	<dependencies>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-samples-spring-boot-interface</artifactId>
            <version>${project.parent.version}</version>
        </dependency>

        <!-- dubbo -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-reload4j</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- spring boot starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

    </dependencies>

In addition to the above dependencies, it is also necessary to introduce the common part, demo-interface

<dependency>
    <groupId>demo-interface</groupId>
    <artifactId>demo-interface</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

Post a picture of the project

insert image description here


Common part (demo-interface)

The demo-interface module is a common part. Create a new package under src/main/java named demo, and create a new interface named Service under the package.

The behavior used by the provider consumer is defined in the Service, the content is as follows

insert image description here


Because this module only needs to create an interface, the pom basically does not need to introduce any dependencies



service provider (demo-provider)

Both providers and consumers need to introduce common parts, as mentioned above

The demo-provider module is the provider, create a new package named demo.provider, and create a new class under the package named ServerImpl

ServerImpl implements the interface Service provided by the common part (interface), as follows

package demo.provider;

import org.apache.dubbo.config.annotation.DubboService;

import demo.Service;

@DubboService
public class ServiceImpl implements Service {
    
    

	@Override
	public String sayHi(String name) {
    
    
		return "hi, " + name;
	}

}

@DubboServiceThe difference from API-based development is that there is an additional annotation on the class

The @DubboService annotation is an annotation used to mark service provider interfaces. The function of this annotation is to mark an interface as a Dubbo service provider, so that the implementation class of the interface can be registered and exposed by Dubbo as a service that can be called by other services. The interface implementation class marked by the @DubboService annotation will be scanned by the Dubbo framework, and the corresponding service interface proxy object will be automatically generated and registered in the Dubbo registry for other service consumers to call. Using this annotation can simplify the steps of publishing and exposing Dubbo services and improve development efficiency.


Then create a SpringBoot startup class ProviderApplicationwith the following content

@SpringBootApplication
@EnableDubbo
public class ProviderApplication {
    
    

	public static void main(String[] args) {
    
    
		SpringApplication.run(ProviderApplication.class, args);
	}
	
}

An annotation has been added @EnableDubbo. After trying, there is no problem without this annotation (but it is better to add it to avoid other problems)


Modify the configuration file of SpringBoot, because the Maven project I created, then you need to create a new application.properties or application.yml under src/main/resources

properties

dubbo.application.name=demo-provider
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
dubbo.registry.address=zookeeper://${zookeeper.address:127.0.0.1}:2181

yml

dubbo:
  application:
    name: dubbo-springboot-demo-provider
  protocol:
    name: dubbo
    port: -1
  registry:
    address: zookeeper://${
    
    zookeeper.address:127.0.0.1}:2181

In this way, the service provider does a good job



service consumer (demo-consumer)

demo-consumer is a consumer module, create a new package demo.consumer, and create a startup class ConsumerApplication under the package, the content is as follows

package demo.consumer;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {
    
    

	public static void main(String[] args) {
    
    
		SpringApplication.run(ConsumerApplication.class, args);
	}
	
}

Here you need to write a web interface, so you need to add web dependencies in pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>


Create a new class named TestControl with the following contents

package demo.consumer;

import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import demo.Service;

@RestController
public class TestControl {
    
    

	@DubboReference
    private Service service;
	
	@GetMapping("/")
	public String test(String name) {
    
    
		return service.sayHi(name);
	}
	
}

A web interface is defined above, the route is /, the interface receives a parameter name, the interface will call the sayHi function of the service amount, and the name parameter is passed in.

The service here uses @DubboReferenceannotation injection, and calling sayHi is actually equivalent to calling sayHi of the implementation class of demo-provider


I don’t want to understand the principle here, just guess a little bit, according to my thinking, it should be roughly that the provider and the consumer connect to zookeeper, the consumer communicates with the provider through zookeeper, and the consumer uses the object injected by @DubboReference. Guess that RPC sends data to the provider. For example, the class is Service and the function is sayHi, then send a Service|sayHi. After receiving the data, the provider will find the corresponding implementation class, and implement the function of the implementation class and then execute the returned data. , the rest is the details, such as parameters and the like. Of course, I’m just using my ideas to implement such a framework here, and provide a simple idea. To know the details, you still need to look at the source code, documentation and debug


The SpringBoot configuration file is the same as the provider, but server.port is required to set the web port

In this way, the consumer has also done a good job


Obtain Service not through annotations, but through Context

Let’s extend it here. Sometimes annotations cannot be used to inject objects. At this time, you need to obtain provider objects in other ways.

Get the code as follows

ReferenceConfig<Service> referenceConfig = new ReferenceConfig<>();
referenceConfig.setInterface(Service.class);
Service service = referenceConfig.get();


start application

run ProviderApplicationandConsumerApplication


It should be noted that the provider needs to be started before starting the consumer, otherwise the consumer module will report an error and cause the entire program to be Over. This problem is @DubboReferencecaused by annotations. By default, it will check whether the corresponding provider is available at startup. Of course, the check can be canceled through configuration or the like.

There are several solutions

  1. Add the parameter check = false to the annotation, for example@DubboReference(check = false)

  2. Add content to SpringBoot configuration file

    • properties increasedubbo.consumer.check=false

    • yml increase

    •   dubbo:
          consumer:
            check: false
      
  3. Add the following code in the startup class or configuration class

    •   @Bean
        public ConsumerConfig consumerConfig() {
              
              
            ConsumerConfig consumerConfig = new ConsumerConfig();
            consumerConfig.setCheck(false);
            return consumerConfig;
        }
      

After starting, the consumer service will explode some errors, but it does not affect, access the address through the browser, the effect is as follows

insert image description here


problem solved

[DUBBO] qos-server can not bind localhost:22222, dubbo version: 3.2.0-beta.4, current host: 192.168.0.108, error code: 7-4. This may be caused by , go to https://dubbo.apache.org/faq/7/4 to find instructions. 

java.net.BindException: Address already in use: bind
...

Fail to start qos server: , dubbo version: 3.2.0-beta.4, current host: 192.168.0.108, error code: 7-4. This may be caused by , go to https://dubbo.apache.org/faq/7/4 to find instructions. 

java.net.BindException: Address already in use: bind

This error means that the port of the qos service is occupied, because the qos server will be started automatically when started with Dubbo. The default port is 22222. I started the provider and consumer on the same computer above, so I reported this error.

Dubbo's QoS (Quality of Service) server is an independent server, which is used to provide Dubbo service quality assurance and monitor and manage service-related indicators.

It can be solved by modifying the SpringBoot configuration file

properties

# 是否启用,默认启用
dubbo.application.qosEnable=true
# 端口,默认22222
dubbo.application.qosPort=12345
dubbo.application.qosAcceptForeignIp=false


So far, the basic use has been ok




END

Guess you like

Origin blog.csdn.net/qq_41806966/article/details/131589154
Recommended