网易首页 > 网易号 > 正文 申请入驻

淘宝七天自动确认收货,可以怎么实现?

0
分享至

目前常见的应用软件都有消息的延迟推送的影子,应用也极为广泛,例如:

  • 淘宝七天自动确认收货。在我们签收商品后,物流系统会在七天后延时发送一个消息给支付系统,通知支付系统将款打给商家,这个过程持续七天,就是使用了消息中间件的延迟推送功能。

  • 12306 购票支付确认页面。我们在选好票点击确定跳转的页面中往往都会有倒计时,代表着 30 分钟内订单不确认的话将会自动取消订单。其实在下订单那一刻开始购票业务系统就会发送一个延时消息给订单系统,延时30分钟,告诉订单系统订单未完成,如果我们在30分钟内完成了订单,则可以通过逻辑代码判断来忽略掉收到的消息。

在上面两种场景中,如果我们使用下面两种传统解决方案无疑大大降低了系统的整体性能和吞吐量:

  • 使用 redis 给订单设置过期时间,最后通过判断 redis 中是否还有该订单来决定订单是否已经完成。这种解决方案相较于消息的延迟推送性能较低,因为我们知道 redis 都是存储于内存中,我们遇到恶意下单或者刷单的将会给内存带来巨大压力。

  • 使用传统的数据库轮询来判断数据库表中订单的状态,这无疑增加了IO次数,性能极低。

  • 使用 jvm 原生的 DelayQueue ,也是大量占用内存,而且没有持久化策略,系统宕机或者重启都会丢失订单信息。

消息延迟推送的实现

在 RabbitMQ 3.6.x 之前我们一般采用死信队列+TTL过期时间来实现延迟队列,我们这里不做过多介绍。

在 RabbitMQ 3.6.x 开始,RabbitMQ 官方提供了延迟队列的插件,可以下载放置到 RabbitMQ 根目录下的 plugins 下。

首先我们创建交换机和消息队列,application.properties 中配置与上一篇文章相同。

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;

@Configuration
public class MQConfig {

public static final String LAZY_EXCHANGE = "Ex.LazyExchange";
public static final String LAZY_QUEUE = "MQ.LazyQueue";
public static final String LAZY_KEY = "lazy.#";

@Bean
public TopicExchange lazyExchange(){
//Map pros = new HashMap<>();
//设置交换机支持延迟消息推送
//pros.put("x-delayed-message", "topic");
TopicExchange exchange = new TopicExchange(LAZY_EXCHANGE, true, false, pros);
exchange.setDelayed(true);
return exchange;
}

@Bean
public Queue lazyQueue(){
return new Queue(LAZY_QUEUE, true);
}

@Bean
public Binding lazyBinding(){
return BindingBuilder.bind(lazyQueue()).to(lazyExchange()).with(LAZY_KEY);
}
}

我们在 Exchange 的声明中可以设置exchange.setDelayed(true)来开启延迟队列,也可以设置为以下内容传入交换机声明的方法中,因为第一种方式的底层就是通过这种方式来实现的。

//Map pros = new HashMap<>();
//设置交换机支持延迟消息推送
//pros.put("x-delayed-message", "topic");
TopicExchange exchange = new TopicExchange(LAZY_EXCHANGE, true, false, pros);

发送消息时我们需要指定延迟推送的时间,我们这里在发送消息的方法中传入参数new MessagePostProcessor()是为了获得Message对象,因为需要借助Message对象的api 来设置延迟时间。

import com.anqi.mq.config.MQConfig;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class MQSender {

@Autowired
private RabbitTemplate rabbitTemplate;

//confirmCallback returnCallback 代码省略,请参照上一篇

public void sendLazy(Object message){
rabbitTemplate.setMandatory(true);
rabbitTemplate.setConfirmCallback(confirmCallback);
rabbitTemplate.setReturnCallback(returnCallback);
//id + 时间戳 全局唯一
CorrelationData correlationData = new CorrelationData("12345678909"+new Date());

//发送消息时指定 header 延迟时间
rabbitTemplate.convertAndSend(MQConfig.LAZY_EXCHANGE, "lazy.boot", message,
new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
//设置消息持久化
message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
//message.getMessageProperties().setHeader("x-delay", "6000");
message.getMessageProperties().setDelay(6000);
return message;
}
}, correlationData);
}
}

我们可以观察setDelay(Integer i)底层代码,也是在 header 中设置 x-delay。等同于我们手动设置 header

message.getMessageProperties().setHeader("x-delay", "6000");

/**
* Set the x-delay header.
* @param delay the delay.
* @since 1.6
*/
public void setDelay(Integer delay) {
if (delay == null || delay < 0) {
this.headers.remove(X_DELAY);
}
else {
this.headers.put(X_DELAY, delay);
}
}

2

消费端进行消费

import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

@Component
public class MQReceiver {

@RabbitListener(queues = "MQ.LazyQueue")
@RabbitHandler
public void onLazyMessage(Message msg, Channel channel) throws IOException{
long deliveryTag = msg.getMessageProperties().getDeliveryTag();
channel.basicAck(deliveryTag, true);
System.out.println("lazy receive " + new String(msg.getBody()));

## 测试结果[#](https://www.cnblogs.com/haixiang/p/10966985.html#3724420099)

```java
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;

@SpringBootTest
@RunWith(SpringRunner.class)
public class MQSenderTest {

@Autowired
private MQSender mqSender;

@Test
public void sendLazy() throws Exception {
String msg = "hello spring boot";

mqSender.sendLazy(msg + ":");
}
}

果然在 6 秒后收到了消息lazy receive hello spring boot:

福利

IT架构师/技术大咖的交流圈子,为您提供架构体系知识、技术文章、流行实践案例、解决方案等,行业大咖分享交流/同行经验分享互动,期待你的加入!扫码即可加入哦

随着材料不断增多社群会不定期涨价早加入更优惠

公众号发送如下关键字获取免费资料:

1.架构电子书视频--回复"架构"

2.架构实践案例集--回复"实践"

3.Docker实战文档--回复"docker"

4.技术架构规划文档--回复"规划"

5.华为鸿蒙技术资料--回复"华为"

免责声明:

本公众号部分分享的资料来自网络收集和整理,所有文字和图片版权归属于原作者所有,且仅代表作者个人观点,与本公众号无关,文章仅供读者学习交流使用,并请自行核实相关内容,如文章内容涉及侵权,请联系后台管理员删除。

非功能性架构和高可用性设计

系统架构性能问题诊断及优化思路,纯干货!

微服务架构统一安全认证设计与实践

千万级DAU系统该如何设计

这才是真正的架构设计 !

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
3连胜+第8胜,火箭队为什么赢球,5个决定很正确,重用一人回报大

3连胜+第8胜,火箭队为什么赢球,5个决定很正确,重用一人回报大

体坛大辣椒
2024-11-14 11:32:00
星舰再次出发,怎么还带个香蕉?

星舰再次出发,怎么还带个香蕉?

身轻如雁
2024-11-14 10:32:42
环球足球奖最佳男球员候选名单:C罗、梅西、亚马尔在列

环球足球奖最佳男球员候选名单:C罗、梅西、亚马尔在列

直播吧
2024-11-14 16:38:15
尼克斯无缘22分逆转遭准绝杀 唐斯46+10加盟新高布伦森丢反绝杀

尼克斯无缘22分逆转遭准绝杀 唐斯46+10加盟新高布伦森丢反绝杀

醉卧浮生
2024-11-14 12:20:36
特朗普拜登白宫会面,一笑泯恩仇!新内阁任命基本完成,一窝老鹰

特朗普拜登白宫会面,一笑泯恩仇!新内阁任命基本完成,一窝老鹰

靓仔情感
2024-11-14 11:38:35
给阿门-汤普森找个伊森&小卡式的比较对象?乌度卡:奥萨尔

给阿门-汤普森找个伊森&小卡式的比较对象?乌度卡:奥萨尔

直播吧
2024-11-14 12:20:28
男子网恋奔现,清纯学生妹变大姐,男子:知足了!起码性别对了

男子网恋奔现,清纯学生妹变大姐,男子:知足了!起码性别对了

佑宛故事汇
2024-11-12 17:56:12
三对夫妻旅游途中互相发生性关系,判刑后仍不认罪

三对夫妻旅游途中互相发生性关系,判刑后仍不认罪

书画艺术收藏
2024-11-10 20:00:02
邓超走到了这一步,证明了冯小刚说的那句话,真对

邓超走到了这一步,证明了冯小刚说的那句话,真对

喵喵娱乐团
2024-11-12 16:11:50
“美国不需要你,有本事你去中国啊!”

“美国不需要你,有本事你去中国啊!”

铁山学者
2024-10-07 13:02:18
尘埃落定!皇马新帅曝光!42岁少帅接班,德甲不败夺冠,佛爷钦点

尘埃落定!皇马新帅曝光!42岁少帅接班,德甲不败夺冠,佛爷钦点

阿泰希特
2024-11-14 13:21:36
惨绝人寰的75.8大灾难,究竟导致多少人死亡,2.6万还是24万人

惨绝人寰的75.8大灾难,究竟导致多少人死亡,2.6万还是24万人

暗夜罗裳
2023-10-30 15:39:55
67年王近山求见王震:凭我这张老脸找你了,王震:就这张老脸管用

67年王近山求见王震:凭我这张老脸找你了,王震:就这张老脸管用

跳跳历史
2024-11-14 14:12:17
特朗普誓将跨界玩出花?前福克斯主持人被任命为国防部长

特朗普誓将跨界玩出花?前福克斯主持人被任命为国防部长

财联社
2024-11-13 10:49:08
一个兽医,套现30亿的操作

一个兽医,套现30亿的操作

大猫财经Pro
2024-11-13 14:29:08
禹作敏最嚣张的时候有多无法无天?

禹作敏最嚣张的时候有多无法无天?

尚书乔
2024-11-10 00:00:03
程序员要失业了!百度推出秒哒,无需写代码也能实现任意想法

程序员要失业了!百度推出秒哒,无需写代码也能实现任意想法

映射生活的身影
2024-11-12 15:55:33
记者:国青重点考察几位海归球员,杨希被要求大胆投入进攻

记者:国青重点考察几位海归球员,杨希被要求大胆投入进攻

懂球帝
2024-11-14 14:51:14
中国6大长寿食物,鱼排第3,第一名经常被当早餐,有你爱吃的吗?

中国6大长寿食物,鱼排第3,第一名经常被当早餐,有你爱吃的吗?

小谈食刻美食
2024-11-13 19:35:06
总算是打出了一场像样的比赛,湖人锋线大将需要保持这样的水准?

总算是打出了一场像样的比赛,湖人锋线大将需要保持这样的水准?

稻谷与小麦
2024-11-14 16:49:53
2024-11-14 17:10:44
IT架构师联盟
IT架构师联盟
IT架构实战分享
708文章数 7653关注度
往期回顾 全部

科技要闻

极氪与领克合并,吉利从大扩张走向大整合

头条要闻

广州人社局回应中学生获评正高级职称:可能性几乎没有

头条要闻

广州人社局回应中学生获评正高级职称:可能性几乎没有

体育要闻

微信第一控卫哈利伯顿,是数据刷子吗?

娱乐要闻

娜扎张云龙恋情曝光!甜蜜细节被扒

财经要闻

楼市"税收新政",影响有多大?最新解读

汽车要闻

七块屏幕四座布局 仰望U7中式百万座舱

态度原创

手机
房产
家居
亲子
艺术

手机要闻

iQOO Neo10 系列手机全系支持 120W 快充

房产要闻

减税!降利率!降房价!降门槛…海南买房成本,正在大幅降低!

家居要闻

现代潮流空间 轻奢现代风并重

亲子要闻

家长的三种方法把孩子重养一遍!

艺术要闻

故宫珍藏的墨迹《十七帖》,比拓本更精良,这才是地道的魏晋写法

无障碍浏览 进入关怀版