RabbitMQ简单应用の订阅模式
订阅模式
公众号-->订阅之后才会收到相应的文章。
解读:
1.一个生产者,多个消费者
2.每个消费者都有自己的队列
3.生产者没有将消息直接发送到队列里,而是发送给了交换机(转发器)exchange
4.每个队列都要绑定到交换机(转发器)上
5.生产者发送的消息记过交换机然后到达队列,然后就能实现被多个消费者消费
图例:
|-------------|-----Q-----C3
P------------X-------------|-----Q-----C3
|-------------|-----Q-----C3
注册--->发邮件--->发短信
MQ工厂类Connection
- package com.mmr.rabbitmq.util;
- import java.io.IOException;
- import com.rabbitmq.client.Connection;
- import com.rabbitmq.client.ConnectionFactory;
- public class ConnectionUtils {
- /**
- * @desc 获取Mq 的链接
- * @author zp
- * @throws IOException
- * @date 2018-7-19
- */
- public static Connection getConnection() throws IOException {
- // 1.定义一个链接工厂
- ConnectionFactory factroy = new ConnectionFactory();
- // 2.设置服务地址
- factroy.setHost("127.0.0.1");
- // 3.设置端口号
- factroy.setPort(5672);
- // 4.vhost 设置数据库
- factroy.setVirtualHost("vhtest");
- // 5.设置用户名
- factroy.setUsername("jerry");
- // 6. 设置密码
- factroy.setPassword("123456");
- // 7.返回链接
- return factroy.newConnection();
- }
- }
消息生产者类Send,这个时候,运行代码再到控制台去查看,并没有发现我们的消息,因为在MQ中只有队列可以存储消息,而交换机不可以存储消息,下面这段代码并没有将交换机和队列进行绑定,所以数据就丢失了。
- package com.mmr.rabbitmq.ps;
- import java.io.IOException;
- import com.mmr.rabbitmq.util.ConnectionUtils;
- import com.rabbitmq.client.Channel;
- import com.rabbitmq.client.Connection;
- public class Send {
- private static final String EXCHANGE_NAME="test_exchange_fanout";
- public static void main(String[] args) throws IOException {
- // 创建连接
- Connection connection = ConnectionUtils.getConnection();
- // 获取通道
- Channel channel = connection.createChannel();
- // 声明交换机
- channel.exchangeDeclare(EXCHANGE_NAME, "fanout");// fanout 分发
- // 发送消息
- String msg = "hello ps";
- channel.basicPublish(EXCHANGE_NAME, "", null, msg.getBytes());
- System.out.println("send:"+msg);
- channel.close();
- connection.close();
- }
- }
代码运行后的控制台:
由于交换机不能存储数据,那么我们就需要考虑如何将交换机和队列进行绑定。因为只要将两者进行绑定之后,那么数据存储问题就迎刃而解。
消费者Recv1 Recv2
- package com.mmr.rabbitmq.ps;
- import java.io.IOException;
- import com.mmr.rabbitmq.util.ConnectionUtils;
- import com.rabbitmq.client.Channel;
- import com.rabbitmq.client.Connection;
- import com.rabbitmq.client.Consumer;
- import com.rabbitmq.client.DefaultConsumer;
- import com.rabbitmq.client.Envelope;
- import com.rabbitmq.client.AMQP.BasicProperties;
- public class Recv1 {
- private static final String QUEUE_NAME_STRING="test_queue_fanout_email";
- private static final String EXCHANGE_NAME="test_exchange_fanout";
- public static void main(String[] args) throws IOException {
- // 创建连接
- Connection connection = ConnectionUtils.getConnection();
- // 创建通道
- final Channel channel = connection.createChannel();
- // 声明队列
- channel.queueDeclare(QUEUE_NAME_STRING, false, false, false, null);
- // 绑定队列,绑定到交换机/转发器
- channel.queueBind(QUEUE_NAME_STRING, EXCHANGE_NAME, "");
- // 保证每次只分发一个
- channel.basicQos(1);
- // 定义一个消费者
- Consumer consumer = new DefaultConsumer(channel){
- @Override
- public void handleDelivery(String consumerTag, Envelope envelope,
- BasicProperties properties, byte[] body) throws IOException {
- // TODO Auto-generated method stub
- String msg = new String(body,"utf-8");
- System.out.println("[1]Recv msg:"+msg);
- try {
- // 每次休息一会儿
- Thread.sleep(2000);
- } catch (Exception e) {
- // TODO: handle exception
- e.printStackTrace();
- }finally{
- System.out.println("recv1 done");
- //回执
- channel.basicAck(envelope.getDeliveryTag(), false);
- }
- }
- };
- boolean autoAck = false;// 不自动应答
- channel.basicConsume(QUEUE_NAME_STRING, autoAck,consumer);
- }
- }
- package com.mmr.rabbitmq.ps;
- import java.io.IOException;
- import com.mmr.rabbitmq.util.ConnectionUtils;
- import com.rabbitmq.client.Channel;
- import com.rabbitmq.client.Connection;
- import com.rabbitmq.client.Consumer;
- import com.rabbitmq.client.DefaultConsumer;
- import com.rabbitmq.client.Envelope;
- import com.rabbitmq.client.AMQP.BasicProperties;
- public class Recv2 {
- private static final String QUEUE_NAME_STRING="test_queue_fanout_sms";
- private static final String EXCHANGE_NAME="test_exchange_fanout";
- public static void main(String[] args) throws IOException {
- // 创建连接
- Connection connection = ConnectionUtils.getConnection();
- // 创建通道
- final Channel channel = connection.createChannel();
- // 声明队列
- channel.queueDeclare(QUEUE_NAME_STRING, false, false, false, null);
- // 绑定队列,绑定到交换机/转发器
- channel.queueBind(QUEUE_NAME_STRING, EXCHANGE_NAME, "");
- // 保证每次只分发一个
- channel.basicQos(1);
- // 定义一个消费者
- Consumer consumer = new DefaultConsumer(channel){
- @Override
- public void handleDelivery(String consumerTag, Envelope envelope,
- BasicProperties properties, byte[] body) throws IOException {
- // TODO Auto-generated method stub
- String msg = new String(body,"utf-8");
- System.out.println("[2]Recv msg:"+msg);
- try {
- // 每次休息一会儿
- Thread.sleep(2000);
- } catch (Exception e) {
- // TODO: handle exception
- e.printStackTrace();
- }finally{
- System.out.println("recv2 done");
- //回执
- channel.basicAck(envelope.getDeliveryTag(), false);
- }
- }
- };
- boolean autoAck = false;// 不自动应答
- channel.basicConsume(QUEUE_NAME_STRING, autoAck,consumer);
- }
- }
运行上述代码进行监听,再通过运行Send发送消息,我们可以在MQ-管理平台上看到:
进过这样的使用,我们的消息订阅就完成了。
RabbitMQ简单应用の订阅模式的更多相关文章
- RabbitMQ的发布订阅模式(Publish/Subscribe)
一.发布/订阅(Publish/Subscribe)模式 发布订阅是我们经常会用到的一种模式,生产者生产消息后,所有订阅者都可以收到.RabbitMQ的发布/订阅模型图如下: 1.该模式下生产者并不是 ...
- RabbitMQ入门-消息订阅模式
消息派发 上篇<RabbitMQ入门-消息派发那些事儿>发布之后,收了不少反馈,其中问的最多的还是有关消息确认以及超时等场景的处理. 楼主,有遇到消费者后台进程不在,但consumer连接 ...
- RabbitMQ入门-发布订阅模式
兔子的Publish/Subscribe是这样的: 有个生产者P,X代表交换机,交换机绑定队列,消费者从队列中取得消息.每次有消息,先发到交换机中,然后由交换机负责发送到它已知的队列中. 生产者代码: ...
- RabbitMQ简单应用の主题模式(topic)
Topic exchange(主题转发器) 发送给主题转发器的消息不能是任意设置的选择键,必须是用小数点隔开的一系列的标识符.这些标识符可以是随意,但是通常跟消息的某些特性相关联.一些合法的路由选择键 ...
- 用BlockingQueue实现的简单发布订阅模式
- Go RabbitMQ(三)发布订阅模式
RabbitMQ 在上一节中我们创建了工作队列,并且假设每一个任务都能够准确的到达对应的worker.在本节中我们将介绍如何将一个消息传递到多个消费者,这也就是所说的发布订阅模式 为了验证该模式我们使 ...
- RabbitMQ指南之三:发布/订阅模式(Publish/Subscribe)
在上一章中,我们创建了一个工作队列,工作队列模式的设想是每一条消息只会被转发给一个消费者.本章将会讲解完全不一样的场景: 我们会把一个消息转发给多个消费者,这种模式称之为发布-订阅模式. 为了阐述这个 ...
- RabbitMQ六种队列模式-发布订阅模式
前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅 [本文]RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...
- RabbitMQ学习第三记:发布/订阅模式(Publish/Subscribe)
工作队列模式是直接在生产者与消费者里声明好一个队列,这种情况下消息只会对应同类型的消费者. 举个用户注册的列子:用户在注册完后一般都会发送消息通知用户注册成功(失败).如果在一个系统中,用户注册信息有 ...
随机推荐
- 关于shared_ptr与weak_ptr的使用(good)
shared_ptr是带引用计数的智能指针,可以说大部分的情形选择用shared_ptr不会出问题.那么weak_ptr是什么,应该怎么用呢? weak_ptr也是智能指针,但是比较弱,感觉没什么用. ...
- 多态(instanceof)
多态调用的三种格式 * A:多态的定义格式: * 就是父类的引用变量指向子类对象 父类类型 变量名 = new 子类类型(); 变量名.方法名(); * B: 普通类多态定义的格式 父类 变量名 = ...
- storm集群配置
环境:centos6.4软件:jzmq-master-----java与c++通讯的桥梁,有了它,就可以使用zeromp了storm-0.8.2zeromq-2.1.7-----号称史上最牛逼的消息队 ...
- chrome浏览器安装不上的惨痛经历
项目在赶进度的时候,手贱把chrome的一些文件删除了,整个浏览器都没法打开 决定重装下,但是连卸载的功能都打不开了 上网重新下载了个安装包,发现安装包都打不来 很绝望,查了很多资料 很多人说要删除注 ...
- C函数调用
目录 C函数调用 设置SP SP分析 区分NAND和NOR启动 参数调用 title: C函数调用 tags: ARM date: 2018-10-14 16:37:10 --- C函数调用 设置SP ...
- java使用google开源工具实现图片压缩【转】
jar包名 import net.coobird.thumbnailator.Thumbnails; import net.coobird.thumbnailator.geometry.Positio ...
- golang json反序列化
package main import ( "encoding/json" "fmt" "reflect" ) type js struct ...
- mysql使用navicat和mysqldump导出数据
1.navicat 方式一:选中表,右键转储:(含有表结构和数据) 方式二:选择右上角工具,点击数据传输,在这个页面右侧选择数据库,左侧选择文件. 点击下一步,选择导出的表名和各种函数什么的,然后点击 ...
- 解析ArcGis的标注(一)——先看看分数式、假分数式标注是怎样实现的
该“标注”系列博文的标注引擎使用“标准标注引擎(standard label engine)”,这个概念如不知道,可不理会,ArcGis默认标注引擎就是它. ArcGis的标注表达式支持VBScrip ...
- 错误记录:vue跟vue编译器版本不一致
错误如下: error in ./src/Utils.vue Module build failed: Error: Vue packages version mismatch: - vue@ - v ...