Spring Boot Integration Apache Dubbo

Apache Dubbo is a high performance, lightweight, open source Java RPC framework that provides three core capabilities: Interface-oriented remote method calls, smart fault tolerance and load balancing, and automatic service registration and discovery.

Note that it is Apache Dubbo, not Alibaba Dubbo anymore.Simply put, Alibaba handed over Dubbo to the Apache open source community for maintenance.See dubbo-spring-boot-project

Spring Boot Series: Integrating Alibaba Dubbo

1. Description of examples in this paper

1.1 Framework Version

  • Dubbo Version
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.7.5</version>
</dependency>
  • Spring Boot Version
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.1.RELEASE</version>
    <relativePath/>
</parent>

1.2 Modular Relationships

  • Root project order: Manage project information;
  • Subproject order-api: Defines the interface, parameters, and result set of the response result for the RPC service;
  • Subproject order-provider: Provider side of RPC service;
  • Subproject order-consumer: The consumer side of the RPC service, which is actually invoked by other services during development

2. Root Project

2.1 Create project order

To distinguish this from the Dubbo project of the older version of alibaba, the file name is apache-dubbo-demo and the maven project name is order.

The main purpose of the project is to define project information, manage the entire project dependent versions, and so on, so the src directory is not needed.

2.2 pom.xml

Both <dependency management>and <dependencies>are used for dependency management in the root project.

  1. <dependencyManagement>: Declare global dependencies, which inherit dependencies when a subproject specifies a reference;
  2. <dependencies>: Declares global dependencies, and subprojects directly automatically inherit dependencies.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- Parent Reference -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath/>
    </parent>

    <!-- Essential information -->
    <groupId>cn.van.order</groupId>
    <artifactId>order</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>${project.artifactId}</name>
    <description>Apache Dubbo Root Project</description>

    <!--To configure-->
    <properties>
        <java.version>1.8</java.version>
        <dubbo.version>2.7.5</dubbo.version>
        <zookeeper.version>3.4.14</zookeeper.version>
    </properties>

    <!-- Subprojects -->
    <modules>
        <module>order-api</module>
        <module>order-provider</module>
        <module>order-consumer</module>
    </modules>

    <!--Declare global dependencies (subprojects need to display references to inherit dependencies)-->
    <dependencyManagement>
        <dependencies>
            <!-- dubbo-start rely on -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>${dubbo.version}</version>
            </dependency>
            <!--zookeeper Registry clients are introduced using curator Client -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-zookeeper</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <exclusions>
                    <exclusion>
                        <artifactId>slf4j-log4j12</artifactId>
                        <groupId>org.slf4j</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!--Declare global dependencies (subprojects do not need to display references, automatically inherit dependencies)-->
    <dependencies>
        <!-- spring boot rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <!-- Packaging Plugins -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3. order-api

3.1 Project Dependency

No more dependencies, so it's simple.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>cn.van.order</groupId>
        <artifactId>order</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <groupId>cn.van.order</groupId>
    <artifactId>order-api</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>${project.artifactId}</name>
    <description>dubbo Public Projects</description>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.2 Encapsulate RPC Result Set

  • Encapsulate a return code enumeration class ResultCodeEnum.java first
public enum ResultCodeEnum {
    /*** General Section 100 - 599***/
    // Successful Request
    SUCCESS(200, "successful"),
    
    /*** Here error codes can be separated at different zones for different modules, for example: ***/

    // The range 1000-1999 indicates a user module error
    // Range 2000-2999 indicates an order module error
    // The range 3000-3999 indicates a commodity module error
    // . . . 

    ORDER_NOT_FOUND(2000, "order not found"),
    ;
    /**
     * Response Status Code
     */
    private Integer code;
    /**
     * Response information
     */
    private String message;

    ResultCodeEnum(Integer code, String msg) {
        this.code = code;
        this.message = msg;
    }

    public Integer getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
  • Encapsulate an RPC response result set RpcResult.java first
public class RpcResult <T> implements Serializable {

    /**
     * Is response successful
     */
    private Boolean success;
    /**
     * Response Status Code
     */
    private Integer code;
    /**
     * Response data
     */
    private T data;
    /**
     * error message
     */
    private String message;

    // Constructor Start
    /**
     * Parameterless constructors (constructors are private and cannot be created externally)
     */
    private RpcResult() {
        this.code = 200;
        this.success = true;
    }
    /**
     * Parametric constructor
     * @param obj
     */
    private RpcResult(T obj) {
        this.code = 200;
        this.data = obj;
        this.success = true;
    }

    /**
     * Parametric constructor
     * @param resultCode
     */
    private RpcResult(ResultCodeEnum resultCode) {
        this.success = false;
        this.code = resultCode.getCode();
        this.message = resultCode.getMessage();
    }
    // Constructor End

    /**
     * Universal return succeeded (no results returned)
     * @param <T>
     * @return
     */
    public static<T> RpcResult<T> success(){
        return new RpcResult();
    }

    /**
     * Return success (with results)
     * @param data
     * @param <T>
     * @return
     */
    public static<T> RpcResult<T> success(T data){
        return new RpcResult<T>(data);
    }

    /**
     * Universal return failed
     * @param resultCode
     * @param <T>
     * @return
     */
    public static<T> RpcResult<T> failure(ResultCodeEnum resultCode){
        return  new RpcResult<T>(resultCode);
    }

    public Boolean getSuccess() {
        return success;
    }

    public void setSuccess(Boolean success) {
        this.success = success;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return "RpcResult{" +
                "success=" + success +
                ", code=" + code +
                ", data=" + data +
                ", message='" + message + '\'' +
                '}';
    }
}

3.3 Write an RPC interface

public interface OrderDubboService {
    RpcResult<OrderDomain> getOrder();
}

The entity OrderDomain.java is fairly simple, as detailed in the Github repository.

4. order-provider

This subproject is a service-type project that registers interface services with the zookeeper registry for consumption.

4.1 Project Dependency

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>cn.van.order</groupId>
        <artifactId>order</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <groupId>cn.van.order</groupId>
    <artifactId>order-provider</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>${project.artifactId}</name>
    <description>Dubbo Service Provider</description>

    <dependencies>
        <dependency>
            <groupId>cn.van.order</groupId>
            <artifactId>order-api</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <!-- zookeeper rely on -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <version>${dubbo.version}</version>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

4.2 Service Implementation Interface

@Service
public class OrderDubboServiceImpl implements OrderDubboService {
    
    @Override
    public RpcResult<OrderDomain> getOrder() {
        return RpcResult.success(new OrderDomain(1, 10086, LocalDateTime.now()));
    }
}

Be careful:
@Service is a comment below the dubbo package, not inside Spring.

4.3 Project Configuration

  1. The configuration of dubbo starts directly with dubbo and no longer with Spring.
  2. base-packages: Specifies the path to the interface implementation.
server:
  # Service Port
  port: 7777
spring:
  application:
    name: order-provider
# Dubbo-related configuration (dubbo configuration no longer begins with Spring)
dubbo:
  application:
    # apply name
    name: order-provider
  scan:
    # Interface implementer (service implementation) package
    base-packages: cn.van.order.service.impl
  # Registry Information
  registry:
    address: zookeeper://127.0.0.1:2181
  protocol:
    # Protocol Name
    name: dubbo
    # Protocol Port
    port: 20880

5. order-consumer

This sub-project is a consumer project, such as commodity module, financial module, and so on.

5.1 Project Dependency

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>cn.van.order</groupId>
        <artifactId>order</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <groupId>cn.van.order</groupId>
    <artifactId>order-consumer</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>${project.artifactId}</name>
    <description>Dubbo Consumer</description>


    <dependencies>
        <dependency>
            <groupId>cn.van.order</groupId>
            <artifactId>order-api</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>

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

        <!-- dubbo rely on -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>

        <!-- dubbo Of zookeeper rely on -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <version>${dubbo.version}</version>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

5.2 Test Interface

Simulate an interface to get order details.

@RestController
@RequestMapping("/order")
public class OrderConsumerController {
    @Reference
    OrderDubboService orderDubboService;

    @GetMapping("getOrder")
    public RpcResult getOrder() {
        return orderDubboService.getOrder();
    }
}

Note: @Reference introduces the Dubbo interface, so it is a comment for Dubbo.

5.3 Profile

server:
  port: 7000
spring:
  application:
    name: order-consumer
# dubbo-related configuration
dubbo:
  application:
    name: order-consumer
  registry:
    address: zookeeper://127.0.0.1:2181

6. Testing

Everything is ready, and if the order-consumer's test interface successfully requests data, then the Dubbo service is built successfully.

6.1 Start zookeeper

We chose zookeeper as the registry, so we need to start it before starting the project.

6.2 dubbo-admin

dubbo-admin makes it easy to see if order-provider successfully registered the interface, as detailed in the installation steps apache/dubbo-admin

Default port: 8080.

6.3 Start dubbo-provider

After successful startup, you can dubbo-admin: The interface OrderService has been successfully registered with zookeeper as follows:

The successful registration of the excuse to the registry indicates that the dubbo-provider registration was successful.

6.4 Start order-cosumer

Start the consumer project and request the consumer interface in the browser: http://localhost:7000/order/getOrder And successfully returned the following data:

{
    "success":true,
    "code":200,
    "data":{
        "id":1,
        "orderNum":10086,
        "gmtCreate":"2020-05-06T11:59:45.535"
    },
    "message":null
}

Successfully requesting data from order-provider indicates that Dubbo was successfully built!

7. Summary

The complete code above has been uploaded to Github Welcome to star!

Cultural exchange

  1. Dust Blog
  2. Dust Blog-Gold Excavation
  3. Dust Blog-Blog Park
  4. Dust Blog-CSDN
  5. Github

Tags: Java Dubbo Apache Spring Maven

Posted on Fri, 08 May 2020 12:39:59 -0700 by rashpal