这里我使用Redis的发布、订阅功能实现简单的消息队列,基本的命令有publish、subscribe等。

在Jedis中,有对应的java方法,但是只能发布字符串消息。为了传输对象,需要将对象进行序列化,并封装成字符串进行处理。

使用Redis实现消息队列


封装一个消息对象

public class Message implements Serializable{

private static final long serialVersionUID = 1L;

private String titile;
private String info; public Message(String titile,String info){
this.titile=titile;
this.info=info;
} public String getTitile() {
return titile;
}
public void setTitile(String titile) {
this.titile = titile;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}

  

为这个消息对象提供序列化方法

public class MessageUtil {

//convert To String
public static String convertToString(Object obj,String charset) throws IOException{ ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(obj);
String str = bo.toString(charset);
bo.close();
oo.close();
return str;
} //convert To Message
public static Object convertToMessage(byte[] bytes) throws Exception{
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
ObjectInputStream sIn = new ObjectInputStream(in);
return sIn.readObject(); }
}

  

从Jedis连接池中获取连接

public class RedisUtil {

/**
* Jedis connection pool
* @Title: config
*/
public static JedisPool getJedisPool(){
ResourceBundle bundle=ResourceBundle.getBundle("redis");
String host=bundle.getString("host");
int port=Integer.valueOf(bundle.getString("port"));
int timeout=Integer.valueOf(bundle.getString("timeout"));
// String password=bundle.getString("password"); JedisPoolConfig config=new JedisPoolConfig();
config.setMaxActive(Integer.valueOf(bundle.getString("maxActive")));
config.setMaxWait(Integer.valueOf(bundle.getString("maxWait")));
config.setTestOnBorrow(Boolean.valueOf(bundle.getString("testOnBorrow")));
config.setTestOnReturn(Boolean.valueOf(bundle.getString("testOnReturn"))); JedisPool pool=new JedisPool(config, host, port, timeout); return pool;
}
}

  

创建Provider类

public class Producer {

private Jedis jedis;
private JedisPool pool; public Producer(){
pool=RedisUtil.getJedisPool();
jedis = pool.getResource();
} public void provide(String channel,Message message) throws IOException{
String str1=MessageUtil.convertToString(channel,"UTF-8");
String str2=MessageUtil.convertToString(message,"UTF-8");
jedis.publish(str1, str2);
} //close the connection
public void close() throws IOException {
//将Jedis对象归还给连接池,关闭连接
pool.returnResource(jedis);
}
}

  

创建Consumer类

public class Consumer {

private Jedis jedis;
private JedisPool pool; public Consumer(){
pool=RedisUtil.getJedisPool();
jedis = pool.getResource();
} public void consum(String channel) throws IOException{
JedisPubSub jedisPubSub = new JedisPubSub() {
// 取得订阅的消息后的处理
public void onMessage(String channel, String message) {
System.out.println("Channel:"+channel);
System.out.println("Message:"+message.toString());
} // 初始化订阅时候的处理
public void onSubscribe(String channel, int subscribedChannels) {
System.out.println("onSubscribe:"+channel);
} // 取消订阅时候的处理
public void onUnsubscribe(String channel, int subscribedChannels) {
System.out.println("onUnsubscribe:"+channel);
} // 初始化按表达式的方式订阅时候的处理
public void onPSubscribe(String pattern, int subscribedChannels) {
// System.out.println(pattern + "=" + subscribedChannels);
} // 取消按表达式的方式订阅时候的处理
public void onPUnsubscribe(String pattern, int subscribedChannels) {
// System.out.println(pattern + "=" + subscribedChannels);
} // 取得按表达式的方式订阅的消息后的处理
public void onPMessage(String pattern, String channel, String message) {
System.out.println(pattern + "=" + channel + "=" + message);
}
}; jedis.subscribe(jedisPubSub, channel);
} //close the connection
public void close() throws IOException {
//将Jedis对象归还给连接池
pool.returnResource(jedis);
}
}

  

测试方法

public static void main(String[] args){

Message msg=new Message("hello!", "this is the first message!");

Producer producer=new Producer();
Consumer consumer=new Consumer();
try {
producer.provide("chn1",msg);
consumer.consum("chn1");
} catch (IOException e) {
e.printStackTrace();
}
}

  

Redis笔记(七)Java实现Redis消息队列的更多相关文章

  1. 手把手教你用redis实现一个简单的mq消息队列(java)

    众所周知,消息队列是应用系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有 ActiveMQ,RabbitMQ,Zero ...

  2. Java分布式:消息队列(Message Queue)

    Java分布式:消息队列(Message Queue) 引入消息队列 消息,是服务间通信的一种数据单位,消息可以非常简单,例如只包含文本字符串:也可以更复杂,可能包含嵌入对象.队列,是一种常见的数据结 ...

  3. Java高并发--消息队列

    Java高并发--消息队列 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 举个例子:在购物商城下单后,希望购买者能收到短信或者邮件通知.有一种做法时在下单逻辑执行后调 ...

  4. 【MQ】java 从零开始实现消息队列 mq-02-如何实现生产者调用消费者?

    前景回顾 上一节我们学习了如何实现基于 netty 客服端和服务端的启动. [mq]从零开始实现 mq-01-生产者.消费者启动 [mq]java 从零开始实现消息队列 mq-02-如何实现生产者调用 ...

  5. Redis 竟然能用 List 实现消息队列

    分布式系统中必备的一个中间件就是消息队列,通过消息队列我们能对服务间进行异步解耦.流量消峰.实现最终一致性. 目前市面上已经有 RabbitMQ.RochetMQ.ActiveMQ.Kafka等,有人 ...

  6. redis k-v数据库、高速缓存、消息队列代理

    Redis 简介   Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的 ...

  7. Redis笔记(六)Redis的消息通知

    Redis的消息通知可以使用List类型的LPUSH和RPOP(左进右出),当然更方便的是直接使用Redis的Pub/Sub(发布/订阅)模式. >>使用List实现队列 使用列表类型的L ...

  8. 使用redis的发布订阅模式实现消息队列

    配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://w ...

  9. Redis中的Stream数据类型作为消息队列的尝试

    Redis的List数据类型作为消息队列,已经比较合适了,但存在一些不足,比如只能独立消费,订阅发布又无法支持数据的持久化,相对前两者,Redis Stream作为消息队列的使用更为有优势.   相信 ...

  10. Redis系列(五):消息队列

    消息队列已经成为现在互联网服务端的标配组件,现在比较常用的消息中间件有RabbitMQ.Kafka.RocketMQ.ActiveMQ.说出来你可能不信,Redis作为一个缓存中间件,居然也提供了消息 ...

随机推荐

  1. 日期的js插件DatePicker

    官网:http://my97.net/dp/index.asp 百度网盘:http://pan.baidu.com/s/1c20y7uC 只显示月份 <input name="cost ...

  2. hiho #1284 机会渺茫

    #1284 : 机会渺茫 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi最近在追求一名学数学的女生小Z.小Z其实是想拒绝他的,但是找不到好的说辞,于是提出了这样的要 ...

  3. OpenCV图像的缩放

    函数介绍:    1.cvResize 改变图像大小     void cvResize(const CvArr *src, CvArr *dst, int interpolation)    函数说 ...

  4. Android 中的 Intent 简介

    Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据. ------------------------------- ...

  5. [翻译]opengl扩展教程1

    [翻译]opengl扩展教程1 原文地址https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/extensions.php [翻译]ope ...

  6. [k]web页面-browser兼容问题-1

    1:空的a标签在IE7/8下不能点击(2015-05-22) html代码: <ul class='oUl'><li><a href="#"> ...

  7. 怎样将myeclipse里默认编码设置成utf-8

    需要设置三个位置: [1]需要在  Preferences->general->content types->下角是文件编码,可以自己定义 [2]windows->Prefer ...

  8. IPC---信号量

    一.什么是信号量 信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程) 所拥有. 信号量的值为正的时候,说明它空闲.所测试的线程可以锁定而使用它.若为0,说明 它被占用,测试的线 ...

  9. Solr集群常用的操作总结

    之前搭建过SolrCloud和Solr单机版本,另外还有很多对Solr配置文件以及核心的操作,以下主要总结Solr集群中的常用操作,即在配置文件中正确设置ZK_HOST参数并且Zookeeper正确启 ...

  10. Java for LeetCode 214 Shortest Palindrome

    Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...