淘宝最长多少天确认收货(面试官问:淘宝七天自动确认收货,让你设计,可以怎么实现?)

目前常见的应用软件都有消息延迟推送的影子,而且应用广泛,比如:

  • 淘宝七天自动确认收货。我们签收货物后,物流系统会延迟七天后向支付系统发送消息,通知支付系统将钱支付给商家。这个过程持续七天,也就是使用了消息中间件的延迟推送功能。
  • 1306购票支付确认页面。我们在选择机票点击确定跳转的页面上经常会有一个倒计时,意思是如果30分钟内没有确认订单,订单会自动取消。实际上,在下单的瞬间,票务业务系统会向订单系统发送延迟消息,延迟30分钟告知订单系统订单未完成。如果我们在30分钟内完成订单,我们可以通过逻辑代码判断忽略收到的消息。
  • 在上述两种场景下,如果我们使用以下两种传统解决方案,系统的整体性能和吞吐量无疑会大大降低:

  • 使用redis为订单设置到期时间,最后通过判断redis中是否还有订单来确定订单是否已经完成。相比消息的延迟推送性能,这种解决方案的性能更低,因为我们知道redis是存储在内存中的,当我们遇到恶意的订单或者账单时,会给内存带来很大的压力。
  • 传统的数据库轮询是用来判断数据库表中订单的状态,这无疑增加了IO的数量,性能极低。
  • 使用jvm的native DelayQueue也要占用大量内存,而且没有持久化策略,系统在宕机或重启时会丢失订单信息。
  • 消息延迟推送的实现

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

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

    淘宝确认收货时间是多长

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

    导入org . spring framework . amqp . core . *; 导入org . spring framework . context . annotation . bean; import org . spring framework . context . annotation . configuration; 导入Java . util . hashmap; 导入Java . util . map; @ Configuration public class MQ config { public static final String LAZY _ EXCHANGE = & # 34;《出埃及记》LazyExchange & # 34; public static final String LAZY _ QUEUE = & # 34;MQ。懒人队列& # 34;; public static final String LAZY _ KEY = & # 34;懒惰。#"; @ Bean public topic exchange lazy exchange(){ //Map & lt;字符串,对象& gtpros = new HashMap & lt& gt(); //设置开关支持延迟消息推送 /pros . put(& # 34;x延迟消息& # 34;, "话题& # 34;); topic EXCHANGE EXCHANGE = new topic EXCHANGE(LAZY _ EXCHANGE,true,false,pros); exchange . set delayed(true); 退货换货; } @Bean 公共队列lazyQueue(){ 返回新队列(LAZY_QUEUE,true); } @ Bean public Binding lazy Binding(){ return Binding builder . bind(lazy queue())。到(lazyExchange())。用(LAZY _ KEY); } } 我们可以设置交换。setdelayed (true)在交换的声明中打开延迟队列,或者我们可以把下面的内容设置到switch声明的方法中,因为第一个方法的底层就是这样实现的。

    //地图& lt字符串,对象& gtpros = new HashMap & lt& gt(); //设置开关支持延迟消息推送 /pros . put(& # 34;x延迟消息& # 34;, "话题& # 34;); topic EXCHANGE EXCHANGE = new topic EXCHANGE(LAZY _ EXCHANGE,true,false,pros); 发送消息时,我们需要指定延迟推送的时间。这里,我们在发送消息的方法中传入参数new MessagePostProcessor()以获取消息对象,因为我们需要借助消息对象的api来设置延迟时间。

    导入com . anqi . MQ . config . MQ config; import org . spring framework . amqp . amqp exception; 导入org . spring framework . amqp . core . message; import org . spring framework . amqp . core . messagedeliverymode; import org . spring framework . amqp . core . messagepostprocessor; 导入org . spring framework . amqp . rabbit . connection . correlation data; 导入org . spring framework . amqp . rabbit . core . rabbit template; import org . spring framework . beans . factory . annotation . auto wired; 导入org . spring framework . stereotype . component; 导入Java . util . date; @ Component public class MQ sender { @ Autowired private rabbit template rabbit template; //确认回调返回回调代码省略,请参考上一篇文章 Public void send lazy(object message){ rabbit template . set mandatory(true); rabbit template . setconfirmcallback(confirm callback); rabbit template . setreturncallback(return callback);[/h //id+全局唯一时间戳 关联数据关联数据=新的关联数据(& # 34;12345678909"+new Date()); //指定发送消息时的头延迟时间 rabbit template . convertandsend(MQ config . lazy _ exchange,& # 34;lazy.boot & # 34,message, new messagepostprocessor(){ @ override public message postprocessmessage(message message)throwsamqpexception { //设置消息持久性 message . getmessageproperties()。setDeliveryMode(MessageDeliveryMode。持久); //message . getmessageproperties()。set header(& # 34;x延迟& # 34;, "6000"); message . getmessageproperties()。set delay(6000); 返回消息; } },correlation data); } } 我们可以观察setDelay(整数I)的底层代码,也可以在头中设置x-delay。相当于手动设置表头。

    message.getMessageProperties()。set header(& # 34;x延迟& # 34;, "6000"); /** *设置x延迟标题。 * @param delay延迟。 * @自1.6 */ public void set delay(整数延迟){ if(delay = = null | | delay & lt;0){ this . headers . remove(X _ DELAY); } else { this . headers . put(X _ DELAY,DELAY); } } 消费端消费。

    导入com . rabbit MQ . client . channel; 导入org . spring framework . amqp . rabbit . annotation . *; 导入org . spring framework . amqp . support . amqp headers; 导入org . spring framework . stereotype . component; 导入Java . io . io exception; 导入Java . util . map; @ Component public class MQReceiver { @ rabbit listener(queues = & # 34;MQ。懒人队列& # 34;) @ rabbit handler public void onLazyMessage(消息msg,通道Channel)抛出io exception { long delivery tag = msg . getmessage properties()。getDeliveryTag(); channel . basic ack(delivery tag,true); system . out . println(& # 34;懒惰接收& # 34;+new String(msg . getbody()); } ` ` ` ` # #测试结果[#](https://www.cnblogs.com/haixiang/p/10966985.html # 3724485 导入org . JUnit . runner . run with; import org . spring framework . beans . factory . annotation . auto wired; 导入org . spring framework . boot . test . context . spring boot test; 导入org . spring framework . test . context . JUnit 4 . spring runner; @ spring boot test @ run with(spring runner . class) public class MQSenderTest { @ Autowired private MQSender MQSender; @ Test public void send lazy()抛出异常{ String msg = & # 34;hello spring boot & # 34; MQ sender . send lazy(msg+& # 34;:"); } } 果不其然,6秒后我收到了消息lazy receive hello spring boot:

    您可以还会对下面的文章感兴趣

    最新评论

    1. 食堂干饭王
      食堂干饭王
      发布于:2022-04-27 05:55:00 回复TA
      ng lazy Binding(){return Binding builder . bind(lazy queue())。到(lazyExchange())。用(LAZY _ KEY); }}我们可
    1. 碧蓝幻想
      碧蓝幻想
      发布于:2022-04-27 08:54:07 回复TA
      }我们可以设置交换。setdelayed (true)在交换的声明中打开延迟队列,或者我们可以把下面的内容设置到switch声明的方法中,因为第一个方法的底层就是这样实
    1. 雷菊世秋
      雷菊世秋
      发布于:2022-04-27 01:31:19 回复TA
      谁说不是呢
    1. 喻艳萱娜
      喻艳萱娜
      发布于:2022-04-27 01:31:19 回复TA
      世纪唯一不变的真理,就是凡事都会改变。

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

    使用微信扫描二维码后

    点击右上角发送给好友