Redis消息队列概述
Redis通过List
、Pub/Sub
或Stream
数据结构实现消息队列功能。以下分别介绍三种方式的实现逻辑及代码示例。
使用List实现消息队列
Redis的List
支持LPUSH
/RPOP
(生产者-消费者模式)或BRPOP
(阻塞模式)操作。
生产者代码
import redis.clients.jedis.Jedis;
public class ListProducer {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
for (int i = 0; i < 10; i++) {
String message = "Message-" + i;
jedis.lpush("queue", message);
System.out.println("Produced: " + message);
}
jedis.close();
}
}
消费者代码(阻塞模式)
import redis.clients.jedis.Jedis;
import java.util.List;
public class ListConsumer {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
while (true) {
List<String> messages = jedis.brpop(0, "queue"); // 0表示无限阻塞
System.out.println("Consumed: " + messages.get(1));
}
}
}
使用Pub/Sub实现消息队列
Redis的Pub/Sub
模式支持发布-订阅模型,但消息无持久化。
订阅者代码
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;
public class Subscriber {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
JedisPubSub listener = new JedisPubSub() {
@Override
public void onMessage(String channel, String message) {
System.out.println("Received: " + message);
}
};
jedis.subscribe(listener, "channel");
}
}
发布者代码
import redis.clients.jedis.Jedis;
public class Publisher {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
jedis.publish("channel", "Hello, Redis Pub/Sub!");
jedis.close();
}
}
使用Stream实现消息队列(推荐)
Redis 5.0+的Stream
支持持久化、消费者组等高级特性。
生产者代码
import redis.clients.jedis.Jedis;
import redis.clients.jedis.StreamEntryID;
public class StreamProducer {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
StreamEntryID id = jedis.xadd("mystream", null, Map.of("data", "Hello, Stream!"));
System.out.println("Produced with ID: " + id);
jedis.close();
}
}
消费者组代码
import redis.clients.jedis.Jedis;
import redis.clients.jedis.StreamEntry;
import redis.clients.jedis.StreamEntryID;
public class StreamConsumer {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
// 创建消费者组(仅需执行一次)
jedis.xgroupCreate("mystream", "mygroup", new StreamEntryID(), true);
while (true) {
Map<String, List<StreamEntry>> messages = jedis.xreadGroup(
"mygroup", "consumer1", 1, 0, false, Map.of("mystream", ">")
);
messages.forEach((stream, entries) -> {
entries.forEach(entry -> {
System.out.println("Consumed: " + entry.getFields());
// 手动ACK确认
jedis.xack("mystream", "mygroup", entry.getID());
});
});
}
}
}
注意事项
- List:简单但需手动实现ACK和重试机制。
- Pub/Sub:实时性好,但消息不持久化。
- Stream:支持消费者组、消息回溯,适合生产环境。
- 连接管理:示例未处理连接池,生产环境建议使用
JedisPool
。
以上代码需依赖Jedis库,Maven配置如下:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.3.1</version>
</dependency>