一、为什么使用
随着互联网场景中所要面对的用户规模和体量的增加,系统的也需要做相应的拆分设计和实现。随之而来的,以前的一套系统,现在成了多个微服务。如;电商系统,以前就在一个工程中写就可以了,现在需要拆分出,用户、支付、商品、配送、活动、风控等各个模块。那么这些模块拆分后,如何高效的通信呢?
- 关于通信,就引入了 RPC 框架,而 Dubbo 就是其中的一个实现方式。
- 那为啥用 Dubbo 呢?其实核心问题就一个,为了提高通信效率。因为 Dubbo 的底层通信是 Socket 而不是 HTTP 所以通信的性能会更好。同时 Dubbo 又有分布式的高可用设计,在一组部署了交易服务的实例宕机后,会被从注册中心摘除,之后流量会打到其他服务上。
二、要怎么使用
Dubbo 的使用分为2方,一个是接口的提供方,另外一个是接口的调用方。接口的提供方需要提供出被调用方使用接口的描述性信息。这个信息包括;接口名称、接口入参、接口出参,只有让调用方拿到这些信息以后,它才能依托于这样的接口信息做一个代理操作,并在代理类中使用 Socket 完成双方的信息交互。
所以你看上去调用 RPC 接口好像和使用 HTTP 也没啥区别,无非就是引入了 POM 配置,之后再配置了注解就可以使用了。但其实,它是把你的 Jar 当做代理的必要参数使用了。本文也会介绍,具体是怎么代理的
三、使用的案例
对于编程的学习来说,其实最开始的那一下,不是搞明白所有原理,而是先让自己可以看到运行出来的效果。哎,之后就去分析原理,这样会舒服的多。
所以小傅哥这里提供了一套简单的 Dubbo 使用案例,只要你满足最基本的配置条件,就可以运行出效果;
- JDK 1.8
- Maven 3.x - jdk1.8支持的就可以
- Dubbo 3.1.4 - POM 中已经配置,与2.x最大的使用上的区别就是一些注解的使用
- Zookeeper 3.4.x - 如果你只是按照本文中的直连模式测试,那么不安装 Zookeeper 也可以
1. 接口提供方
工程案例创建结构,采用的是 DDD 结构。但和 DDD 一点关系没有。如果你对工程创建有疑惑,可以参考 《Java 简明教程》之 DDD 架构
1.1 接口定义
源码:cn.bugstack.dev.tech.dubbo.api.IUserService
public interface IUserService {
Response<UserResDTO> queryUserInfo(UserReqDTO reqDTO);
}
- 接口定义平平无奇,但第1个坑暗藏玄机!
- 也就是,所有的 Dubbo 接口,出入参,默认都需要继承 Serializable 接口。也就是 UserReqDTO、UserResDTO、Response 这3个类,都得继承 Serializable 序列化接口。
1.2 接口实现
源码:cn.bugstack.dev.tech.dubbo.trigger.rpc.UserService
@Slf4j
@DubboService(version = "1.0.0")
public class UserService implements IUserService {
@Override
public Response<UserResDTO> queryUserInfo(UserReqDTO reqDTO) {
log.info("查询用户信息 userId: {} reqStr: {}", reqDTO.getUserId(), JSON.toJSONString(reqDTO));
try {
// 1. 模拟查询【你可以从数据库或者Redis缓存获取数据】
UserResDTO resDTO = UserResDTO.builder()
.userId(reqDTO.getUserId())
.userName("小傅哥")
.userAge(20)
.build();
// 2. 返回结果
return Response.<UserResDTO>builder()
.code(Constants.ResponseCode.SUCCESS.getCode())
.info(Constants.ResponseCode.SUCCESS.getInfo())
.data(resDTO).build();
} catch (Exception e) {
log.error("查询用户信息失败 userId: {} reqStr: {}", reqDTO.getUserId(), JSON.toJSONString(reqDTO), e);
return Response.<UserResDTO>builder()
.code(Constants.ResponseCode.UN_ERROR.getCode())
.info(Constants.ResponseCode.UN_ERROR.getInfo())
.b