RabbitMQ TTL、死信队列在订单支付场景的应用

基于RabbitMQ的TTL以及死信队列,使用SpringBoot实现延迟付款,手动补偿操作。

1、用户下单后展示等待付款页面

2、在页面上点击付款的按钮,如果不超时,则跳转到付款成功页面

3、如果超时,则跳转到用户历史账单中查看因付款超时而取消的订单。

生产者:

配置类

package com.lagou.config;import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;
import java.util.Map;/*** @Date 2020/8/24 17:34* @Created weijie* @Description*/@Configuration
public class RabbitConfig {@Beanpublic Queue queue() {Map<String, Object> props = new HashMap<>();// 消息的生存时间 30sprops.put("x-message-ttl", 30000);// 设置该队列所关联的死信交换器(当队列消息TTL到期后依然没有消费,则加入死信队列)props.put("x-dead-letter-exchange", "ex.go.dlx");// 设置该队列所关联的死信交换器的routingKey,如果没有特殊指定,使用原队列的routingKeyprops.put("x-dead-letter-routing-key", "go.dlx");Queue queue = new Queue("q.go", true, false, false, props);return queue;}@Beanpublic Queue queueDlx() {Queue queue = new Queue("q.go.dlx", true, false, false);return queue;}@Beanpublic Exchange exchange() {DirectExchange exchange = new DirectExchange("ex.go", true,false, null);return exchange;}/*** 死信交换器* @return*/@Beanpublic Exchange exchangeDlx() {DirectExchange exchange = new DirectExchange("ex.go.dlx", true,false, null);return exchange;}@Beanpublic Binding binding() {returnBindingBuilder.bind(queue()).to(exchange()).with("go").noargs();}/*** 死信交换器绑定死信队列* @return*/@Beanpublic Binding bindingDlx() {returnBindingBuilder.bind(queueDlx()).to(exchangeDlx()).with("go.dlx").noargs();}}

支付接口:

package com.lagou.controller;import com.lagou.entity.Order;
import com.lagou.service.OrderService;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import java.util.Date;
import java.util.List;
import java.util.UUID;/*** @Date 2020/8/23 22:27* @Created by weijie* @Description*/@Controller
public class OrderController {@AutowiredAmqpTemplate amqpTemplate;@AutowiredOrderService orderService;int count = 0;/*** 下订单接口、支付接口、查看订单接口*/@RequestMapping("/order/create/orderId")public void createOrder(@PathVariable String orderId){Order order = new Order();order.setOrderCode(UUID.randomUUID().toString());order.setCreateTime(new Date());order.setIsPay(0);order.setOrderName("订单:" + count++);amqpTemplate.convertAndSend("ex.go", "go", order);orderService.update(order);}@RequestMapping("/pay/orderCode")@ResponseBodypublic String pay(@PathVariable String orderCode){Order order = orderService.findByOrderCode(orderCode);if (order == null){return "订单不存在";}if (order.getIsPay() == 1){return "订单已支付";}if (order.getStatus() == 1){return "订单已超时";}//订单支付成功order.setIsPay(1);//未超时order.setStatus(0);orderService.update(order);return "订单支付成功";}@RequestMapping("/order/list")@ResponseBodypublic List<Order> list(){List<Order> all = orderService.findAll();return all;}}

消费者

配置类:

package com.lagou.config;import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @Date 2020/8/24 15:19* @Created weijie* @Description*/@Configuration
public class RabbitConfig {@Beanpublic Queue queue(){return QueueBuilder.nonDurable("q.go.dlx").build();}
}

监听订单队列:

package com.lagou.consumer;import com.lagou.entity.Order;
import com.lagou.service.OrderService;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.io.IOException;/*** @Date 2020/8/24 15:35* @Created weijie* @Description*/@Component
public class Listener {@AutowiredOrderService orderService;private Integer index = 0;/*** 监听私信队里中的值* @param msg* @param channel*/@RabbitListener(queues = "q.go.dlx")public void getMessage(Message msg, Channel channel) throws IOException {String orderCode = new String(msg.getBody());System.out.println("超时订单 : " + orderCode);//需要确认收到的消息,否则死信队列消息会一直存在//???long deliveryTag = msg.getMessageProperties().getDeliveryTag();if (index % 2 == 0){//确认消息channel.basicAck(deliveryTag, false);}else{//拒收消息channel.basicAck(deliveryTag, false);}index ++;Order order = orderService.findByOrderCode(orderCode);if (order == null){System.out.println("未查询到相应订单:" + orderCode);return;}//订单已支付if (order.getIsPay() > 0){System.out.println("订单已支付:" + orderCode);return;}//订单未支付order.setIsPay(0);//订单已超时order.setIsTimeOut(1);orderService.update(order);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508837.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里巴巴Java开发手册-使用JDK8的Opional类来防止出现NPE问题

/*** https://www.baeldung.com/java-optional*/Testpublic void optionalTest(){Peo peo new Peo("weijie", 18);/*** of、ofNullable*///of 判断peo是否为空&#xff0c;如果不为空程序继续执行Optional<Peo> _of Optional.of(peo);//程序直接抛出NullExce…

阿里巴巴Java开发手册-finally块必须对资源对象、流对象进行关闭操作,如果有异常也要做try-cach操作

对于JDK7及以上版本&#xff0c;可以使用try-with-resources方式 使用方式&#xff1a; /*** https://www.cnblogs.com/itZhy/p/7636615.html* 其实这种方式只是语法糖&#xff0c;反编译以后还是tryCacheThrowTest()中的代码* https://www.cnblogs.com/langtianya/p/5139465.h…

阿里巴巴Java开发手册-日志规约

1.【强制】 应用中不可直接使用日志系统(Log4j、Logback)中的API&#xff0c;而应依赖使用的SLF4j中的API。使用门面模式的日志框架吗&#xff0c;有利于维护和各个类的日志处理方式统一。 import org.slf4j.Logger;import org.slf4j.LoggerFactory;Logger logger LoggerFacto…

Java 回调 (Callback) 接口学习使用

文章目录Java 回调 (Callback) 接口学习使用1.什么是回调(Callback)&#xff1f;2.Java代码示例2.直接调用3.接口调用4.Lambda表达式推荐看我的InfoQ地址&#xff0c;界面排版更简洁Java 回调 (Callback) 接口学习使用 1.什么是回调(Callback)&#xff1f; 回调函数&#xff0…

常用的限流算法学习

常用的限流算法有漏桶算法和令牌桶算法&#xff0c;guava的RateLimiter使用的是令牌桶算法&#xff0c;也就是以固定的频率向桶中放入令牌&#xff0c;例如一秒钟10枚令牌&#xff0c;实际业务在每次响应请求之前都从桶中获取令牌&#xff0c;只有取到令牌的请求才会被成功响应…

基于rocketMq秒杀系统demo

基于RocketMQ设计秒杀。 要求&#xff1a; 1. 秒杀商品LagouPhone&#xff0c;数量100个。 2. 秒杀商品不能超卖。 3. 抢购链接隐藏 4. NginxRedisRocketMQTomcatMySQL 实现 接口说明&#xff1a;https://www.liuchengtu.com/swdt/#R9f978d0d00ef9be99f0…

常见压缩算法学习

文章目录无损压缩算法理论基础信息熵熵编码字典编码综合通用无损压缩算法相关常见名词说明java对几种常见算法实现Snappydeflate算法Gzip算法huffman算法Lz4算法Lzo算法使用方式无损压缩算法理论基础 信息熵 信息熵是一个数学上颇为抽象的概念&#xff0c;在这里不妨把信息熵理…

java中钩子方法 addShutdownHook 学习使用

钩子作用&#xff1a; 在线上Java程序中经常遇到进程程挂掉&#xff0c;一些状态没有正确的保存下来&#xff0c;这时候就需要在JVM关掉的时候执行一些清理现场的代码。Java中得ShutdownHook提供了比较好的方案。 JDK在1.3之后提供了Java Runtime.addShutdownHook(Thread hook)…

基于Curator实现dubbo服务自动注册发现

文章目录概念基于ServiceDiscovery实现服务自动注册和发现Service:服务基本信息InstanceDetails:封装实例用过来保存到zk中ServiceProvider&#xff1a;服务提供者ServiceConsumer&#xff1a;服务消费者运行基于ServiceDiscovery、ServiceCache实现服务自动注册和发现Registry…

jdk、cglib动态代理代码示例

文章目录jdk动态代理实现步骤代码示例新建一个接口新建一个接口的实现类新建一个代理类调用测试cglib动态代理实现实现步骤创建一个实现类新建一个代理类调用测试jdk动态代理 实现步骤 新建一个接口新建一个接口的实现类新建一个代理类&#xff0c;实现InvocationHandler接口…

Netty 客户端服务器端通信 demo

服务端 package com.demo.rpc.netty;import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioSocketC…

Solr实战篇

1.在MySQL数据中建立lagou_db数据库, 将position.sql中的数据导入到mysql 数据中。 2.使用Solr的DIH 将mysql中的数据导入到Solr中。 3.使用SpringBoot 访问Solr 使用positionName 字段检索职位信息 如果检索到的职位信息不够5条 则需要 启用positionAdvantage 查找 美女多、…

Elasticsearch Java Low Level REST Client(通用配置)

Elasticsearch Java Low Level REST Client&#xff08;通用配置&#xff09; 通用配置 正如初始化中所解释的&#xff0c;RestClientBuilder支持提供RequestConfigCallback和HttpClientConfigCallback&#xff0c;它们允许Apache Async Http Client公开的任何自定义。这些回…

elasticsearch实战篇

文章目录1.新建SpringBoot项目依赖2.实现配置模块 config控制层 controller模型层 model服务层 service工具 util主类单元测试1.新建SpringBoot项目 依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org…

Docker 部署java服务

作业描述&#xff1a; &#xff08;1&#xff09;Hot是应用程序(springboot)&#xff0c;打成jar包&#xff1a;docker-demo-1.0-SNAPSHOT.jar &#xff08;2&#xff09;利用dockerfile将docker-demo-1.0-SNAPSHOT.jar构建成镜像docker-demo Dockerfile-docker-demo&#xf…

单向链表 双向链表 java代码实现

文章目录单向链表代码实现单元测试控制台打印头插法尾插法双向链表代码实现单元测试控制台打印头插法尾插法单向链表 代码实现 package csdn.dreamzuora.list;/*** author: weijie* Date: 2020/10/15 15:28* Description:*/ public class SingleNode {int id;String name…

栈、队列 java代码实现

文章目录普通队列数组实现java代码实现单元测试控制台打印链表实现java代码实现单元测试控制台打印LinkedList队列使用优先队列&#xff1a;PriorityQueue使用栈数组实现java代码实现单元测试控制台打印链表实现java代码实现单元测试控制台打印普通队列 概念&#xff1a;先入先…

递归学习 斐波那契 java代码实现

文章目录java代码单元测试java代码 package csdn.dreamzuora.recursion;/*** Title: 斐波那契额* Description:*斐波那契数列&#xff1a;0、1、1、2、3、5、8、13、21、34、55.....* f[n] f[n-2] f[n-1]* 优点&#xff1a;代码简单* 缺点&#xff1a;占用空间较大、如果递归…

二分查找 java代码实现

文章目录二分查找java代码单元测试二分查找java代码 package csdn.dreamzuora.query;/*** Title: 二分查找* Description:* 时间复杂度&#xff1a;log2N* version 1.0* author: weijie* date: 2020/10/16 13:52*/ public class BinarySearch implements Search {int[] array;…

二叉查找树 java代码实现

文章目录代码实现节点实现类二叉树实现单元测试代码实现 节点实现类 package csdn.dreamzuora.tree;/*** Title:* Description:** version 1.0* author: weijie* date: 2020/10/19 13:30*/ public interface Node { }package csdn.dreamzuora.tree;import java.io.Serializab…