Java利用Redis实现消息队列

使用jar包:jedis-2.9.0.jarcommons-pool2-2.3.jar

  1. Message 需要传送的实体类(需实现Serializable接口)
  2. ObjectUtil 将对象和byte数组双向转换的工具类
  3. Jedis 通过消息队列的先进先出(FIFO)的特点结合Redis的list中的push和pop操作进行封装的工具类

1、消息类

public class Message implements Serializable{
	private int id;
	private String content;

	public Message(int id,String content) {
		this.id = id;
		this.content = content;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
}

 

2、序列化

        主要是将对象转化为byte数组,和根据byte数组反序列化成java对象; 主要是用到了ByteArrayOutputStream和ByteArrayInputStream; 注意:每个需要序列化的对象都要实现Serializable接口; 

public class ObjectUtil {
	
	public static byte[] object2Bytes(Object obj) throws IOException{
		ByteArrayOutputStream bo = new ByteArrayOutputStream();
		ObjectOutputStream oo = new ObjectOutputStream(bo);
		oo.writeObject(obj);
		byte[] bytes = bo.toByteArray();
		bo.close();
		oo.close();
		return bytes;
	}
	
	public static Object bytes2Object(byte[] bytes) throws Exception {
		ByteArrayInputStream in = new ByteArrayInputStream(bytes);
		ObjectInputStream sIn = new ObjectInputStream(in);
		return sIn.readObject();
	}
}

3、利用redis做队列,采用redis中list的push和pop操作;

public class JedisUtil {
	private static String JEDIS_IP;
	private static int JEDIS_PORT;
	private static String JEDIS_PASSWORD;
	private static JedisPool jedisPool;
	static{
		Configuration conf = Configuration.getInstance();
		JEDIS_IP="127.0.0.1";
		JEDIS_PORT = 6379;
		JEDIS_PASSWORD = "123456";
		JedisPoolConfig config = new JedisPoolConfig();
	        config.setMaxIdle(256);
	        config.setTestOnBorrow(true);
	        config.setTestOnReturn(true);
	        config.setTestWhileIdle(true);
	        config.setMinEvictableIdleTimeMillis(60000L);
	        config.setTimeBetweenEvictionRunsMillis(3000L);
	        config.setNumTestsPerEvictionRun(-1);
	        jedisPool=new JedisPool(config,JEDIS_IP,JEDIS_PORT,60000,JEDIS_PASSWORD);	
	}
	
    /**
     * 存储REDIS队列 顺序存储
     * @param  key reids键名
     * @param  value 键值
     */
    public static void lpush(byte[] key, byte[] value) {

        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.lpush(key, value);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }

    /**
     * 存储REDIS队列 反向存储
     * @param  key reids键名
     * @param  value 键值
     */
    public static void rpush(byte[] key, byte[] value) {

        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.rpush(key, value);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }

    /**
     * 获取队列数据
     * @param  key 键名
     * @return
     */
    public static byte[] rpop(byte[] key) {

        byte[] bytes = null;
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            bytes = jedis.rpop(key);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
        return bytes;
    }
   
    private static void close(Jedis jedis) {
        try{
            jedisPool.returnResource(jedis);
        }catch (Exception e){
            if(jedis.isConnected()){
                jedis.quit();
                jedis.disconnect();
            }
        }
    }
}

4、测试

用lpush和rpop对redis的队列中的元素进行存入和取出,就能满足先进先出(FIFO)的特点。存入队列中的是Message对象序列化后的字节数组,取出时,再将其反序列化为原对象。

public class TestRedisQueue {

	public static byte[] redisKey = "key".getBytes();
    static {
        try {
            init();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    //初始存入1000个消息到队列
    private static void init() throws IOException {
        for (int i = 0; i < 1000; i++) {
            Message message = new Message(i, "这是第" + i + "个内容");
            JedisUtil.lpush(redisKey, ObjectUtil.object2Bytes(message));
        }
    }

    //每运行一次取出100个消息
    public static void main(String[] args) {
        try {
        	for(int i=0;i<100;i++){
        		pop();
        	}            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void pop() throws Exception {
        byte[] bytes = JedisUtil.rpop(redisKey);
        Message msg = (Message) ObjectUtil.bytes2Object(bytes);
        if (msg != null) {
            System.out.println(msg.getId() + "----" + msg.getContent());
        }
    }
}

 

你可能感兴趣的:(redis,数据库)