SpringBoot2.x Dubbo 整合实例

avatar 2020年02月01日14:30:03 6 2909 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
  • 个人淘宝
  • 店铺名:言曌博客咨询部

  • (部分商品未及时上架淘宝)
avatar

发表评论

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

  

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