RocketMQ 实战:模拟电商网站场景综合案例(一)
========================================================
一、内容介绍
1、案例介绍:
1.1 业务分析
1)下单业务
2)支付业务
1.2 问题分析
2、技术分析
2.1 技术选型:
1)SpringBoot
2)Dubbo
3)Zookeeper
4)RocketMQ
5)Mysql
2.2 SpringBoot 整合 RocketMQ
1)消息生产者
2)消息消费者。
2.3 SpringBoot 整合 Dubbo
1)搭建 Zookeeper 集群
2)RPC 服务接口
3)服务提供者
4)服务消费者。
3、环境搭建
3.1 数据库
1)优惠券表
2)商品表
3)订单表
4)订单商品日志表
5)用户表
6)用户余额日志表
7)订单支付表
8)MQ 消息生产表
9)MQ 消息消费表。
3.2 项目初始化
1)工程浏览
- shop-api 接口层
- shop-common 工具工程
- shop-coupon-service 优惠券服务
- shop-goods-service 商品服务
- shop-order-service 订单服务
- shop-order-web 订单系统
- shop-parent 父工程
- shop-pay-service 支付服务
- shop-pay-web 支付系统
- shop-pojo 实体类
- shop-user-service 用户服务。
- shop-dao 持久层 。
2)工程关系:12个系统
-
shop-common 工具工程
-
shop-parent 父工程
-
shop-pojo 实体类
-
shop-dao 持久层。
-
1)web 层 :
-
shop-order-web 订单系统
-
shop-pay-web 支付系统
-
接口层:shop-api 接口层
-
2)服务层:
-
shop-coupon-service 优惠券服务
-
shop-goods- 商品服务
-
shop-order-service 订单服务
-
shop-pay-service 支付服务
-
shop-user-service 用户服务。
-
3)储存层:数据库 Mysql
3.3 MyBatis 逆向工程使用
1)代码生成
2)代码导入。
3.4 公共类介绍
1)ID 生成器
2)异常处理类
3)常量类
4)响应实体类。
4、下单业务
4.1 下单基本流程
- 1)接口定义
- 2)业务类实现
- 3)校验订单
- 4)生成预订单
- 5)扣减库存
- 6)扣减优惠券
- 7)扣减用户余额
- 8)确认订单
- 9)小结
4.2 失败补偿机制
- 1)消息发送方
- 2)消费接收方
4.3 测试
5、支付业务
5.1 创建支付订单
5.2 支付回调
6、整体联调
6.1 准备工作
1)配置 RestTemplate 类。
2)配置请示地址。
6.2 下单测试
6.3 支付测试。
二、综合案例功能介绍
1、业务分析
模拟电商网站场景主要业务分为:订单业务 和 支付业务。
1.1、订单业务流程:
- 1)用户请求订单系统下单
- 2)订单系统通过RPC调用订单服务下单
- 3)订单服务调用优惠券服务,扣减优惠券
- 4)订单服务调用调用库存服务,校验并扣减库存
- 5)订单服务调用用户服务,扣减用户余额
- 6)订单服务完成确认订单
1.2、支付业务流程:
- 1)用户请求支付系统
- 2)支付系统调用第三方支付平台API进行发起支付流程
- 3)用户通过第三方支付平台支付成功后,第三方支付平台回调通知支付系统
- 4)支付系统调用订单服务修改订单状态
- 5)支付系统调用积分服务添加积分
- 6)支付系统调用日志服务记录日志。
2、问题分析
2.1、问题1
用户提交订单后,扣减库存成功、扣减优惠券成功、使用余额成功,但是在确认订单操作失败,需要对库存、库存、余额进行回退。如何保证数据的完整性?
解决方案:
使用 RocketMQ 保证在下单失败后系统数据的完整性。
2.2、问题2
用户通过第三方支付平台(支付宝、微信)支付成功后,第三方支付平台要通过回调 API 异步通知商家支付系统用户支付结果,支付系统根据支付结果修改订单状态、记录支付日志和给用户增加积分。
商家支付系统如何保证在收到第三方支付平台的异步通知时,如何快速给第三方支付凭条做出回应?
解决方案:
通过 RocketMQ 进行数据分发,提高系统处理性能。
三、项目技术介绍
1、技术分析:技术选型:
1)SpringBoot :使用框架,快速开发。
2)Dubbo :实现 微服务分布式系统的 RPC 远程调用。
3)Zookeeper :服务注册中心,搭建高可用集群系统
4)RocketMQ :消息中间件实现系统解藕。
5)Mysql :存储基础数据。
2、技术分析:SpringBoot 整合 RocketMQ
1)消息生产者
2)消息消费者。
3、技术分析:SpringBoot 整合 Dubbo
1)搭建 Zookeeper 集群
2)RPC 服务接口
3)服务提供者
4)服务消费者。
四、SpringBoot 整合 RocketMQ :springboot 集成 rocketmq 生产者
1、下载 rocketmq-spring 项目,
https://github.com/apache/rocketmq-spring.git
rocketmq-spring-rocketmq-spring-all-2.0.3.zip
2、将 rocketmq-spring 安装到本地仓库。
mvn install -Dmaven.skip.test=true
3、打开 idea 创建 springboot-rocketmq-producer 项目,并在项目 pom.xml 中添加 依赖。
--> idea --> File
--> New --> Project
--> Maven
Project SDK: ( 1.8(java version "1.8.0_131" )
--> Next
--> Groupld : ( djh.it )
Artifactld : ( springboot-rocketmq-producer )
Version : 1.0-SNAPSHOT
--> Name: ( springboot-rocketmq-producer )
Location: ( ...\springboot-rocketmq-producer\ )
--> Finish
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>djh.it</groupId>
<artifactId>springboot-rocketmq-producer</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<properties>
<rocketmq-spring-boot-starter-version>2.0.3</rocketmq-spring-boot-starter-version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>${rocketmq-spring-boot-starter-version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
<!-- Dspringboot-rocketmq-producer\pom.xml -->
4、在项目 springboot-rocketmq-producer 中,添加 application.properties 配置文件
## springboot-rocketmq-producer\src\main\resources\application.properties
rocketmq.name-server=192.168.25.135:9876;192.168.25.138:9876 # nameserver
rocketmq.producer.group=my-group # 发送者组名
5、在项目 springboot-rocketmq-producer 中,创建启动类 ProducerApplication.java
/**
* springboot-rocketmq-producer\src\main\java\djh\it\shop\springboot\rocketmq\ProducerApplication.java
*
* 2024-6-3 创建启动类 ProducerApplication.java
*/
package djh.it.shop.springboot.rocketmq;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProducerApplication {
public static void main(String[] args) {
SpringApplication.run(ProducerApplication.class, args);
}
}
6、在项目 springboot-rocketmq-producer 中,创建 测试 类 ProducerTest。java 进行测试。
/**
* idea\springboot-rocketmq-producer\src\test\java\djh\it\shop\test\ProducerTest.java
*
* 2024-6-3 创建 测试 类 ProducerTest。java
*/
package djh.it.shop.test;
import djh.it.shop.springboot.rocketmq.ProducerApplication;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ProducerApplication.class})
@Slf4j
public class ProducerTest {
@Autowired
private RocketMQTemplate rocketMQTemplate;
@Test
public void testSendMessage(){
rocketMQTemplate.convertAndSend("springboot-rocketmq", "Hello Springboot Rocketmq");
log.info("消息发送成功");
}
}
7、如果安装了RocketMQ 控制台,可以进行后台查看。
浏览器地址栏输入:虚拟机 IP :8080 登录到 RocketMQ 控制台,进行测试
如:http://192.168.25.135:8080/
http://172.18.30.110:8080/
点击【主题】,查看到 【springboot-rocketmq】。
五、SpringBoot 整合 RocketMQ :springboot 集成 rocketmq 消费者
1、打开 idea 创建 springboot-rocketmq-consumer 项目,并在项目 pom.xml 中添加 依赖。
--> idea --> File
--> New --> Project
--> Maven
Project SDK: ( 1.8(java version "1.8.0_131" )
--> Next
--> Groupld : ( djh.it )
Artifactld : ( springboot-rocketmq-consumer )
Version : 1.0-SNAPSHOT
--> Name: ( springboot-rocketmq-consumer )
Location: ( ...\springboot-rocketmq-consumer\ )
--> Finish
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>djh.it</groupId>
<artifactId>springboot-rocketmq-consumer</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<properties>
<rocketmq-spring-boot-starter-version>2.0.3</rocketmq-spring-boot-starter-version>
</properties>
<dependencies>
<!-- 添加web起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>${rocketmq-spring-boot-starter-version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
<!-- D:\Java\java-test\idea\springboot-rocketmq-consumer\pom.xml -->
2、在项目 springboot-rocketmq-consumer 中,添加 application.properties 配置文件
## springboot-rocketmq-consumer\src\main\resources\application.properties
# nameserver :集群配置
# rocketmq.name-server=192.168.25.135:9876;192.168.25.138:9876
# nameserver :单机配置
rocketmq.name-server=172.18.30.110:9876
# 消费者组名
rocketmq.consumer.group=my-group
3、在项目 springboot-rocketmq-consumer 中,创建启动类 ConsumerApplication.java
/**
* springboot-rocketmq-consumer\src\main\java\djh\it\shop\springboot\rocketmq\ConsumerApplication.java
*
* 2024-6-4 创建启动类 ConsumerApplication.java
*/
package djh.it.shop.springboot.rocketmq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@Slf4j
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
log.info("消费者启动成功");
}
}
4、在项目 springboot-rocketmq-consumer 中,创建监听器类 Consumer.java
/**
* springboot-rocketmq-consumer\src\main\java\djh\it\shop\springboot\rocketmq\listener\Consumer.java
*
* 2024-6=4 创建监听器类 Consumer.java
*/
package djh.it.shop.springboot.rocketmq.listener;
import org.apache.rocketmq.spring.annotation.ConsumeMode;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;
@RocketMQMessageListener(topic = "springboot-rocketmq", consumeMode = ConsumeMode.CONCURRENTLY, consumerGroup="${rocketmq.consumer.group}")
@Component
public class Consumer implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.println("接收到消息:" + message);
}
}
5、提前安装配置好 RocketMQ 服务,并启动服务,然后启动 ConsumerApplication.java 启动类 和 启动类 ProducerApplication.java 进行测试。
上一节关联链接请点击:
# 全面解剖 消息中间件 RocketMQ-(5)