应用场景

  • 为什么要用redis?
    二进制存储、java序列化传输、IO连接数高、连接频繁

一、序列化

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

其代码如下:

package Utils;
import java.io.*;
/**
* @author ChinWay.Y
* @time 2017-02-15
*/
public class ObjectUtil {
/**
* 对象转byte[]
* @param obj
* @return
* @throws IOException
*/
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;
}
/**
* byte[]转对象
* @param bytes
* @return
* @throws Exception
*/
public static Object bytes2Object(byte[] bytes) throws Exception{
ByteArrayInputStream in=new ByteArrayInputStream(bytes);
ObjectInputStream sIn=new ObjectInputStream(in);
return sIn.readObject();
}
}

二、消息类(实现Serializable接口)

package Model;

import java.io.Serializable;
/**
* @author ChinWay.Y
* @time 2017-02-15
*/
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:先进先出原则头入(rpopjava采用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;
/**
* @author ChinWay.Y
* @time 2017-02-15
*/
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=null;
Jedis jedis=null;
try{
jedis=jedisPool.getResource();
value=jedis.get(key);
}catch (Exception e){
jedisPool.returnBrokenResource(jedis);
e.printStackTrace();
}finally {
close(jedis);
}
return value;
} private static void close(Jedis jedis) {
try{
jedisPool.returnResource(jedis);
}catch (Exception e){
if(jedis.isConnected()){
jedis.quit();
jedis.disconnect();
}
}
}
public static byte[] get(byte[] key){
byte[] value = null;
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
value = jedis.get(key);
} catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace();
} finally {
//返还到连接池
close(jedis);
} return value;
} public static void set(byte[] key, byte[] value) { Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.set(key, value);
} catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace();
} finally {
//返还到连接池
close(jedis);
}
} public static void set(byte[] key, byte[] value, int time) { Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.set(key, value);
jedis.expire(key, time);
} catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace();
} finally {
//返还到连接池
close(jedis);
}
} public static void hset(byte[] key, byte[] field, byte[] value) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.hset(key, field, value);
} catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace();
} finally {
//返还到连接池
close(jedis);
}
} public static void hset(String key, String field, String value) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.hset(key, field, value);
} catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace();
} finally {
//返还到连接池
close(jedis);
}
} /**
* 获取数据
*
* @param key
* @return
*/
public static String hget(String key, String field) { String value = null;
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
value = jedis.hget(key, field);
} catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace();
} finally {
//返还到连接池
close(jedis);
} return value;
}
/**
* 获取数据
*
* @param key
* @return
*/
public static byte[] hget(byte[] key, byte[] field) { byte[] value = null;
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
value = jedis.hget(key, field);
} catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace();
} finally {
//返还到连接池
close(jedis);
} return value;
}
public static void hdel(byte[] key, byte[] field) { Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.hdel(key, field);
} catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace();
} finally {
//返还到连接池
close(jedis);
}
}
/**
* 存储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); }
} /**
* 将列表 source 中的最后一个元素(尾元素)弹出,并返回给客户端
* @param key reids键名
* @param destination 键值
*/
public static void rpoplpush(byte[] key, byte[] destination) { Jedis jedis = null;
try { jedis = jedisPool.getResource();
jedis.rpoplpush(key, destination); } catch (Exception e) { //释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace(); } finally { //返还到连接池
close(jedis); }
} /**
* 获取队列数据
* @param key 键名
* @return
*/
public static List lpopList(byte[] key) { List list = null;
Jedis jedis = null;
try { jedis = jedisPool.getResource();
list = jedis.lrange(key, 0, -1); } catch (Exception e) { //释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace(); } finally { //返还到连接池
close(jedis); }
return list;
}
/**
* 获取队列数据
* @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;
}
public static void hmset(Object key, Map hash) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.hmset(key.toString(), hash);
} catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace(); } finally {
//返还到连接池
close(jedis); }
}
public static void hmset(Object key, Map hash, int time) {
Jedis jedis = null;
try { jedis = jedisPool.getResource();
jedis.hmset(key.toString(), hash);
jedis.expire(key.toString(), time);
} catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace(); } finally {
//返还到连接池
close(jedis); }
}
public static List hmget(Object key, String... fields) {
List result = null;
Jedis jedis = null;
try { jedis = jedisPool.getResource();
result = jedis.hmget(key.toString(), fields); } catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace(); } finally {
//返还到连接池
close(jedis); }
return result;
} public static Set hkeys(String key) {
Set result = null;
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
result = jedis.hkeys(key); } catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace(); } finally {
//返还到连接池
close(jedis); }
return result;
}
public static List lrange(byte[] key, int from, int to) {
List result = null;
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
result = jedis.lrange(key, from, to); } catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace(); } finally {
//返还到连接池
close(jedis); }
return result;
}
public static Map hgetAll(byte[] key) {
Map result = null;
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
result = jedis.hgetAll(key);
} catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace(); } finally {
//返还到连接池
close(jedis);
}
return result;
} public static void del(byte[] key) { Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.del(key);
} catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace();
} finally {
//返还到连接池
close(jedis);
}
} public static long llen(byte[] key) { long len = 0;
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.llen(key);
} catch (Exception e) {
//释放redis对象
jedisPool.returnBrokenResource(jedis);
e.printStackTrace();
} finally {
//返还到连接池
close(jedis);
}
return len;
}
}

四、Configuration主要用于读取Redis的配置信息

package Utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
* @author ChinWay.Y
* @time 2017-02-15
*/
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;
/**
* @author ChinWay.Y
* @time 2017-02-15
*/
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消息队列的生产者和消费者代码已经完成
  1. Message 需要传送的实体类(需实现Serializable接口)
  2. Configuration Redis的配置读取类,继承自Properties
  3. ObjectUtil 将对象和byte数组双向转换的工具类
  4. Jedis 通过消息队列的先进先出(FIFO)的特点结合Redis的list中的push和pop操作进行封装的工具类

预热一下吧《实现Redis消息队列》的更多相关文章

  1. redis消息队列简单应用

    消息队列出现的原因 随着互联网的高速发展,门户网站.视频直播.电商领域等web应用中,高并发.大数据已经成为基本的标识.淘宝双11.京东618.各种抢购.秒杀活动.以及12306的春运抢票等,他们这些 ...

  2. logstash解耦之redis消息队列

    logstash解耦之redis消息队列 架构图如下: 说明:通过input收集日志消息放入消息队列服务中(redis,MSMQ.Resque.ActiveMQ,RabbitMQ),再通过output ...

  3. Redis 消息队列的实现

    概述 Redis实现消息队列有两种形式: 广播订阅模式:基于Redis的 Pub/Sub 机制,一旦有客户端往某个key里面 publish一个消息,所有subscribe的客户端都会触发事件 集群订 ...

  4. java-spring基于redis单机版(redisTemplate)实现的分布式锁+redis消息队列,可用于秒杀,定时器,高并发,抢购

    此教程不涉及整合spring整合redis,可另行查阅资料教程. 代码: RedisLock package com.cashloan.analytics.utils; import org.slf4 ...

  5. (转)java redis使用之利用jedis实现redis消息队列

    应用场景 最近在公司做项目,需要对聊天内容进行存储,考虑到数据库查询的IO连接数高.连接频繁的因素,决定利用缓存做. 从网上了解到redis可以对所有的内容进行二进制的存储,而java是可以对所有对象 ...

  6. spring mvc redis消息队列

    通常情况下,为了提高系统开发的灵活性和可维护度,我们会采用消息队列队系统进行解耦.下面是一个采用spring redis实现的消息队列实例,但此实例会由于网络延迟和阻塞等情况导致消息处理的延时,因而不 ...

  7. Redis笔记(七)Java实现Redis消息队列

    这里我使用Redis的发布.订阅功能实现简单的消息队列,基本的命令有publish.subscribe等. 在Jedis中,有对应的java方法,但是只能发布字符串消息.为了传输对象,需要将对象进行序 ...

  8. 使用jedis实现Redis消息队列(MQ)的发布(publish)和消息监听(subscribe)

    前言: 本文基于jedis 2.9.0.jar.commons-pool2-2.4.2.jar以及json-20160810.jar 其中jedis连接池需要依赖commons-pool2包,json ...

  9. Java实现Redis消息队列

    这里我使用Redis的发布.订阅功能实现简单的消息队列,基本的命令有publish.subscribe等. 在Jedis中,有对应的java方法,但是只能发布字符串消息.为了传输对象,需要将对象进行序 ...

随机推荐

  1. SpringCloud入门之YAML格式文件规范学习

    1. 认识 YAML YAML(发音 /ˈjæməl/)是一个类似 XML.JSON 的数据序列化语言.其强调以数据为中心,旨在方便人类使用:并且适用于日常常见任务的现代编程语言.因而 YAML 本身 ...

  2. java web路径和spring读取配置文件

    此篇博客缘起:部署java web系统到阿里云服务器(ubuntu14.04)的时候,有以下两个问题 找不到自定义的property配置文件 上传图片的时候找不到路径 开发的时候是在windows上的 ...

  3. 第10章 统计和查看Linux的系统状态

    写在前面的话:本文是假设你已经有了进程.内存.cpu的理论基础而写的,文中涉及的各种状态只给出了简单说明而没有解释它们的意义,如果不懂这些理论性的东西,本文可能让你看的直接想右上角叉叉.关于这些理论, ...

  4. python变量和变量赋值的几种形式

    动态类型的语言 python是动态类型的语言,不需要声明变量的类型. 实际上,python中的变量仅仅只是用来保存一个数据对象的地址.无论是什么数据对象,在内存中创建好数据对象之后,都只是把它的地址保 ...

  5. python装饰器2:类装饰器

    装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 本文是装饰器相关内容的第二篇,关于类装饰器. "类装饰器"有两种解读方式:用来装饰类的装饰器:类作为装饰器装饰其它东西.你 ...

  6. Spring Day 1

    概述 开发三层架构,web层 service服务层,dao持久层. web层struts2配置核心过滤器/*,通过拦截器调用目标action,action中调用service层开启事务. servic ...

  7. WPF TreeView SelectedItemChanged called twice

    How to avoid WPF TreeView SelectedItemChanged being called twice Very often, we need to execute some ...

  8. Fundebug能够捕获这些BUG

    摘要:Fundebug的JavaScript监控插件更新至0.1.0,可以监控3种不同类型的前端BUG:JavaScript执行错误.资源加载错误.HTTP请求错误. 从简单的onerror开始,Fu ...

  9. [Linux]lnmp一键安装包,访问yii/tp5/laravel的时候,报错500或者空白页面

    当你将默认的访问路径改后(nginx.conf中的root 之后的路径),同时应该将/home/wwwroot/default/.user.ini 中的路径也改了! .user.ini 是隐藏文件,需 ...

  10. SqL读取XML、解析XML、SqL将XML转换DataTable、SqL将XML转换表

    DECLARE @ItemMessage XML )) SET @ItemMessage=N' <ReceivablesInfos> <ReceivablesList> < ...