领导:谁再用redis过期监听实现关闭订单,立马滚蛋!

在电商、支付等领域,往往会有这样的场景,用户下单后放弃支付了,那这笔订单会在指定的时间段后进行关闭操作,细心的你一定发现了像某宝、某东都有这样的逻辑,而且时间很准确,误差在1s内;那他们是怎么实现的呢?

一般实现的方法有几种:

有一些方案虽然广为流传但存在着致命缺陷,不要用来实现延时任务

redis 过期监听

Basically expired events are generated when the Redis server deletes the key and not when the time to live theoretically reaches the value of zero

redis 自动过期的实现方式是:定时任务离线扫描并删除 部分过期键;在访问键时惰性检查是否过期并删除过期键。redis 从未保证会在设定的过期时间立即删除并发送过期通知。实际上,过期通知晚于设定的过期时间数分钟的情况也比较常见。

此外键空间通知采用的是发送即忘(fire and forget)策略,并不像消息队列一样保证送达。当订阅事件的客户端会丢失所有在断线期间所有分发给它的事件。

这是一种比定时扫描数据库更 “LOW” 的解决方案,请不要使用。

rabbitmq 死信

死信(Dead Letter) 是 rabbitmq 提供的一种机制。当一条消息满足下列条件之一那么它会成为死信:

  • 消息被否定确认(如channel.basicNack) 并且此时requeue 属性被设置为false。
  • 消息在队列的存活时间超过设置的TTL时间
  • 消息队列的消息数量已经超过最大队列长度

若配置了死信队列,死信会被 rabbitmq 投到死信队列中。

在 rabbitmq 中创建死信队列的操作流程大概是:

  • 创建一个交换机作为死信交换机
  • 在业务队列中配置 x-dead-letter-exchange 和 x-dead-letter-routing-key,将第一步的交换机设为业务队列的死信交换机
  • 在死信交换机上创建队列,并监听此队列

死信队列的设计目的是为了存储没有被正常消费的消息,便于排查和重新投递。 死信队列同样也没有对投递时间做出保证,在第一条消息成为死信之前,后面的消息即使过期也不会投递为死信

这里说点题外话,使用 redis 过期监听或者 rabbitmq 死信队列做延时任务都是以设计者预想之外的方式使用中间件,这种出其不意必自毙的行为通常会存在某些隐患,比如缺乏一致性和可靠性保证,吞吐量较低、资源泄漏等。比较出名的一个事例是很多人使用 redis 的 list 作为消息队列,以致于最后作者看不下去写了 disque 并最后演变为 redis stream。工作中还是尽量不要滥用中间件,用专业的组件做专业的事

时间轮

时间轮是一种很优秀的定时任务的数据结构,然而绝大多数时间轮实现是纯内存没有持久化的。运行时间轮的进程崩溃之后其中所有的任务都会灰飞烟灭,所以奉劝各位勇士谨慎使用。

redisson delayqueue

redisson delayqueue 是一种基于 redis zset 结构的延时队列实现。delayqueue 中有一个名为 timeoutSetName 的有序集合,其中元素的 score 为投递时间戳。delayqueue 会定时使用 zrangebyscore 扫描已到投递时间的消息,然后把它们移动到就绪消息列表中。

delayqueue 保证 redis 不崩溃的情况下不会丢失消息,在没有更好的解决方案时不妨一试。

在数据库索引设计良好的情况下,定时扫描数据库中未完成的订单产生的开销并没有想象中那么大。在使用 redisson delayqueue 等定时任务中间件时可以同时使用扫描数据库的方法作为补偿机制,避免中间件故障造成任务丢失。

Original: https://www.cnblogs.com/Finley/p/16395466.html
Author: -Finley-
Title: 领导:谁再用redis过期监听实现关闭订单,立马滚蛋!

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/529378/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 大数据之Hadoop中HDFS的故障排除

    NameNode故障处理 1)需求 NameNode进程挂了并且存储的数据也丢失了 2)故障模拟 (1) kill -9 NameNode进程 kill -9 19886 (2)删…

    Linux 2023年6月8日
    0113
  • 快速上手FastJSON

    作为一名后端开发而言肯定会接触数据,把数据提供给前端或者把数据存储起来,目前比较火热的传输格式是json,给前端传json是再常见不过啦,甚至是往db里面直接存入json。 在ja…

    Linux 2023年6月14日
    083
  • Ubuntu18.04 + Windows10 双系统安装

    此处忽略Windows10安装!!! 准备 安装环境 OS:Windows10 CPU:Intel(R) Core(TM) i5-10600KF CPU @ 4.10GHz 4.1…

    Linux 2023年5月27日
    0107
  • linux 网络配置

    安装linux之后一般都是网络自启动, 适合在没有网络工具的情况下修改配置文件 ubuntu: 网络配置文件/etc/network/interfaces 配置类似于: auto …

    Linux 2023年6月14日
    081
  • Python中使用%s占位符生成sql与literal转义防止sql注入攻击原理浅析

    问题背景 在后端服务中经常需要通过传入参数动态生成sql查询mysql,如查询用户信息、资产信息等,一条常见的sql如下: SELECT vip, coin FROM user_a…

    Linux 2023年6月6日
    0137
  • Ubuntu 18.04 安装教程

    准备材料 Ubuntu安装U盘 足够的硬盘空间 未初始化的硬盘需要提前初始化 注意事项 Ubuntu安装盘的制作请参考我的另外一个博客,里面写清楚了怎么制作Ubuntu安装盘,步骤…

    Linux 2023年6月14日
    080
  • 使用MyBatis Generator代码生成器的简单模式

    在动态web项目的lib目录下放入mybatis-3.2.2jar、mysql-connector-java-5.1.25-bin.jar、log4j-1.2.17.jar还有生成…

    Linux 2023年6月8日
    0117
  • 致远 OA 组合 getshell

    测试版本为: 致远 A8-V5 协同管理软件 V6.1SP2 1.获取cookie信息 2….

    Linux 2023年5月28日
    0316
  • CVE-2020-3580漏洞复现

    一、前言 前段时间碰到了该漏洞,记录一下! 二、漏洞介绍 该漏洞为思科ASA设备和FTD设备的未授权反射型XSS漏洞,影响版本如下: Cisco ASA Software 9.6 …

    Linux 2023年6月8日
    0108
  • 命令大全目录

    linux 本文来自博客园,作者:ivanlee717,转载请注明原文链接:https://www.cnblogs.com/ivanlee717/p/16341641.html O…

    Linux 2023年6月7日
    0142
  • CentOS7为php7.2安装php-redis扩展

    先下载phpredis-develop 安装unzip、zip解压工具 解压后会多了个phpredis-develop的目录。进入目录 安装phpize模块 执行phpize 查找…

    Linux 2023年5月28日
    083
  • 函数的设计和使用

    1.函数的定义 将可能需要反复执行的代码封装为函数,并在需要该功能的地方进行调用,不仅可以实现代码复用,更重要的是可以保证代码的一致性,只需要修改函数代码则所有调用均受影响。 设计…

    Linux 2023年6月7日
    0173
  • 内存错误和服务器内存RAS功能-DELL篇-1

    简介 内存子系统错误是现代计算系统中最常见的一些错误类型。了解内存错误是如何发生的以及如何预防或避免它们可能是一个复杂的话题–在过去30年里,这个话题挑战了无数的行业研…

    Linux 2023年6月7日
    0135
  • Golang 实现 Redis(4): AOF 持久化与AOF重写

    AOF 持久化是典型的异步任务,主协程(goroutine) 可以使用 channel 将数据发送到异步协程由异步协程执行持久化操作。 在 DB 中定义相关字段: type DB …

    Linux 2023年5月28日
    0105
  • B站学习斯坦福大学Swift 语言教程 iOS11 开发【第一集】踩到的几个坑(XCode 13.2.1版本)

    在Xcode 13.2.1 中,找不到从哪里拖拽添加button控件 Xcode13起,添加UI控件需要点击右上方的➕号 button的title属性设置成ghost的emoji后…

    Linux 2023年6月13日
    0108
  • centos7 安装MariaDB 10.6

    镜像下载、域名解析、时间同步请点击阿里云开源镜像站 背景 centos7使用yum install mariadb-server命令安装的默认版本是5.5的,这是因为系统默认源只有…

    Linux 2023年5月27日
    0373
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球