您的位置:首页 > 新闻 > 热点要闻 > 河北建设工程信息网招标_什么是广告艺术设计_总裁培训班_百度竞价返点开户

河北建设工程信息网招标_什么是广告艺术设计_总裁培训班_百度竞价返点开户

2025/4/21 19:40:03 来源:https://blog.csdn.net/weixin_51329147/article/details/147150166  浏览:    关键词:河北建设工程信息网招标_什么是广告艺术设计_总裁培训班_百度竞价返点开户
河北建设工程信息网招标_什么是广告艺术设计_总裁培训班_百度竞价返点开户

在电商、订票或预约类系统中,订单的提交与取消是核心业务流程之一。为了保障系统的稳定性与用户体验,我们需要有效地处理两个常见问题:

  • 订单重复提交(用户连续点击、页面卡顿、网络重试等引起)
  • 订单超时未支付自动取消

本篇博客将介绍这两个问题产生的原因,以及在实际开发中常见的解决方案。

代码地址:https://github.com/RainbowJier/ArchitectureDesign#


架构设计

应用架构图

应用架构图,描述后端系统由哪些应用组成,对系统架构中的某个模块进行细分说明 [1],比如流量包下单模块的应用架构图,如下所示:

系统时序图

时序图说明 [2]:

  1. 获取 token:用户进入订单页面,生成 token 存储到 Redis。
  2. 用户下单
    1. 配置 Redis 加锁,实现防止用户重复提交。
    2. 订单价格验证
      1. 考虑优惠券或其它折扣因素
      2. 校验前端展示的价格与后端计算出的价格是否一致
    3. 创建订单信息,保存到数据库。
    4. 发送订单信息到延迟队列,在规定时间内未支付,自动关闭订单。
    5. 响应用户,下单成功。
  3. 集成第三方支付接口,响应第三方支付信息(关键点)
  4. 等待用户支付,回调处理,
    1. 支付成功
      1. 同步更新订单支付状态。
      2. 激活对应的流量套餐。
    2. 支付失败
      1. 超过规定支付时间,延迟队列自动关闭订单。

订单重复提交防范机制

问题场景

用户在下单时可能回出现如下情况:

  1. 在前端下单过程中,由于用户多次点击提交按钮,导致系统重复接收并处理下单请求,进而生成了多个订单。
  2. 由于网络延迟或其他技术性因素造成的页面响应迟缓,促使用户反复尝试刷新页面或重新提交表单,从而无意中触发了多次请求的发送。
  3. 黑客或具有恶意意图的用户利用 Postman 等 HTTP 客户端工具,故意对系统进行重复性的表单提交攻击,以此达到破坏正常服务流程的目的。

问题:

  1. 导致表单重复提交,造成数据重复或者混乱。
  2. 核心接口的请求次数增加,消耗服务器负载,严重造成服务器宕机、

解决方案

幂等性设计

实现幂等性的核心是:无论请求被提交多少次,结果都是一样的

❌方案一:前端控制

前端 JS 控制点击次数,屏蔽点击按钮无法点击

存在问题:

  1. 前端的 JS 可以被绕过。
✅方案二:服务端 token 令牌
架构设计

使用 SpringBoot 的 AOP 切面编程,每次调用订单接口时,会先校验是否“重复提交”。

流程图

  1. 用户每次进入订单页面

    1. 系统生成一个 order_token,存储在 Redis, 如 SETNX(设置唯一标识)配合过期时间。
  2. 用户提交订单时

    1. AOP 拦截请求,校验这个 order_token 是否存在。
    2. 提交订单时必须携带这个order_token 校验是否 Redis 中是否存在键值对。
  3. 后端验证 token 是否存在

    1. 存在,说明首次下订单,保存订单,删除 Redis 中的 order_token
    2. 不存在,说明重复提交,无法保存订单。
  4. 用户进入下单页面

    1. 调用 getToken() 方法生成 request-token 令牌{key: order:submit:[account_no]:[32 位随机数],value : 1}
    2. 存储到 Redis。
  5. 用户提交订单时

    1. 进入 AOP 拦截器,校验 request-token 是否存在。
    2. 存在,不拦截请求,保存订单信息到数据库,删除 Redis 中的令牌。
    3. 不存在,删除失败,说明重复提交,直接拦截请求。

订单超时未支付自动取消

问题场景

  1. 支付超时判断:用户在下单之后,系统需要设置一个支付超时时间(如 20 分钟、1 小时等)。
  2. 订单状态变更:当支付超时后,系统需要将订单状态设置为”支付超时“或者”失效“, 并触发响应的业务逻辑。
  3. 通知用户:在订单超时前,可以通过短信、邮箱等通知用户。

解决方案

架构设计

  1. 为何订单的延迟消息时间会超过支付的有效时间
    1. 情形说明:若延迟消息设定的有效时间为 10 分钟,而支付的有效期为 20 分钟。
    2. 具体流程分析
      1. 在延迟消息到期后的第 10 分钟,如果用户尚未完成支付,则“关单服务”自动介入,并将该订单的状态更新为“未支付”。
      2. 假设在 15 分钟时,用户尝试进行支付。此时,由于订单已被标记为“未支付”,即便用户成功支付,也无法即时反映至订单的实际状态中,从而导致了数据的一致性问题。
  2. **在“关单服务”流程中,为何需要在”关闭订单“时查询”第三档支付平台“**
    a. 用户在完成第【6】步支付操作后,可能会由于网络问题导致虽然实际已付款,但系统数据库中的订单状态仍显示为未支付。这种情况会导致订单状态出现错误。
    b. 因此,在第【9】步时,通过再次向第三方支付平台查询该笔交易的实际状态,可以准确确认订单的真实情况,从而保证数据的一致性和准确性。
RabbitMQ 实现延迟队列

RabbitMQ TTL+死信队列示意:

  1. 设置订单队列消息的 TTL 为 30 分钟
  2. 到期未消费进入死信队列
  3. 消费死信队列,执行取消逻辑
@Bean
public Queue orderDelayQueue() {Map<String, Object> args = new HashMap<>(3);args.put("x-message-ttl", ttl);   // 设置消息过期时间args.put("x-dead-letter-exchange", orderCloseEventExchange);args.put("x-dead-letter-routing-key", orderReleaseBindingKey);return new Queue(orderDelayQueue, true, false, false, args);
}

实践建议

  1. 接口层防抖 + 服务层幂等 + 数据库唯一约束 三层保障,才能真正防止重复订单
  2. 对于高并发系统,延迟队列+死信机制 是更可控、更实时的取消策略
  3. 实时取消的同时,注意回滚库存、释放优惠券、通知用户等后续处理

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com