【并发】9、借助redis 实现生产消费,消息订阅发布模式队列
这个就是一个消息可以被多次消费的范例了
其实这个实现的方式可以参考我之前的设计模式,观察者模式
https://www.cnblogs.com/cutter-point/p/5249780.html
不过有一点需要注意一下啊,这个消息发布的时候,好像是不支持字节数据的,里面好像会对字节进行转换,这样的结果就是导致我最后无法吧相应的字节转换成我之前序列化的对象
不知道是不是ObjectInputStream和ObjectOutputStream实现不是很好的原因,还是什么,反正反序列化的时候,有些不可见的字符应该是被截掉了
消息发布者
package queue.redisQueue; import queue.fqueue.vo.TempVo;
import redis.clients.jedis.Jedis; import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.util.UUID; /**
* @ProjectName: cutter-point
* @Package: queue.redisQueue
* @ClassName: RedisQueueProducter3
* @Author: xiaof
* @Description: 订阅,发布模式 发布消息
* @Date: 2019/6/12 16:47
* @Version: 1.0
*/
public class RedisQueueProducter3 implements Runnable { private Jedis jedis;
private String queueKey; public RedisQueueProducter3(Jedis jedis, String queueKey) {
this.jedis = jedis;
this.queueKey = queueKey;
} public void putMessage() {
try {
Thread.sleep((long) (Math.random() * 1000)); //不存在则创建,存在则直接插入
//向redis队列中存放数据
//生成数据
TempVo tempVo = new TempVo();
tempVo.setName(Thread.currentThread().getName() + ",time is:" + UUID.randomUUID()); try {
int i = 0;
while(i < 10) {
//反馈订阅的数量
long num = jedis.publish(queueKey.getBytes(), tempVo.toString().getBytes());
if(num > 0) {
System.out.println("成功!num:" + num);
break;
}
++i;
}
} catch (Exception e) {
System.out.println("失败!");
} } catch (Exception e) {
e.printStackTrace();
}
} @Override
public void run() { while(true) {
putMessage(); } }
}
消息消费者
package queue.redisQueue; import queue.fqueue.vo.EventVo;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;
import redis.clients.util.SafeEncoder; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.UnsupportedEncodingException; /**
* @ProjectName: cutter-point
* @Package: queue.redisQueue
* @ClassName: RedisQueueConsume3
* @Author: xiaof
* @Description: 发布订阅消息,订阅线程
* @Date: 2019/6/12 16:53
* @Version: 1.0
*/
public class RedisQueueConsume3 implements Runnable { private Jedis jedis;
private String queueKey; class myJedisPubSub extends JedisPubSub {
/** JedisPubSub类是一个没有抽象方法的抽象类,里面方法都是一些空实现
* 所以可以选择需要的方法覆盖,这儿使用的是SUBSCRIBE指令,所以覆盖了onMessage
* 如果使用PSUBSCRIBE指令,则覆盖onPMessage方法
* 当然也可以选择BinaryJedisPubSub,同样是抽象类,但方法参数为byte[]
**/
@Override
public void onMessage(String channel, String message) {
System.out.println(Thread.currentThread().getName()+"-接收到消息:channel=" + channel + ",message=" + message);
//接收到exit消息后退出
System.out.println(message);
}
} public RedisQueueConsume3(Jedis jedis, String queueKey) {
this.jedis = jedis;
this.queueKey = queueKey;
} public void consumerMessage() {
jedis.subscribe(new myJedisPubSub(), queueKey);
} @Override
public void run() {
while (true) {
consumerMessage();
}
}
}
测试代码:
@Test
public void test4() throws InterruptedException { //读写取数据
for(int i = 0; i < 2; ++i) {
System.out.println("输出测试" + i);
RedisQueueProducter3 producter = new RedisQueueProducter3(jedisPool.getResource(), "xiaof");
Thread t = new Thread(producter);
t.start();
} while(true) {
Thread.sleep(1000);
}
} @Test
public void test5() throws InterruptedException { //读写取数据
for(int i = 0; i < 5; ++i) {
System.out.println("输出测试" + i);
//切记一定要重新获取Resource,不然无法并发操作
RedisQueueConsume3 fqueueConsume = new RedisQueueConsume3(jedisPool.getResource(), "xiaof");
Thread t = new Thread(fqueueConsume);
t.setDaemon(true);
t.start();
} while(true) {
Thread.sleep(1000);
}
}
效果展示
同一消息被多个订阅者同步消费

【并发】9、借助redis 实现生产消费,消息订阅发布模式队列的更多相关文章
- activemq 生产消费模式,订阅发布模式不同类型数据传输
1.项目结构 2. activemq-pom pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns ...
- 基于Redis的消息订阅/发布
在工业生产设计中,我们往往需要实现一个基于消息订阅的模式,用来对非定时的的消息进行监听订阅. 这种设计模式在 总线设计模式中得到体现.微软以前的WCF中实现了服务总线 ServiceBus的设计模式. ...
- Redis之Redis消息订阅发布简介
概念: Redis消息订阅发布是进程间的一种消息通信模式,发送者pub发送消息,订阅者sub接收消息. 使用须知: 需要先订阅后发布,才能接收到消息.在订阅时,相当于创建了可供发布的频道. 案例: ( ...
- python redis 实现简单的消息订阅
python + redis 实现简单的消息订阅 订阅端 import redis from functools import wraps class Subscribe: def __init__( ...
- RabbitMQ下的生产消费者模式与订阅发布模式
所谓模式,就是在某种场景下,一类问题及其解决方案的总结归纳.生产消费者模式与订阅发布模式是使用消息中间件时常用的两种模式,用于功能解耦和分布式系统间的消息通信,以下面两种场景为例: 数据接入 假设 ...
- Kafka下的生产消费者模式与订阅发布模式
原文:https://blog.csdn.net/zwgdft/article/details/54633105 在RabbitMQ下的生产消费者模式与订阅发布模式一文中,笔者以“数据接入”和“事 ...
- SpringBoot+Redis 实现消息订阅发布
什么是 Redis Redis 是一个开源的使用 ANSI C语言编写的内存数据库,它以 key-value 键值对的形式存储数据,高性能,读取速度快,也提供了持久化存储机制. Redis 通常在项目 ...
- Redis中的简单事物以及消息订阅发布
Redis支持简单的事物,但是没有mysql的Innodb支持的那么的完善 我们接下来看一下Redis和Mysql的事物的一个对比: MySQL Redis 开启 start transactio ...
- Linux+Redis实战教程_day02_消息订阅与发布_多数据库_redis批量操作-事务_redis持久化
5.扩展知识-消息订阅与发布(了解) 订阅新闻,新闻发布 subscribe channel:订阅频道,例:subscribe mychat,订阅mychat这个频道 psubscribe chann ...
随机推荐
- PostgreSQL远程连接,发生致命错误:没有用于主机“…”,用户“…”,数据库“…”,SSL关闭的pg_hba.conf记录
PostgreSQL远程连接方法 有时候在远程连接时,会报Error connecting to the server:致命错误:没有用于主机“…”,用户“…”,数据库“…”,SSL关闭的pg_hba ...
- Linux下通过nmap扫描局域网内设备,获取ip地址和mac地址
安装nmap sudo apt-get install nmap 扫描 sudo nmap -sP -PI -PT
- 解决url传递过程中加号变空格的问题<转>
url传递过程中加号变空格在接收url参数的过程中,会发现如果参数中存在‘+’号,接收后会变成空格. 如11+22接收后变成11 22.要解决这个问题,需要将加号替换为%2B进行传递. 如11%2B2 ...
- JVM 初始化阶段例子
创建如下Demo package com.example.jvm.classloader; class Parent{ static int a = 3; static { System.out.pr ...
- sql中order by和group by的区别
order by 和 group by 的区别: 1,order by 从英文里理解就是行的排序方式,默认的为升序. order by 后面必须列出排序的字段名,可以是多个字段名. 2,group b ...
- Nginx 配置操作注意事项
Nginx reload 会中断现有连接吗? - 知乎https://www.zhihu.com/question/57096250 在NGINX上配置HTTPS---血的教训--要重启NGINX - ...
- [转]arcgis for server 10.2 下载及安装
转自:https://blog.csdn.net/nominior/article/details/80211963 https://blog.csdn.net/mrib/article/detail ...
- Python3基础 函数 多值参数 元组与字典形式(键值对分别指出)
Python : 3.7.3 OS : Ubuntu 18.04.2 LTS IDE : pycharm-community-2019.1.3 ...
- java.io.EOFException at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer
如题,网上找了相关资料查明是websocket连接超时的问题.使用了反向代理,因此超过60S没有数据传输的连接会断开. 把代理的那个超时时间设置长一点,无限长.你开什么玩笑!那还代理个啥玩意. 解决方 ...
- opencv4 mask_rcnn模型调(c++)
昨天有人问我关于调用mask_rcnn模型的问题,忽然想到最近三个月都没用opencv调用训练好的mask_rcnn模型了,今晚做个尝试,所以重新编译了 opencv4,跑个案例试试 #include ...