Dubbo Microservice Architecture Using Redis as Registry (SpringBoot)

title: Dubbo micro-service architecture using Redis as registry (SpringBoot)
date: 2019-07-30 14:06:29
categories:

  • Framework
    author: mrzhou
    tags:
  • SpringBoot
  • redis
  • Dubbo
  • Microservices
  • RPC

Preface

Dubbo, as a high-performance RPC framework, has been widely used in most front-line IT enterprises. Today we will try it. In order to write as little code as possible and make the program simple and clear, we build it based on SpringBook.
Although Dubbo recommends zk as the registry, today we'll try changing Redis.

Demand decomposition

The purpose of this project is to explain the use of Dubbo and Redis, so simplify the business as much as possible. Our consumer calls the service provider to get a simple user information.
Decomposition of business:

  • User-common
  • Service Provider
  • User-consumer

Interface project

In principle, the project is only part of the interface definition, in fact, any dependencies can not be needed, just in order to write less code, here introduced lombok, and then the project packaged and released to the maven repository.
pom.xml

<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>
    <groupId>cn.miw.dubbo</groupId>
    <artifactId>common</artifactId>
    <version>0.0.1</version>
    <dependencies>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Interface definition
UserService.java

package cn.miw.dubbo.api;

import cn.miw.dubbo.model.User;

public interface UserService {
    User findById(Integer id);
}

Entity Definition
User.java

package cn.miw.dubbo.model;

import java.io.Serializable;

import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class User implements Serializable{

    private static final long serialVersionUID = -7001216319830050312L;
    private Integer id;
    private String name;
    private int age;
    
}

Service Provider Project

In this project, the specific service processing logic is implemented and the registration process is completed. This project can integrate some mature orm frameworks. For simple demonstration, its implementation is simply to create an object to return.

  • pom.xml
<?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>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath />
    </parent>
    <groupId>cn.miw.dubbo</groupId>
    <artifactId>user-provider</artifactId>
    <version>0.0.1</version>
    <packaging>jar</packaging>
    <name>demo</name>
    <description>server</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- Introducing Universal Projects -->
        <dependency>
            <groupId>cn.miw.dubbo</groupId>
            <artifactId>common</artifactId>
            <version>0.0.1</version>
        </dependency>
        <!-- Dubbo Need third party packages -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!-- Redis Support packages -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <!-- Dubbo starter -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>
        <!-- Redis starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        
    </dependencies>

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

</project>

This is a SpringBook project, we need to use redis as the registry, so we introduced the relevant starter and support packages, plus Dubbo's starter and support packages.

Let's first look at the simple implementation of the function. Here we need to pay attention to the @Service annotation, which is the annotation in dubbo. Through this annotation, we can realize the process of the specific service layer in the registry. So we need @Component to support it so that it can be managed by Spring.

  • UserServiceImpl.java
package cn.miw.dubbo.server.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alibaba.dubbo.config.annotation.Service;

import cn.miw.dubbo.api.UserService;
import cn.miw.dubbo.model.User;

@Service(version = "1.0")
@Component
public class UserServiceImpl implements UserService {
    
    private static Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    @Override
    public User findById(Integer id) {
        log.info("Received ID: {}",id);
        User user = new User();
        user.setAge(10+id*2);
        user.setName("Zhang San"+id);
        user.setId(id);
        return user;
    }
}

Looking at the startup class, it's very simple, just add the @EnableDubbo annotation, because the project is not a web project, so add a sentence java System.in.read(); to keep it running.

  • ServerApp.java
package cn.miw.dubbo.server;

import java.io.IOException;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;

@SpringBootApplication
@EnableDubbo
public class ServerApp {

    public static void main(String[] args) throws IOException {
        SpringApplication.run(ServerApp.class, args);
        System.in.read();
    }

}

Let's look at the configuration again. This paper points out the location of redis in the registry and points out that the protocol used to provide services is dubbo protocol. The service port is 12345.

  • application.yml
dubbo:
  application:
    id: user-provider
    name: user-provider    
    qosEnable: true
    qosPort: 22223
  registry:
    address: redis://root:pass@192.168.0.116:6379

  protocol:
    name: dubbo
    port: 12345    
    
spring:
  application:
    name: user-provider    

Service caller project

This project relies on only one more web project than the service provider

  • pom.xml
<?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>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath />
    </parent>
    <groupId>cn.miw.dubbo</groupId>
    <artifactId>consumer</artifactId>
    <version>0.0.1</version>
    <packaging>war</packaging>
    <name>user-consumer</name>
    <description>consumer</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- Dubbo and redis Start with the General Section -->
        <dependency>
            <groupId>cn.miw.dubbo</groupId>
            <artifactId>common</artifactId>
            <version>0.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- Dubbo and redis Universal Partial End -->

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

    </dependencies>

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

</project>

To make it as simple as possible, we only have one java file

  • ConsumerApp.java
package cn.miw.dubbo.consumer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;

import cn.miw.dubbo.api.UserService;

@SpringBootApplication
@EnableDubbo
@RestController
public class ConsumerApp {

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

    @Reference(version = "1.0")
    UserService userService;
    
    private static Logger log = LoggerFactory.getLogger(ConsumerApp.class);
    
    @GetMapping("/")
    public Object index(Integer id) {
        log.info("Input ID: {},{}",id,(id==null)?0:id);
        return userService.findById((id==null)?0:id);
    }
}

configuration file

  • application.yml
dubbo:
  application:
    id: user-consumer
    name: user-consumer        
    qosEnable: false
    qosPort: 22224
  registry:
    address: redis://root:pass@192.168.0.116:6379
  consumer:
    timeout: 3000

    
spring:
  application:
    name: user-consumer    

Matters needing attention

  • Since the common project is used by both other projects, please compile and publish it to your own maven warehouse first. If they are developed on the same computer, you only need to install it to the local warehouse. If there are more than one computer or group development, you can publish it to your own group's private warehouse.
  • Before starting the service consumer, please start the service provider, which can run the service provider project at the same time by multiple computers.
  • Start the consumer access http://localhost:8080/view the results through the browser. You can also start multiple consumers to see which services are invoked separately when multiple servers are running.

epilogue

After this split, each is actually very simple. In the specific development, each project only needs to deal with its own business code, without considering more, so that each project can be completed better, without affecting the functions of other modules, so that development and deployment maintenance can be more convenient.

Tags: PHP Dubbo Maven Redis Spring

Posted on Tue, 30 Jul 2019 01:01:36 -0700 by Ironphp