SpringBoot2.x Dubbo 整合实例

avatar 2020年2月1日14:30:03 评论 80 views

Dubbo 是阿里开源的一个 RPC 框架,2011年开源,然后2014年就不更新了,2017年又重新更新。随着不断更新和SpringBoot整合,入门门槛越来越低,配置也越来越少。

本文介绍 SpringBoot 2.x 和 Dubbo 整合。

代码地址:https://github.com/saysky/springboot-dubbo-demo

一、项目结构

主要分为三部分,服务提供者(provider),服务消费者(consumer),api包(一般由服务提供者封装)

其中 dubbo-provider 指的是服务提供者。dubbo-consumer 指的是服务消费者,需要调用服务提供者

通常 dubbo-provider 和 dubbo-consumer 不同的项目,很可能由不同的团队开发,这里为了大家学习方便放到一个项目里,以不同的模块来区分。

dubbo-api 是同 dubbo-provider 的团队提供,里面主要是如实体类型,service 接口之类的,会把这个依赖的提供给 dubbo-consumer。

完整的结构如下

 

下面将详细介绍整合过程,本文以对用户的添加和查询为例介绍,其他的没什么区别

二、API 层:dubbo-api

该层主要是对外暴露的,任何人都可以获取。

该层只是一个普通的模块,不需要添加 SpringBoot 或者其他依赖,因为用到了 @Data 注解添加 lombok 依赖,lombok 是帮助自动创建 getter/setter、构造器、toString 等的工具。

1、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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <artifactId>springboot-dubbo-demo</artifactId>
        <groupId>com.liuyanzhao</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <groupId>com.liuyanzhao</groupId>
    <artifactId>dubbo-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>dubbo-api</name>

    <description>Demo project for Spring Boot</description>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>

    </dependencies>

</project>

 

2、User.java

package com.liuyanzhao.dubbo.api.entity;

import lombok.Data;

import java.io.Serializable;

/**
 * @author 言曌
 * @date 2020-01-31 16:32
 */
@Data
public class User implements Serializable {

    private static final long serialVersionUID = 6147345506206285446L;

    private Long id;

    private String username;

    private String nickname;

    private String email;

    private String password;
}

 

3、UserService.java

package com.liuyanzhao.dubbo.api.service;

import com.liuyanzhao.dubbo.api.entity.User;

import java.util.List;

/**
 * @author 言曌
 * @date 2020-01-31 16:32
 */

public interface UserService {

    /**
     * 根据ID获得用户信息
     * @param id
     * @return
     */
    User findById(Long id);

    /**
     * 添加用户
     * @@param user
     */
    void insert(User user);

    /**
     * 获得所有用户
     * @return
     */
    List<User> findAll();

}

 

三、服务提供者:dubbo-provider

这里才开始设计到 SpringBootDubbo 的整合

主要包括三部分:

① 给启动类添加开启dubbo注解;

② 在 application.yml 添加 dubbo 配置;

③ 在服务提供者的 Service 实现里添加阿里巴巴的 @Service 注解(不是 Spring 的)

其他的关于数据访问层的也一并贴上代码吧,大家也可以直接在 github 上下载该项目代码

1、pom.xml

添加 dubbo 依赖,这里需要添加 api 依赖,一方面给服务消费者使用,同时自己也方便依赖

<?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 https://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.2.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.liuyanzhao</groupId>
    <artifactId>dubbo-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>dubbo-provider</name>
    <description>Demo project for Spring Boot</description>

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

    <dependencies>
        <!--   web     -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- dubbo依赖 -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>
        <!--  数据库连接池    -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.5.0</version>
        </dependency>
        <!--  h2数据库,用于测试持久化    -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--   mybatis     -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>com.liuyanzhao</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

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

</project>

主要添加 dubbo 依赖:dubbo-spring-boot-starter

其他的如 h2 是内存性数据库,方便测试,这里就不用 mysql,减少大家创建数据库和表结构的时间

ORM 框架用的是 MyBatis

 

2、application.yml

添加 dubbo 配置

# 配置端口
server:
  port: 8081

# dubbo 配置
dubbo:
  application:
    name: dubbo-provider
  registry:
    # 修改为自己的ip
    address: 192.168.43.217:2181
    protocol: zookeeper
  consumer:
    check: false
    timeout: 3000

spring:
  # 为了测试方便,这里数据库持久层采用 h2 数据库
  datasource:
    data: classpath:db/data.sql
    schema: classpath:db/schema.sql
    url: jdbc:h2:mem:dbtest
    driverClassName: org.h2.Driver
    username: sa
    password: sa
    platform: h2
    sql-script-encoding: utf-8
  h2:
    console:
      enabled: true
      path: /h2
      settings:
        web-allow-others: true

mybatis:
  mapper-locations: classpath:mapping/*Mapper.xml
  type-aliases-package: com.liuyanzhao.dubbo.api.entity

主要关注 dubbo 的配置,注意修改 IP 地址为自己的IP

windows 查看IP的方法,在 CMD 里输入 ipconfig;

mac 或 linux 是在终端输入 ifconfig。

 

3、DubboProviderApplication.java

开启 Dubbo 自动配置

package com.liuyanzhao.dubbo.provider;

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

// 开启dubbo的自动配置
@EnableDubbo
@SpringBootApplication
public class DubboProviderApplication {

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

}

主要是添加了一个注解 @EnableDubbo

 

4、UserServiceImple.java

注意

1、@Service 注解是 com.alibaba.dubbo.config.annotation.Service 的,

不是 org.springframework.stereotype.Service,如果写错了服务消费者将无法找到服务提供者

2、别忘了添加 @Component 注解,否则 Spring 不会创建 bean

package com.liuyanzhao.dubbo.provider.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.liuyanzhao.dubbo.api.entity.User;
import com.liuyanzhao.dubbo.api.service.UserService;
import com.liuyanzhao.dubbo.provider.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;


/**
 * @author 言曌
 * @date 2020-01-31 17:11
 */

// dubbo注解,暴露服务
@Service
@Component
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public User findById(Long id) {
        return userMapper.findById(id);
    }

    @Override
    public void insert(User user) {
        userMapper.insert(user);
    }

    @Override
    public List<User> findAll() {
        return userMapper.findAll();
    }
}

 

5、UserMapper.java

package com.liuyanzhao.dubbo.provider.mapper;

import com.liuyanzhao.dubbo.api.entity.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * @author 言曌
 * @date 2020-01-31 21:38
 */
@Mapper
public interface UserMapper {

    /**
     * 根据ID获得用户
     * @param id
     * @return
     */
    User findById(Long id);

    /**
     * 添加用户
     * @param user
     * @return
     */
    int insert(User user);

    /**
     * 获得所有用户
     * @return
     */
    List<User> findAll();
}

 

6、UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liuyanzhao.dubbo.provider.mapper.UserMapper">

    <resultMap id="BaseResultMap" type="com.liuyanzhao.dubbo.api.entity.User">
        <result column="id" jdbcType="INTEGER" property="id" />
        <result column="username" jdbcType="VARCHAR" property="username" />
        <result column="password" jdbcType="VARCHAR" property="password" />
        <result column="nickname" jdbcType="VARCHAR" property="nickname" />
        <result column="email" jdbcType="VARCHAR" property="email" />
    </resultMap>

    <insert id="insert">
        INSERT INTO `user` (username, password, nickname, email)
        VALUES (#{username}, #{password}, #{nickname}, #{email})
    </insert>

    <select id="findById" resultMap="BaseResultMap">
        SELECT
            id, username, password, nickname, email
        FROM
            `user`
        WHERE id = #{value}
    </select>

    <select id="findAll" resultMap="BaseResultMap">
        SELECT
            id, username, password, nickname, email
        FROM
            `user`
    </select>

</mapper>

 

7、data.sql

该文件是 h2 的数据文件,位置在 resource/db/data.sql

INSERT INTO User (id, username, nickname, password, email) VALUES(1, 'zhangsan', '张三', '123456', 'zhangsan@gmai.com');
INSERT INTO User (id, username, nickname, password, email) VALUES(2, 'lisi', '李四', '666666', 'lisi@gmai.com');
INSERT INTO User (id, username, nickname, password, email) VALUES(3, 'wangwu', '王五', '331122', 'wangwu@gmai.com');

 

8、schema.sql

该文件是 h2 的表结构文件,位置在 resource/db/schema.sql

create table if not exists user (
    id bigint not null primary key auto_increment,
    username varchar(100),
    nickname varchar(100),
    password varchar(100),
    email varchar(100)
);

 

四、服务消费者:dubbo-consumer

主要包括三部分:

① 给启动类添加开启dubbo注解;

② 在 application.yml 添加 dubbo 配置;

③ 在服务消费者中使用 @Reference 注入服务提供者的服务

 

1、pom.xml

同样是添加 dubbo 依赖,还需要添加 api 依赖

<?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 https://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.2.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.liuyanzhao</groupId>
    <artifactId>dubbo-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <name>dubbo-comsumer</name>
    <description>Demo project for Spring Boot</description>

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

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

        <!-- dubbo依赖 -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>

        <dependency>
            <groupId>com.liuyanzhao</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

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

</project>

 

2、application.yml

主要关注 dubbo 配置

# 配置端口
server:
  port: 8080

# dubbo 配置
dubbo:
  application:
    name: dubbo-consumer
  registry:
    # 修改为自己的ip
    address: 192.168.43.217:2181
    protocol: zookeeper
    check: false
  consumer:
    check:  false
    timeout: 3000

 

3、DubboComsumerApplication.java

在启动类上添加 @EnableDubbo 注解

package com.liuyanzhao.dubbo.comsumer;

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

// 开启dubbo的自动配置
@EnableDubbo
@SpringBootApplication
public class DubboComsumerApplication {

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

}

 

4、UserController.java

注意:注入服务提供者提供的依赖,是用阿里巴巴提供的 @Reference 注解,不是使用 @Autowired

package com.liuyanzhao.dubbo.comsumer.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.liuyanzhao.dubbo.api.entity.User;
import com.liuyanzhao.dubbo.api.service.UserService;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author 言曌
 * @date 2020-01-31 21:26
 */
@RestController
public class UserController {

    @Reference
    private UserService userService;

    /**
     * 获得用户列表
     * @return
     */
    @GetMapping("/user")
    public List<User> findAll() {
        return userService.findAll();
    }

    /**
     * 根据ID查询用户
     * @param id
     * @return
     */
    @GetMapping("/user/{id}")
    public User findById(@PathVariable("id") Long id) {
        return userService.findById(id);
    }

    /**
     * 添加用户
     * @param user
     */
    @PostMapping("/user")
    public void insert(@RequestBody User user) {
         userService.insert(user);
    }
}

 

五、测试

1、启动 zookeeper

可以在 zookeeper 官网下载,进入安装目录下的bin目录

windows 下是双击 zkServer.cmd 启动

mac 下是在终端执行 zkServer.sh start 启动

 

2、启动 dubbo-provider

启动成功

 

3、启动 dubbo-consumer

启动成功

如果你不能启动成功,可以检查一下 @Service 注解是否有错

检查一下配置文件里 IP 是否正确

检查一下 zookeeper 是否正常启动

检查一下启动控制台里的 IP 是不是本机IP,如果不是可能是虚拟网卡IP,禁用虚拟网卡

或者尝试更换其他网络试试,比如换个手机热点试试

我之前就遇到这种问题,详见这里

 

4、访问项目

http://localhost:8080/user/1

试了其他接口也没问题

 

5、比较 dubbo 和 springcloud 在服务调用方面的使用最大的区别

主要体现在 UserServiceImpl 这个类

如果是 SpringCloud 需要在某个方法上加 RequestMapper, 在类上加 @RestController,就是将服务提供者的所有方法通过 SpringMVC 以 http 接口暴露出去;

而 dubbo 不需要写那么多,dubbo 会根据类路径,方法名来找到服务提供者。

  • 微信
  • 交流学习,有偿服务
  • weinxin
  • 博客/Java交流群
  • 资源分享,问题解决,技术交流。群号:590480292
  • weinxin
avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: