8

订单自动确认或取消设计方案 - 涛姐涛哥

 1 year ago
source link: https://www.cnblogs.com/taojietaoge/p/16994945.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

订单自动确认或取消设计方案

    前不见古人,后不见来者。念天地之悠悠,独怆然而涕下。

简介

系统订单自动确认或取消的设计方案,最常见的一个业务比如N天后自动确认订单,达到动态修改订单状态的目的。大多数项目采用的都是如下两种方案。

  • 方案1:使用传统的数据库如MySQL,通过轮询来判断数据库表中订单的状态。该方案性能较低,且增加了IO次数。
  • 方案2:使用 Redis 给订单设置N天过期时间,通过判断 Redis 中是否还有该订单来决定订单是否已经完成。该方案比方案1好点,但相较于消息的延迟推送性能较低,且需要把 Redis 中数据都从内存中持久化到硬盘。

上面方两种传统解决方案会降低了系统的整体性能和吞吐量,往往不够支持庞大的系统如京东、天猫、亚马逊或者12306等系统。这时可以考虑采用MQ,平时MQ用的较多的就是业务解耦、前端削峰(秒杀系统)、高可用性和顺序消息。除此之外,RabbitMQ还支持定时消息和延迟消息,Broker中有定时消息的机制,消息发送到Broker中,不会立即被Consumer消费,会等到一定的时间才被消费。延迟消息也是一样,延迟一定时间之后才会被Consumer消费。

体系较为庞大的项目一般会采用RabbitMQ的消息延迟消推送来实现。

  • 如京东N天后自动确认收货。在商品被签收后,物流系统会在N天后延时发送一个消息给支付系统,通知支付系统将款打给商家,这个过程持续七天,就是使用了消息中间件的延迟推送功能。
  • 如 12306 购票支付确认页面。选票后点击确定会跳转倒支付页面,该页面会带有倒计时,代表着 30 分钟内订单不确认的话将会自动取消订单。在下订单那一刻,购票业务系统就会发送一个延时消息给订单系统,setDelay延时30分钟,通知订单系统订单未完成,如果用户在30分钟内完成了订单的支付操作,则可以通过逻辑代码判断来忽略掉收到的消息。

消息延迟推送的实现

首先按照常规的手段创建交换机和消息队列,配置生产者和消费者等基础信息。不同的是,在 Exchange 的声明中设置 exchange.setDelayed(true)来开启延迟队列。

 exchange.setDelayed(true)

或设置交换机支持延迟队列推送。

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

然后,发送消息时指定延迟推送的时间就可以实现消息延迟推送了。

1   public Message postProcessMessage(Message message) throws AmqpException {
2                 //设置消息持久化
3                 message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
4                 //message.getMessageProperties().setHeader("x-delay", "6000");
5                 message.getMessageProperties().setDelay(6000);  // 指定延迟推送的时间
6       return message; 7 }
前不见古人
    后不见来者
          念天地之悠悠
               独怆然而涕下

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK