Article 20201013 | | ping elder brother date

See GitHub repository for specific code: click me jump

Project introduction

This project is the first project built by learning Dubbo+Zookeeper. The main architecture is a parent project and three child modules: Dubbo_provider, dubbo_consumer and dubbo_API. The three child modules inherit the parent project respectively.

Remote access to Dubbo is interface-based. The Consumer and Provider use the same interface to enable remote access.

  • Provider writes and implements interfaces and provides services.
  • The Consumer uses the interface and remotely accesses the Provider through a dynamic proxy object created by Dubbo.
  • Define the interface independently in a project (dubBO_API), do dependency management.

P.S. This project focuses on practicing Dubbo+Zookeeper, so it does not write the content of connecting to the database, but only simulates accessing the database.

Step 1 Create the project and write the parent project Maven dependencies

1.1 Creating a Project

Create project with IDEA, create project directory as follows:

1.2 Writing parent project Maven dependencies

Directly on the code:


      
<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>com.gcp</groupId>
    <artifactId>dubbo_pro01</artifactId>
    <packaging>pom</packaging>
    <version>1.0 the SNAPSHOT</version>
    <modules>
        <module>dubbo_provider</module>
        <module>dubbo_consumer</module>
        <module>dubbo_api</module>
    </modules>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4. RELEASE</version>
    </parent>
    <dependencies>
        <! -- Springboot launcher -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <! - lombok dependence - >
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <! -- Dubbo Springboot boot -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.8</version>
        </dependency>
        <! - curator dependence - >
        <! Curator provides a set of Java class libraries that make ZooKeeper easier to use. -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>5.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>5.1.0</version>
        </dependency>
    </dependencies>
</project>
Copy the code

Step 2 write dubbo_API

2.1 Define POJO classes

package com.gcp.pojo;
import lombok.Data;
@Data
public class User {
    private Long id;
    private String name;
    private String password;
}
Copy the code

2.2 Defining a Service Interface

package com.gcp.service;
import com.gcp.pojo.User;
/** * User service interface */
public interface UserService {
    void register(User user);
    User getUserById(Long id);
}
Copy the code

Step 3 Write dubbo_provider

instructions

  • The Dubbo Service Provider does not need to define a Controller and provides services directly through a Service.
  • Using the @dubboService annotation provided by the Dubbo framework, declare that the object of the current type is a Dubbo service provider.
  • Let the Spring container initialize, manage, and register service information with Zookeeper through the Curator framework.
  • In older versions of Dubbo (prior to 2.6 inclusive), the annotation name was @service. So when using older versions of development, pay attention to the package of imported annotations.
  • You need to provide an application.yml configuration file that says what registry Dubbo uses and what address.

3.1 configuration pom. XML

Add dependencies to the pom.xml file:

<dependencies>
    <dependency>
        <groupId>com.gcp</groupId>
        <artifactId>dubbo_api</artifactId>
        <version>1.0 the SNAPSHOT</version>
    </dependency>
</dependencies>
Copy the code

3.2 Defining Mapper interfaces and classes

UserMapper interface:

import com.gcp.pojo.User;

/** * simulate database access */
public interface UserMapper {
    void insert(User user);
    User selectById(Long id);
}
Copy the code

UserMapperImpl implementation class:

@Repository
public class UserMapperImpl implements UserMapper {
    @Override
    public void insert(User user) {
        System.out.println("Database Access: New user -" + user);
    }

    @Override
    public User selectById(Long id) {
        User user = new User();
        user.setId(id);
        user.setName("name" + id);
        user.setPassword("password" + id);
        System.out.println("Database access: Primary key query user -" + user);
        returnuser; }}Copy the code

3.3 Defining the Service Implementation class

@dubboService (loadBalance = “roundrobin”), loadBalance = “roundrobin” means that the service implements load balancing access in polling mode if the service has clusters. The default value is random


@DubboService(loadbalance = "roundrobin")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public void register(User user) {
        System.out.println("UserService implementation class: Registered user");
        userMapper.insert(user);
    }

    @Override
    public User getUserById(Long id) {
        System.out.println("UserService implementation class: Query user by ID");
        returnuserMapper.selectById(id); }}Copy the code

3.4 configuration application. Yml

Description:

  • In Dubbo, each service provider and consumer is managed on an application level.
  • All use names as unique tags.
  • Service providers or consumers with the same name automatically form clusters.
  • By default, the dubbo application uses the Dubbo protocol and port 20880. Protocols can be configured.

Create application.yml in the Resources folder:

dubbo: # dubbo configure the root node
  registry: Configure the dubbo registry
    address: Zookeeper: / / 192.168.40.170:2181  Provide an access address for the registry.
  application: Configure the dubbo application information
    name: gcp-dubbo-first-provider  # configure the application name of this dubbo. The name consists of: letters, digits, '-', and the beginning of a letter
  protocol: All default values are invalid when the protocol is configured.
    name: dubbo # protocol name
    port: 20880 The default port is 20880
Copy the code

How to install Zookeeper can be seen in my other article

3.5 Creating a SpringBoot Initiator

  • Every Dubbo application that is launched must register information in the registry.
  • The service provider registers /dubbo/ XXX /providers
  • Service consumers register with /dubbo/ XXX /consumers
  • Dubbo initiator (dubo-spring-boot-starter) does not take effect by default.
  • You must use @enabledubbo for the initiator to take effect.
  • In versions 2.7.2 to earlier, some configurations are not loaded by default. You need to use @enableDubboconfig for all configurations to take effect.
  • Load balancing policy:
  • The load balancing policy can be set in the @dubboService or @dubboReference annotation
  • Add the loadBalance attribute to the configuration.
  • By default, consumers do not consider the load balancing policy and use the load balancing policy defined by the provider.
  • If the consumer has configured a load balancing policy, the provider’s configured load balancing policy is ignored.

Create SpringBoot boot class in com. GCP package:

@SpringBootApplication
@EnableDubbo
// @EnableDubboConfig
public class DbProviderApplication {
    public static void main(String[] args) { SpringApplication.run(DbProviderApplication.class,args); }}Copy the code

At this point, you can start the service and check whether the service is successfully registered in Zookeeper. Access the Linux server and use the Zookeeper client tool to check:

Step 4 write dubbo_consumer

4.1 configuration pom. XML

Add dependencies to the pom.xml file:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.gcp</groupId>
        <artifactId>dubbo_api</artifactId>
        <version>1.0 the SNAPSHOT</version>
    </dependency>
</dependencies>
Copy the code

4.2 Creating the Consumer local Service interface and implementation class

The Zookeeper registry already provides a Service. Note: In fact, dubbo remote service invocation, is to encapsulate the general rules, but each sub-project has its own individual logic, such as: user registration logic, is unified in an enterprise. Provide a Provider to implement the registration logic; For consumers, this is different and can provide several entrances. For example, Tencent users can register or log in through QQ, QQ music, QQ space and so on. The underlying users are the same.

LocalUserService interface:

package com.gcp.service;
import com.gcp.pojo.User;
/** * Local Service */ for the consumer submodule
public interface LocalUserService {
    void register(User user);
    User getById(Long id);
}
Copy the code

LocalUserServiceImpl Implementation class:

@Service
public class LocalUserServiceImpl implements LocalUserService {

    /** * The interface of the remote service. Through annotation@DubboReference1, notify Dubbo framework, according to the configuration to find the registry, discover the address of the service. * Use the interface name as the naming rule of the zooKeeper node to obtain the IP address. * 2, tell Spring to create a dynamic proxy object for the interface according to the features of the Dubbo framework and maintain * in the Spring container. * 3@AutowiredTo inject the proxy object into the current variable. * /
    @DubboReference
    private UserService userService;
    @Override
    public void register(User user) {
        System.out.println("Ready to invoke remote service, service object type:" + userService.getClass().getName());
        System.out.println("Registered users are:" + user);
        userService.register(user);
    }
    @Override
    public User getById(Long id) {
        System.out.println("Query user by primary key, primary key is:" + id);
        returnuserService.getUserById(id); }}Copy the code

4.3 Creating the Controller Class

UserController class:

@RestController
public class UserController {

    @Autowired
    private LocalUserService localUserService;
    @RequestMapping("findUser")
    public User findUser(Long id){
        return localUserService.getById(id);
    }
    @RequestMapping("registerUser")
    public String register(User user){
        localUserService.register(user);
        return "User registered successfully"; }}Copy the code

4.4 Configuring the Registry Address

Create application.yml in the Resources folder:

dubbo:
  registry:
    address: Zookeeper: / / 192.168.40.170:2181
Copy the code

4.5 Creating a Springboot Boot Class

Create DbConsumerApplication under com.gcp:

@SpringBootApplication
@EnableDubbo
public class DbConsumerApplication {
    public static void main(String[] args) { SpringApplication.run(DbConsumerApplication.class,args); }}Copy the code

4.6 Starting a Test

Start the consumer startup class and check whether the Zookeeper registry is successfully registered:

Step 5 Test the whole project

Open a browser and enter the consumer access address to test whether it can be accessed normally:

Background output: Consumer submodule:

The provider a Module:

Now that the project has been created successfully, you can copy the startup classes of the Provider and Consumer submodules and change the ports to different ones to see how cluster polling and random access work.

See GitHub repository for specific code: click me jump