您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

SpringBoot怎么集成Redisson实现延迟队列

2025/5/8 16:57:05发布20次查看
使用场景1、下单成功,30分钟未支付。支付超时,自动取消订单
2、订单签收,签收后7天未进行评价。订单超时未评价,系统默认好评
3、下单成功,商家5分钟未接单,订单取消
4、配送超时,推送短信提醒
……
对于延时比较长的场景、实时性不高的场景,我们可以采用任务调度的方式定时轮询处理。如:xxl-job
今天我们采用一种比较简单、轻量级的方式,使用 redis 的延迟队列来进行处理。当然有更好的解决方案,可根据公司的技术选型和业务体系选择最优方案。如:使用消息中间件kafka、rabbitmq 的延迟队列
先不讨论其实现原理,直接实战上代码先实现基于 redis 的延迟队列
1、引入 redisson 依赖<dependency> <groupid>org.redisson</groupid> <artifactid>redisson-spring-boot-starter</artifactid> <version>3.10.5</version></dependency>
2、nacos 配置 redis 连接spring: redis: host: 127.0.0.1 port: 6379 password: 123456 database: 12 timeout: 3000
3、创建 redissonconfig 配置/** * created by lpb on 2020/04/20. */@configurationpublic class redissonconfig { @value("${spring.redis.host}") private string host; @value("${spring.redis.port}") private int port; @value("${spring.redis.database}") private int database; @value("${spring.redis.password}") private string password; @bean public redissonclient redissonclient() { config config = new config(); config.usesingleserver() .setaddress("redis://" + host + ":" + port) .setdatabase(database) .setpassword(password); return redisson.create(config); }}
4、封装 redis 延迟队列工具类/** * redis延迟队列工具 * created by lpb on 2021/04/20. */@slf4j@componentpublic class redisdelayqueueutil { @autowired private redissonclient redissonclient; /** * 添加延迟队列 * @param value 队列值 * @param delay 延迟时间 * @param timeunit 时间单位 * @param queuecode 队列键 * @param <t> */ public <t> void adddelayqueue(t value, long delay, timeunit timeunit, string queuecode){ try { rblockingdeque<object> blockingdeque = redissonclient.getblockingdeque(queuecode); rdelayedqueue<object> delayedqueue = redissonclient.getdelayedqueue(blockingdeque); delayedqueue.offer(value, delay, timeunit); log.info("(添加延时队列成功) 队列键&#xff1a;{}&#xff0c;队列值&#xff1a;{}&#xff0c;延迟时间&#xff1a;{}", queuecode, value, timeunit.toseconds(delay) + "秒"); } catch (exception e) { log.error("(添加延时队列失败) {}", e.getmessage()); throw new runtimeexception("(添加延时队列失败)"); } } /** * 获取延迟队列 * @param queuecode * @param <t> * @return * @throws interruptedexception */ public <t> t getdelayqueue(string queuecode) throws interruptedexception { rblockingdeque<map> blockingdeque = redissonclient.getblockingdeque(queuecode); t value = (t) blockingdeque.take(); return value; }}
5、创建延迟队列业务枚举/** * 延迟队列业务枚举 * created by lpb on 2021/04/20. */@getter@noargsconstructor@allargsconstructorpublic enum redisdelayqueueenum { order_payment_timeout("order_payment_timeout","订单支付超时&#xff0c;自动取消订单", "orderpaymenttimeout"), order_timeout_not_evaluated("order_timeout_not_evaluated", "订单超时未评价&#xff0c;系统默认好评", "ordertimeoutnotevaluated"); /** * 延迟队列 redis key */ private string code; /** * 中文描述 */ private string name; /** * 延迟队列具体业务实现的 bean * 可通过 spring 的上下文获取 */ private string beanid;}
6、定义延迟队列执行器/** * 延迟队列执行器 * created by lpb on 2021/04/20. */public interface redisdelayqueuehandle<t> { void execute(t t);}
7、创建枚举中定义的bean&#xff0c;并实现延迟队列执行器orderpaymenttimeout&#xff1a;订单支付超时延迟队列处理类
/** * 订单支付超时处理类 * created by lpb on 2021/04/20. */@component@slf4jpublic class orderpaymenttimeout implements redisdelayqueuehandle<map> { @override public void execute(map map) { log.info("(收到订单支付超时延迟消息) {}", map); // todo 订单支付超时&#xff0c;自动取消订单处理业务... }}
delayqueueprocessorforunevaluatedorders: 处理未评价订单的延迟队列处理类,用于订单超时未评价的情况
/** * 订单超时未评价处理类 * created by lpb on 2021/04/20. */@component@slf4jpublic class ordertimeoutnotevaluated implements redisdelayqueuehandle<map> { @override public void execute(map map) { log.info("(收到订单超时未评价延迟消息) {}", map); // todo 订单超时未评价&#xff0c;系统默认好评处理业务... }}
8、创建延迟队列消费线程&#xff0c;项目启动完成后开启/** * 启动延迟队列 * created by lpb on 2021/04/20. */@slf4j@componentpublic class redisdelayqueuerunner implements commandlinerunner { @autowired private redisdelayqueueutil redisdelayqueueutil; @override public void run(string... args) { new thread(() -> { while (true){ try { redisdelayqueueenum[] queueenums = redisdelayqueueenum.values(); for (redisdelayqueueenum queueenum : queueenums) { object value = redisdelayqueueutil.getdelayqueue(queueenum.getcode()); if (value != null) { redisdelayqueuehandle redisdelayqueuehandle = springutil.getbean(queueenum.getbeanid()); redisdelayqueuehandle.execute(value); } } } catch (interruptedexception e) { log.error("(redis延迟队列异常中断) {}", e.getmessage()); } } }).start(); log.info("(redis延迟队列启动成功)"); }}
以上步骤&#xff0c;redis 延迟队列核心代码已经完成&#xff0c;下面我们写一个测试接口&#xff0c;用 postman 模拟测试一下
9、创建一个测试接口&#xff0c;模拟添加延迟队列/** * 延迟队列测试 * created by lpb on 2020/04/20. */@restcontrollerpublic class redisdelayqueuecontroller { @autowired private redisdelayqueueutil redisdelayqueueutil; @postmapping("/addqueue") public void addqueue() { map<string, string> map1 = new hashmap<>(); map1.put("orderid", "100"); map1.put("remark", "订单支付超时&#xff0c;自动取消订单"); map<string, string> map2 = new hashmap<>(); map2.put("orderid", "200"); map2.put("remark", "订单超时未评价&#xff0c;系统默认好评"); // 添加订单支付超时&#xff0c;自动取消订单延迟队列。为了测试效果&#xff0c;延迟10秒钟 redisdelayqueueutil.adddelayqueue(map1, 10, timeunit.seconds, redisdelayqueueenum.order_payment_timeout.getcode()); // 订单超时未评价&#xff0c;系统默认好评。为了测试效果&#xff0c;延迟20秒钟 redisdelayqueueutil.adddelayqueue(map2, 20, timeunit.seconds, redisdelayqueueenum.order_timeout_not_evaluated.getcode()); }}
10、启动 springboot 项目,用 postman 调用接口添加延迟队列通过 redis 客户端可看到两个延迟队列已添加成功
查看 idea 控制台日志可看到延迟队列已消费成功
以上就是springboot怎么集成redisson实现延迟队列的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product