Redis实现消息队列机制

准备环境

  • 虚拟机或者服务器上有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();
			}

		});
	}

猜你喜欢

转载自blog.csdn.net/Curtisjia/article/details/108608886