千家信息网

如何利用Springboot+Dubbo构建分布式微服务

发表于:2024-11-26 作者:千家信息网编辑
千家信息网最后更新 2024年11月26日,本篇内容主要讲解"如何利用Springboot+Dubbo构建分布式微服务",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何利用Springboot+Du
千家信息网最后更新 2024年11月26日如何利用Springboot+Dubbo构建分布式微服务

本篇内容主要讲解"如何利用Springboot+Dubbo构建分布式微服务",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何利用Springboot+Dubbo构建分布式微服务"吧!

一、先来一张图

说起 Dubbo,相信大家都不会陌生!阿里巴巴公司开源的一个高性能优秀的服务框架,可以使得应用可通过高性能的 RPC 实现服务的输出和输入功能,同时可以和 Spring 框架无缝集成。

Dubbo 架构图

节点角色说明:

  • Provider:暴露服务的服务提供方

  • Consumer:调用远程服务的服务消费方

  • Registry:服务注册与发现的注册中心

  • Monitor:统计服务的调用次数和调用时间的监控中心

  • Container:服务运行容器

二、实现思路

今天,我们以一个用户选择商品下订单这个流程,将其拆分成3个业务服务:用户中心、商品中心、订单中心,使用 Springboot + Dubbo 来实现一个小 Demo!

服务交互流程如下:

本文主要是介绍 Springboot 与 Dubbo 的框架整合以及开发实践,而真实的业务服务拆分是一个非常复杂的过程,比我们介绍的这个要复杂的多,上文提到的三个服务只是为了项目演示,不必过于纠结为什么要这样拆分!

好了,废话也不多说了,下面我们开撸!

  • 1.在虚拟机创建 4 台 centos7,任意选择一台安装 zookeeper

  • 2.构建微服务项目并编写代码

  • 3.在 centos7 上部署微服务

  • 4.远程服务调用测试

三、zookeeper安装

在使用 Dubbo 之前,我们需要一个注册中心,目前 Dubbo 可以选择的注册中心有 zookeeper、Nacos 等,一般建议使用 zookeeper!

首先在安装 Zookeeper 之前,需要安装并配置好 JDK,本机采用的是Oracle Java8 SE。

  • 安装JDK(已经安装可以忽略)

yum -y install java-1.8.0-openjdk
  • 查看java安装情况

java -version

  • JDK安装完成之后,下载安装Zookeeper

#创建一个zookeeper文件夹 cd /usr mkdir zookeeper  #下载zookeeper-3.4.14版本 wget http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz  #解压 tar -zxvf zookeeper-3.4.14.tar.gz
  • 创建数据、日志目录

#创建数据和日志存放目录 cd /usr/zookeeper/ mkdir data mkdir log  #把conf下的zoo_sample.cfg备份一份,然后重命名为zoo.cfg cd conf/ cp zoo_sample.cfg zoo.cfg
  • 配置zookeeper

#编辑zoo.cfg文件 vim zoo.cfg

  • 启动Zookeeper

#进入Zookeeper的bin目录 cd zookeeper/zookeeper-3.4.14/bin  #启动Zookeeper ./zkServer.sh start  #查询Zookeeper状态 ./zkServer.sh status  #关闭Zookeeper状态 ./zkServer.sh stop

出现如下信息,表示启动成功!

四、项目介绍

  • springboot版本:2.1.1.RELEASE

  • zookeeper版本:3.4.14

  • dubbo版本:2.7.3

  • mybtais-plus版本:3.0.6

  • 数据库:mysql-8

  • 构建工具:maven

  • 服务模块:用户中心、商品中心、订单中心

五、代码实践

5.1、初始化数据库

首先在 mysql 客户端,创建3个数据库,分别是:dianshang-user、dianshang-platform、dianshang-business。

  • 在 dianshang-user 数据库中,创建用户表 tb_user,并初始化数据

  • 在 dianshang-platform 数据库中,创建商品表 tb_product,并初始化数据

  • 在 dianshang-platform 数据库中,创建订单表 tb_order、订单详情表 tb_order_detail

5.2、创建工程

数据库表设计完成之后,在 IDEA 下创建一个名称为dianshang的Springboot工程。

最终的目录如下图:

目录结构说明:

  • dianshang-common:主要存放一些公共工具库,所有的服务都可以依赖使用

  • dianshang-business:订单中心,其中api模块主要是提供dubbo服务暴露接口,provider模块是一个springboot项目,提供服务处理操作

  • dianshang-user:用户中心,其中api模块和provider模块,设计与之类似

  • dianshang-platform:商品中心,其中api模块和provider模块,设计与之类似

在父类pom文件中加入dubbo和zookeeper客户端,所有依赖的项目都可以使用。

      org.projectlombok     lombok     1.18.4     provided         org.apache.dubbo     dubbo-spring-boot-starter     2.7.3        org.apache.zookeeper     zookeeper     3.4.13                           org.slf4j             slf4j-api                               org.slf4j             slf4j-log4j12                               log4j             log4j                      org.apache.curator     curator-framework     4.2.0       org.apache.curator     curator-recipes     4.2.0 

温馨提示:小编在搭建环境的时候,发现一个坑,工程中依赖的zookeeper版本与服务器的版本,需要尽量一致,例如,本例中zookeeper服务器的版本是3.4.14,那么在依赖zookeeper文件库的时候,也尽量保持一致,如果依赖3.5.x版本的zookeeper,项目在启动的时候会各种妖魔鬼怪的报错!

5.3、创建用户中心项目

在 IDEA 中,创建dianshang-user子模块,并依赖dianshang-common模块

              org.project.demo         dianshang-common         1.0.0      

同时,创建dianshang-user-provider和dianshang-user-api模块。

  • dianshang-user-api:主要对其他服务提供接口暴露

  • dianshang-user-provider:类似一个web工程,主要负责基础业务的crud,同时依赖dianshang-user-api模块

5.3.1、配置dubbo服务

在dianshang-user-provider的application.yml文件中配置dubbo服务,如下:

#用户中心服务端口 server:   port: 8080 #数据源配置 spring:   datasource:     druid:       driver-class-name: com.mysql.cj.jdbc.Driver       url: "jdbc:mysql://localhost:3306/dianshang-user"       username: root       password: 111111 #dubbo配置 dubbo:   scan:     # 包名根据自己的实际情况写     base-packages: org.project.dianshang.user   protocol:     port: 20880     name: dubbo   registry:     #zookeeper注册中心地址     address: zookeeper://192.168.0.107:2181

5.3.2、编写服务暴露接口以及实现类

在dianshang-user-api模块中,创建一个UserApi接口,以及返回参数对象UserVo!

public interface UserApi {      /**      * 查询用户信息      * @param userId      * @return      */     UserVo findUserById(String userId); }

其中UserVo,需要实现序列化,如下:

@Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) public class UserVo implements Serializable {      private static final long serialVersionUID = 1L;      /**      * 用户ID      */     private String userId;      /**      * 用户中文名      */     private String userName; }

在dianshang-user-provider模块中,编写UserApi接口实现类,如下:

@Service(interfaceClass =UserApi.class) @Component public class UserProvider implements UserApi {      @Autowired     private UserService userService;      @Override     public UserVo findUserById(String userId) {         QueryWrapper queryWrapper = new QueryWrapper();         queryWrapper.eq("user_id",userId);         User source = userService.getOne(queryWrapper);         if(source != null){             UserVo vo = new UserVo();             BeanUtils.copyProperties(source,vo);             return vo;         }         return null;     } }

其中的注解@Service指的是org.apache.dubbo.config.annotation.Service下的注解,而不是Spring下的注解哦!

接着,我们继续创建商品中心项目!

5.4、创建商品中心项目

与用户中心项目类似,在 IDEA 中,创建dianshang-platform子模块,并依赖dianshang-common模块

              org.project.demo         dianshang-common         1.0.0      

同时,创建dianshang-platform-provider和dianshang-platform-api模块。

  • dianshang-platform-api:主要对其他服务提供接口暴露

  • dianshang-platform-provider:类似一个web工程,主要负责基础业务的crud,同时依赖dianshang-platform-api模块

5.4.1、配置dubbo服务

在dianshang-platform-provider的application.yml文件中配置dubbo服务,如下:

#用户中心服务端口 server:   port: 8081 #数据源配置 spring:   datasource:     druid:       driver-class-name: com.mysql.cj.jdbc.Driver       url: "jdbc:mysql://localhost:3306/dianshang-platform"       username: root       password: 111111 #dubbo配置 dubbo:   scan:     # 包名根据自己的实际情况写     base-packages: org.project.dianshang.platform   protocol:     port: 20881     name: dubbo   registry:     #zookeeper注册中心地址     address: zookeeper://192.168.0.107:2181

5.4.2、编写服务暴露接口以及实现类

在dianshang-platform-api模块中,创建一个ProductApi接口,以及返回参数对象ProductVo!

public interface ProductApi {      /**      * 通过商品ID,查询商品信息      * @param productId      * @return      */     ProductVo queryProductInfoById(String productId); }

其中ProductVo,需要实现序列化,如下:

@Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) public class ProductVo implements Serializable {      private static final long serialVersionUID = 1L;      /**商品ID*/     private String productId;      /**商品名称*/     private String productName;      /**商品价格*/     private BigDecimal productPrice; }

在dianshang-platform-provider模块中,编写ProductApi接口实现类,如下:

@Service(interfaceClass = ProductApi.class) @Component public class ProductProvider implements ProductApi {      @Autowired     private ProductService productService;      @Override     public ProductVo queryProductInfoById(String productId) {         //通过商品ID查询信息         Product source = productService.getById(productId);         if(source != null){             ProductVo vo = new ProductVo();             BeanUtils.copyProperties(source,vo);             return vo;         }         return null;     } }

接着,我们继续创建订单中心项目!

5.5、创建订单中心项目

与商品中心项目类似,在 IDEA 中,创建dianshang-business子模块,并依赖dianshang-common模块

              org.project.demo         dianshang-common         1.0.0      

同时,创建dianshang-business-provider和dianshang-business-api模块。

  • dianshang-business-api:主要对其他服务提供接口暴露

  • dianshang-business-provider:类似一个web工程,主要负责基础业务的crud,同时依赖dianshang-business-api模块

5.5.1、配置dubbo服务

在dianshang-business-provider的application.yml文件中配置dubbo服务,如下:

#用户中心服务端口 server:   port: 8082 #数据源配置 spring:   datasource:     druid:       driver-class-name: com.mysql.cj.jdbc.Driver       url: "jdbc:mysql://localhost:3306/dianshang-business"       username: root       password: 111111 #dubbo配置 dubbo:   scan:     # 包名根据自己的实际情况写     base-packages: org.project.dianshang.business   protocol:     port: 20882     name: dubbo   registry:     #zookeeper注册中心地址     address: zookeeper://192.168.0.107:2181

5.5.2、编写服务暴露接口以及实现类

在dianshang-business-api模块中,创建一个OrderApi接口,以及返回参数对象OrderVo!

public interface OrderApi {      /**      * 通过用户ID,查询用户订单信息      * @param userId      * @return      */     List queryOrderByUserId(String userId); }

其中OrderVo,需要实现序列化,如下:

@Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) public class OrderVo implements Serializable {      private static final long serialVersionUID = 1L;      /**订单ID*/     private String orderId;      /**订单编号*/     private String orderNo;      /**订单金额*/     private BigDecimal orderPrice;      /**下单时间*/     private Date orderTime; }

在dianshang-business-provider模块中,编写OrderApi接口实现类,如下:

@Service(interfaceClass = OrderApi.class) @Component public class OrderProvider implements OrderApi {      @Autowired     private OrderService orderService;      @Override     public List queryOrderByUserId(String userId) {         QueryWrapper queryWrapper = new QueryWrapper();         queryWrapper.eq("user_id",userId);         List sourceList = orderService.list(queryWrapper);         if(!CollectionUtils.isEmpty(sourceList)){             List voList = new ArrayList<>();             for (Order order : sourceList) {                 OrderVo vo = new OrderVo();                 BeanUtils.copyProperties(order, vo);                 voList.add(vo);             }             return voList;         }         return null;     } }

至此,3个项目的服务暴露接口已经开发完成!接下来我们来编写怎么进行远程调用!

5.6、远程调用

5.6.1、编写创建订单服务

在dianshang-business-provider模块中,编写创建订单接口之前,先依赖dianshang-business-api和dianshang-user-api,如下:

      org.project.demo     dianshang-platform-api     1.0.0        org.project.demo     dianshang-user-api     1.0.0 

在dianshang-business-provider模块中,编写创建订单服务,如下:

@RestController @RequestMapping("/order") public class OrderController {      @Autowired     private OrderService orderService;      @Autowired     private OrderDetailService orderDetailService;      @Reference(check =false)     private ProductApi productApi;      @Reference(check =false)     private UserApi userApi;      /**      * 新增      */     @JwtIgnore     @RequestMapping(value = "/add")     public boolean add(String productId,String userId){         LocalAssert.isStringEmpty(productId,"产品Id不能为空");         LocalAssert.isStringEmpty(userId,"用户Id不能为空");         ProductVo productVo = productApi.queryProductInfoById(productId);         LocalAssert.isObjectEmpty(productVo,"未查询到产品信息");         UserVo userVo = userApi.findUserById(userId);         LocalAssert.isObjectEmpty(userVo,"未查询到用户信息");         Order order = new Order();         order.setOrderId(IdGenerator.uuid());         order.setOrderNo(System.currentTimeMillis() + "");         order.setOrderPrice(productVo.getProductPrice());         order.setUserId(userId);         order.setOrderTime(new Date());         orderService.save(order);          OrderDetail orderDetail = new OrderDetail();         orderDetail.setOrderDetailId(IdGenerator.uuid());         orderDetail.setOrderId(order.getOrderId());         orderDetail.setProductId(productId);         orderDetail.setSort(1);         orderDetailService.save(orderDetail);         return true;     } }

其中的@Reference注解,是属于org.apache.dubbo.config.annotation.Reference下的注解,表示远程依赖服务。

参数check =false表示启动服务时,不做远程服务状态检查,这样设置的目的就是为了防止当前服务启动不了,例如用户中心项目没有启动成功,但是订单中心又依赖了用户中心,如果check=true,此时订单中心启动会报错!

5.6.2、编写用户查询自己的订单信息

同样的,在dianshang-user-provider模块中,编写用户查询自己的订单信息接口之前,先依赖dianshang-business-api和dianshang-user-api,如下:

     org.project.demo     dianshang-business-api     1.0.0       org.project.demo     dianshang-user-api     1.0.0 

在dianshang-user-provider模块中,编写用户查询自己的订单信息接口,如下:

@RestController @RequestMapping("/user") public class UserController {      @Reference(check =false)     private OrderApi orderApi;       /**      * 通过用户ID,查询订单信息      * @param userId      * @return      */     @RequestMapping("/list")     public List queryOrderByUserId(String userId){         return orderApi.queryOrderByUserId(userId);     } }

至此,远程服务调用,编写完成!

六、服务测试

在将项目部署在服务器之前,咱们先本地测试一下,看服务是否都可以跑通?

  • 启动用户中心dianshang-user-provider

  • 继续启动商品中心dianshang-platform-provider

接着启动订单中心dianshang-business-provider

最后,我们来测试一下服务接口是否为我们预期的结果?

打开浏览器,输入http://127.0.0.1:8082/order/add?productId=1&userId=1测试创建订单接口,页面运行结果显示正常!

我们再来看看数据库,订单是否生成?

ok!很清晰的看到,数据已经进去了,没啥问题!

我们再来测试一下在用户中心订单查询接口,输入http://127.0.0.1:8080/user/list?userId=1,页面运行结果如下!

到此,本地服务测试基本通过!

七、服务器部署

在上文中,我们介绍了服务的构建、开发和测试,那如何在服务器端部署呢?

首先,修改各个项目的application.yml文件,将其中的数据源地址、dubbo注册中心地址修改为线上能联通的地址,然后在dianshang目录下使用maven工具对整个工程执行如下命令进行打包!

mvn clean install

也可以在 IDEA 环境下,通过maven配置clean install命令执行打包。

将各个项目target目录下的dianshang-user-provider.jar、dianshang-platform-provider.jar、dianshang-business-provider.jar拷贝出来。

分别上传到对应的服务器目录,本服务器采用的是 CentOS7,总共4台服务器,其中一台部署zookeeper,另外三台部署三个微服务项目。

登录服务器,输入如下命令,确保JDK已经安装完成!

java -version

关闭所有服务器的防火墙,放行端口访问!

#关闭防火墙 systemctl stop firewalld.service  #禁止开机启动 systemctl disable firewalld.service
  • 启动用户中心服务,日志信息输出到service.log(虚拟机ip:192.168.0.108)

nohup java -jar  dianshang-user-provider.jar > service.log 2>&1 &
  • 启动商品中心服务,日志信息输出到service.log(虚拟机ip:192.168.0.107)

nohup java -jar  dianshang-platform-provider.jar > service.log 2>&1 &
  • 启动订单中心服务,日志信息输出到service.log(虚拟机ip:192.168.0.109)

nohup java -jar  dianshang-business-provider.jar > service.log 2>&1 &

打开浏览器,输入http://192.168.0.109:8082/order/add?productId=1&userId=1测试创建订单接口,页面运行结果显示正常!

我们再来测试一下在用户中心订单查询接口,输入输入http://192.168.0.108:8080/user/list?userId=1,页面运行结果如下!

很清晰的看到,输出了2条信息,第二条订单是在测试环境服务器生成的,第一条是本地开发环境生成的。

到此,服务器部署基本已经完成!

如果是生产环境,可能就需要多台zookeeper来保证高可用,至少2台服务器来部署业务服务,通过负载均衡来路由!

到此,相信大家对"如何利用Springboot+Dubbo构建分布式微服务"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

服务 模块 订单 用户 接口 项目 数据 商品 信息 配置 用户中心 查询 服务器 测试 版本 数据库 文件 目录 同时 工程 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 呼吸系统数据库有哪些 软件开发项目投标报名 郸城第二人民医院网络安全 上海智能套料软件开发商 火绒安全软件网络安全技术 vb代码 新浪股票数据库 高防海外服务器 实时数据库和 专业技术人员网络安全豆丁网 放心的微信软件开发项目 福州六叶网络技术 北京深度网络技术公司 海报网络安全人人有责 双管理节点数据库不同步怎么回事 网络安全口令解说 对数据库有什么深刻的印象 张家港营销网络技术服务费 临沂启辰网络技术有限公司 天津 二级数据库 考点 崇明区机械软件开发服务生产厂家 数据库小型应用系统开发 河北网络技术开发目的 access数据库设备管理系统下载 死亡循环 登陆服务器 未来之役为啥连接不到服务器 超市进销存管理系统数据库 研究生考专业课数据库技术 达芬奇怎么设置数据库保存位置 服务器在上海延迟高吗 2005 数据库可疑
0