RabbitMQ TTL、死信队列在订单支付场景的应用
生活随笔
收集整理的這篇文章主要介紹了
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);}}總結
以上是生活随笔為你收集整理的RabbitMQ TTL、死信队列在订单支付场景的应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux常用压缩和解压命令
- 下一篇: 【kaggle入门题一】Titanic: