目录
前言:
这个主要是生活遇见的一个场景,就是订单未支付 ,时间过期自动取消, 记个小笔记了
当然实际业务肯定要很复杂点的,这个小demo需要去扩展才行,结合实际业务去完善,
实现思路:
比如一个用户下单了, 这个订单数据在入redis库的时候,我们设置了过期时间15分钟, 当线程在判断的时候 发现对比当前时间 超过15 分了 ,订单过期了, 就给监听频道发送取消订单消息,然后处理业务 返回对应用户消息提示
Java代码示例:
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;
public class RedisDelayQueue {
private Jedis jedis = null;
public RedisDelayQueue() {
jedis = new Jedis("localhost", 6379);
}
public void addOrder(String orderId, int delay) {
long timestamp = System.currentTimeMillis() + delay * 1000;
jedis.zadd("delay_queue", timestamp, orderId);
}
public void startListener() {
new Thread(() -> {
JedisPubSub jedisPubSub = new JedisPubSub() {
@Override
public void onMessage(String channel, String message) {
System.out.println("Cancel order: " + message);
}
};
jedis.subscribe(jedisPubSub, "cancel_order");
}).start();
new Thread(() -> {
while (true) {
long timestamp = System.currentTimeMillis();
String orderId = jedis.zrangeByScore("delay_queue", 0, timestamp, 0, 1).stream().findFirst().orElse(null);
if (orderId != null) {
jedis.zrem("delay_queue", orderId);
jedis.publish("cancel_order", orderId);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
- 示例中,我们使用了Jedis客户端库来连接Redis数据库。我们创建了一个RedisDelayQueue类,并定义了两个方法:addOrder和startListener。
- addOrder方法用于向延迟队列中添加一个订单。我们使用zadd命令将订单ID和过期时间戳(timestamp)添加到名为"delay_queue"的有序集合中。
- startListener方法用于启动一个监听器,用于监听订单取消消息。我们使用subscribe命令订阅名为"cancel_order"的频道,并在收到消息时输出取消订单的信息。我们还启动了一个线程,用于定时检查延迟队列中的订单是否已经过期。我们使用zrangeByScore命令获取过期时间戳小于当前时间戳的订单ID,并使用zrem命令从延迟队列中删除该订单。然后,我们使用publish命令向"cancel_order"频道发布取消订单的消息。
依赖:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.6.0</version>
</dependency>