准备环境
- 虚拟机或者服务器上有Redis
- Maven
- eclipse或者idea
- JDK8
代码
Message
package com.leo.study.model;
public class Message {
private String id;
private Object data;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
return "Message [id=" + id + ", data=" + data + "]";
}
}
消息生产者
package com.leo.study.utils;
import java.util.Set;
import java.util.UUID;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.leo.study.model.Message;
import redis.clients.jedis.Jedis;
public class DelayMsgQueue {
private Jedis jedis;
private String queue;
public DelayMsgQueue(Jedis jedis, String queue) {
super();
this.jedis = jedis;
this.queue = queue;
}
/**
* 消息队列
*
* @param data
*/
public void queue(Object data) {
Message message = new Message();
message.setId(UUID.randomUUID().toString().replace("-", ""));
message.setData(data);
try {
String s = new ObjectMapper().writeValueAsString(message);
System.out.println("msg publish:" + System.currentTimeMillis());
// 消息发送,score 延迟 5 秒
//zadd: 将指定的元素添加到有序集合中。
jedis.zadd(queue, System.currentTimeMillis() + 5000, s);
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 消息消费
*/
public void loop() {
while (!Thread.interrupted()) {
// 读取 score 在 0 到当前时间戳之间的消息
Set<String> score = jedis.zrangeByScore(queue, 0, System.currentTimeMillis(), 0, 1);
if (score.isEmpty()) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
break;
}
continue;
}
// 如果读取到了消息,则直接读取消息出来
String next = score.iterator().next();
if (jedis.zrem(queue, next) > 0) {
try {
Message msg = new ObjectMapper().readValue(next, Message.class);
System.out.println("receive msg:" + msg);
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
测试
public void delayMsgTest() {
Redis redis = new Redis();
redis.execute(jedis -> {
DelayMsgQueue queue = new DelayMsgQueue(jedis, "delay-queue");
// 构造消息生产者
Thread producer = new Thread() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
queue.queue("www.javaboy.org>>>>" + i);
}
}
};
// 构造一个消息消费者
Thread consumer = new Thread() {
@Override
public void run() {
queue.loop();
}
};
// 启动
producer.start();
consumer.start();
// 休息 7 秒后,停止程序
try {
Thread.sleep(7000);
consumer.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}