首页 > 代码库 > Java利用Redis实现消息队列
Java利用Redis实现消息队列
应用场景
- 为什么要用redis?
二进制存储、java序列化传输、IO连接数高、连接频繁
一、序列化
这里编写了一个java序列化的工具,主要是将对象转化为byte数组,和根据byte数组反序列化成java对象; 主要是用到了ByteArrayOutputStream和ByteArrayInputStream; 注意:每个需要序列化的对象都要实现Serializable接口;
其代码如下:
1 package Utils; 2 import java.io.*; 3 /** 4 * Created by Kinglf on 2016/10/17. 5 */ 6 public class ObjectUtil { 7 /** 8 * 对象转byte[] 9 * @param obj 10 * @return 11 * @throws IOException 12 */ 13 public static byte[] object2Bytes(Object obj) throws IOException{ 14 ByteArrayOutputStream bo=new ByteArrayOutputStream(); 15 ObjectOutputStream oo=new ObjectOutputStream(bo); 16 oo.writeObject(obj); 17 byte[] bytes=bo.toByteArray(); 18 bo.close(); 19 oo.close(); 20 return bytes; 21 } 22 /** 23 * byte[]转对象 24 * @param bytes 25 * @return 26 * @throws Exception 27 */ 28 public static Object bytes2Object(byte[] bytes) throws Exception{ 29 ByteArrayInputStream in=new ByteArrayInputStream(bytes); 30 ObjectInputStream sIn=new ObjectInputStream(in); 31 return sIn.readObject(); 32 } 33 }
二、消息类(实现Serializable接口)
package Model; import java.io.Serializable; /** * Created by Kinglf on 2016/10/17. */ public class Message implements Serializable { private static final long serialVersionUID = -389326121047047723L; 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; } }
三、Redis的操作
利用redis做队列,我们采用的是redis中list的push和pop操作;
结合队列的特点: 只允许在一端插入新元素只能在队列的尾部FIFO:先进先出原则
Redis中lpush头入
(rpop尾出
)或rpush尾入
(lpop头出
)可以满足要求,而Redis中list药push或 pop的对象仅需要转换成byte[]即可 java采用Jedis进行Redis的存储和Redis的连接池设置
上代码:
package Utils; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import java.util.List; import java.util.Map; import java.util.Set; /** * Created by Kinglf on 2016/10/17. */ public class JedisUtil { private static String JEDIS_IP; private static int JEDIS_PORT; private static String JEDIS_PASSWORD; private static JedisPool jedisPool; static { //Configuration自行写的配置文件解析类,继承自Properties Configuration conf=Configuration.getInstance(); JEDIS_IP=conf.getString("jedis.ip","127.0.0.1"); JEDIS_PORT=conf.getInt("jedis.port",6379); JEDIS_PASSWORD=conf.getString("jedis.password",null); JedisPoolConfig config=new JedisPoolConfig(); config.setMaxActive(5000); config.setMaxIdle(256); config.setMaxWait(5000L); 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); } /** * 获取数据 * @param key * @return */ public static String get(String key){ String value=http://www.mamicode.com/null;>
四、Configuration主要用于读取Redis的配置信息
package Utils; import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * Created by Kinglf on 2016/10/17. */ public class Configuration extends Properties { private static final long serialVersionUID = -2296275030489943706L; private static Configuration instance = null; public static synchronized Configuration getInstance() { if (instance == null) { instance = new Configuration(); } return instance; } public String getProperty(String key, String defaultValue) { String val = getProperty(key); return (val == null || val.isEmpty()) ? defaultValue : val; } public String getString(String name, String defaultValue) { return this.getProperty(name, defaultValue); } public int getInt(String name, int defaultValue) { String val = this.getProperty(name); return (val == null || val.isEmpty()) ? defaultValue : Integer.parseInt(val); } public long getLong(String name, long defaultValue) { String val = this.getProperty(name); return (val == null || val.isEmpty()) ? defaultValue : Integer.parseInt(val); } public float getFloat(String name, float defaultValue) { String val = this.getProperty(name); return (val == null || val.isEmpty()) ? defaultValue : Float.parseFloat(val); } public double getDouble(String name, double defaultValue) { String val = this.getProperty(name); return (val == null || val.isEmpty()) ? defaultValue : Double.parseDouble(val); } public byte getByte(String name, byte defaultValue) { String val = this.getProperty(name); return (val == null || val.isEmpty()) ? defaultValue : Byte.parseByte(val); } public Configuration() { InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream("config.xml"); try { this.loadFromXML(in); in.close(); } catch (IOException ioe) { } } }
五、测试
import Model.Message; import Utils.JedisUtil; import Utils.ObjectUtil; import redis.clients.jedis.Jedis; import java.io.IOException; /** * Created by Kinglf on 2016/10/17. */ public class TestRedisQueue { public static byte[] redisKey = "key".getBytes(); static { try { init(); } catch (IOException e) { e.printStackTrace(); } } private static void init() throws IOException { for (int i = 0; i < 1000000; i++) { Message message = new Message(i, "这是第" + i + "个内容"); JedisUtil.lpush(redisKey, ObjectUtil.object2Bytes(message)); } } public static void main(String[] args) { try { 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()); } } }
每执行一次pop()方法,结果如下:
<br>1----这是第1个内容
<br>2----这是第2个内容
<br>3----这是第3个内容
<br>4----这是第4个内容
总结
至此,整个Redis消息队列的生产者和消费者代码已经完成
- Message
需要传送的实体类(需实现Serializable接口)
- Configuration
Redis的配置读取类,继承自Properties
- ObjectUtil
将对象和byte数组双向转换的工具类
- Jedis
通过消息队列的先进先出(FIFO)的特点结合Redis的list中的push和pop操作进行封装的工具类
Java利用Redis实现消息队列
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。