SpringBoot2.x Dubbo 整合实例

avatar 2020年02月01日14:30:03 6 2606 views
博主分享免费Java教学视频,B站账号:Java刘哥
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


这里才开始设计到 SpringBoot 和 Dubbo 的整合

主要包括三部分:

① 给启动类添加开启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

发表评论

avatar 登录者:匿名
匿名评论,评论回复后会有邮件通知

  

已通过评论:0   待审核评论数:0