赞
踩
互相交流入口地址
整体目录:
【九】springboot整合redis实现启动服务时热点数据保存在全局和缓存
【十三】springboot整合WebService关于传参数
【十五】springboot整合WebSocket实现聊天室
【十六】RabbitMQ基础篇(下载安装并基础使用,内含各种坑问题)
【十九】初学Kafka并实战整合SpringCloudStream进行使用
【二十】springboot整合ElasticSearch实战(万字篇)
【二十三】springboot整合activiti7(1)实战演示篇
【二十四】springboot整合spring事务详解以及实战
【二十五】springboot使用EasyExcel和线程池实现多线程导入Excel数据
【二十六】springboot整合jedis和redisson布隆过滤器处理缓存穿透
【二十八】springboot之threadLocal参数解析器实现session一样保存当前登录功能
目录
本章将通过学习rabbitMQ基础中的延时队列和死信队列,然后写一个demo实现一个小例子,在商城购物时,先下单创建订单记录,然后可以选择进行立即支付或者不支付,若30秒后不支付,则删除订单。下面针对这个例子进行学习。
首先展示一下最终效果,并进行效果讲解,如下所示:
描述:点击购买,创建订单记录,在倒计时内支付成功的话,正常完成购买流程。
描述:点击购买,创建订单记录,在倒计时内未支付成功的话,删除该笔订单。
下面为了满足上述效果,进行实现。
为了满足上面的效果,可以通过很多方法实现,最简单的就是定时任务,创建一个定时任务,定时去请求数据,查看状态为未支付的订单,并删除。当然还可以通过redis或者其他办法,本章当然是通过RabbitMQ的方式实现,将通过延时队列和死信队列实现,逻辑关系如下:
所以需要创建如下几个东西:
分析完毕,下面开整。
建表语句
- CREATE TABLE `dingdan` (
- `id` varchar(255) COLLATE utf8_bin NOT NULL,
- `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
- `type` int DEFAULT NULL COMMENT '0:未支付,1:已支付,默认0',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
上面测试效果是随便整的,过于简便,代码我直接贴出来:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>订单</title>
- </head>
- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
- <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
-
- <body>
- <div style="width: 100%;height: 300px;display: flex;justify-content: center;margin-top: 200px;">
- <div class="card" style="width: 15rem;">
- <img class="card-img-top" style="" src="./img/apple.jpg" alt="Card image cap">
- <div class="card-body">
- <h5 class="card-title">苹果售价:100¥</h5>
- <a onclick="fun1()" style="margin-top: 20px;margin-left: 70px;" class="btn btn-primary">购买</a>
- </div>
- </div>
- </div>
- </body>
-
- <script type="text/javascript">
- function fun1(){
- console.log("点击");
-
- $.ajax({
- url:"http://localhost:7778/dingdanController/insertDingdan",
- data:null,
- type:"post",
- dataType: "json",
- success: function(data) {
- console.log("返回值:"+data.id);
- window.location.href="支付.html?id="+data.id
- }
- });
- }
- </script>
- </html>
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>支付</title>
- </head>
- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
- <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
-
- <body>
- <div style="width: 100px;height: 30px;text-align: center;line-height: 30px;margin-top: 100px;margin-left: 50%;background-color: aliceblue;">
- 支付倒计时:
- </div>
- <div id="time" style="width: 100px;height: 30px;text-align: center;line-height: 30px;margin-top: 10px;margin-left: 50%;background-color: aliceblue;">
-
- </div>
- <button onclick="fun1()" style="margin-top: 10px;margin-left: 50%;" type="button" class="btn btn-primary">确定支付</button>
- </body>
- <script type="text/javascript">
-
- var id = getid('id');
- console.log(id);
- // alert(id);
-
- var i=15;
- $("#time").html(i);
- var time1 =setInterval(function(){
- if(i>0){
- i=i-1;
- $("#time").html(i);
- }else{
- clearInterval(time1);
- }
- },1000)
-
- var time2 = setInterval(function(){
- var i = $("#time").html();
- if(i==0){
- window.location.href="订单.html"
- }
- },1000)
-
- //支付
- function fun1(){
- alert("支付成功");
- clearInterval(time1);
- clearInterval(time2);
- $.ajax({
- url:"http://localhost:7778/dingdanController/pay",
- data:{id:id},
- type:"post",
- dataType: "json",
- success: function(data) {
-
- }
- });
-
- }
- //取值
- function getid(names, urls) {
- urls = urls || window.location.href;
- urls && urls.indexOf("?") > -1 ? urls = urls
- .substring(urls.indexOf("?") + 1) : "";
- var reg = new RegExp("(^|&)" + names + "=([^&]*)(&|$)", "i");
- var r = urls ? urls.match(reg) : window.location.search.substr(1)
- .match(reg);
- if (r != null && r[2] != "")
- return unescape(r[2]);
- return null;
- };
- </script>
- </html>
用的ajax和bootstrap。
下面开始本章的核心改造,首先补一下前面章节的坑,建立父子工程时,直接在父工程的maven进行打包会出异常,因为其中含有一个common公共模块,其他服务有使用commo模块的东西,为了避免编译整个父工程时再报错,在功能模块代码的pom文件,增加如下代码:
这样,下次在父工程直接编译就不会再找不到各个模块对commom模块的依赖了。
然后本次测试会涉及到数据库的操作,所以直接引入mybatis-plus,便于操作,关于mybatis-plus的操作,前面springboot整合篇有讲到。
此处再简单讲一下整合mybatis-plus简要步骤:
接下来改造common模块,为了方便管理,每个模块公用的东西都放到了common子工程,上一章有将topic主题模式消息队列涉及到的常量放到common的RabbitMQConstant类中,但是本章为了方便看,就直接不将常量信息放到其中。
还是展示一下改造后的provider服务的最终目录结构,如下:
框选部分为新增代码,下面开整。
简要描述:
1、创建一个支付接口,一个创建订单接口。
2、创建订单接口:创建订单记录,并发送消息(传订单id)到延时交换机,并将id返回前端方便前端调用支付接口。
3、支付接口:根据订单id,改变订单已支付状态,避免被消息监听器处理。
接着改造consumer服务,最终目录结构如下:
框选处为新增代码。
简要描述:
类似原来的主题模式的常规配置,只不过此处的延时队列创建时有所不同,需要先设置好各个参数再创建,注释有说明,此处为了方便操作,直接使用的路由模式,没有使用主题模式。
3. 新增死信队列监听器
简要描述:
根据从队列接收到的消息处理具体的逻辑,根据订单id查询订单记录,若存在则判断是否已支付,若未支付则删除。
演示效果如本章开篇所展示的一致,此处就不展示了,感兴趣的朋友可以尝试一下,over。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。