官网介绍:https://www.rabbitmq.com/getstarted.html

五种工作模式的主要特点

  1. 简单模式:一个生产者,一个消费者
  2. work模式:一个生产者,多个消费者,每个消费者获取到的消息唯一(消费者彼此竞争成为接收者)。
  3. 订阅模式:一个生产者发送的消息会被多个消费者获取。
  4. 路由模式:发送消息到交换机并且要指定路由key ,消费者将队列绑定到交换机时需要指定路由key
  5. topic模式:将路由键和某模式进行匹配,此时队列需要绑定在一个模式上,“#”匹配一个词或多个词,“*”只匹配一个词。

简单模式(一个生产者,一个消费者)

这种模式下不需要将Exchange进行任何绑定(binding)操作

    public static final String QUEUE_NAME= "myqueue";

    public static void test() throws Exception {
//定义连接工厂
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
//设置Virtual Host
factory.setVirtualHost("/ld");
factory.setUsername("ld");
factory.setPassword("aaa");
//通过工厂获取连接
Connection connection = factory.newConnection(); //创建队列,发送消息
public void producer () {
//创建通道
Channel channel = connection.createChannel();
//声明创建队列
/**
队列名
是否持久化
是否排外 即只允许该channel访问该队列 一般等于true的话用于一个队列只能有一个消费者来消费的场景
是否自动删除(自动删除的前提是: 至少有一个消费者连接到这个队列,之后所有与这个队列连接的消费者都断开时,才会 自动删除。)
其他属性
*/
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//消息内容
String message = "Hello World!";
//发布消息
/**
交换机
队列名
其他属性 路由
消息body
*/
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
//关闭连接和通道
channel.close();
connection.close();
}
//消费者消费消息
public void consumer () {
//创建通道
Channel channel = connection.createChannel();
//声明通道
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//定义消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
//监听队列
//autoAck 是否自动确认消息,true自动确认
channel.basicConsume(QUEUE_NAME, true, consumer);
while (true) {
//这个方法会阻塞住,直到获取到消息
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("接收到消息:" + message);
}
}
}

work模式(一个生产者,一个队列,多个消费者,每个消费者获取到的消息唯一)

    public static final String QUEUE_NAME= "myqueue";

    //消息生产者
public void producer{
//获取连接和通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String message = "";
for (int i = 0; i < 100; i++) {
message = "" + i;
channel.basicPublish("",QUEUE_NAME, null, message.getBytes());
Thread.sleep(i);
}
channel.close();
connection.close();
} //消费者1
public void consumer1{
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//同一时刻服务器只发送一条消息给消费端
channel.basicQos(1);
QueueingConsumer consumer = new QueueingConsumer(channel);
//false:手动确认
channel.basicConsume(QUEUE_NAME, false, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("recive1:" + message);
Thread.sleep(100);
//消息消费完给服务器返回确认状态,表示该消息已被消费
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}

channel.basicPublish

channel.basicPublish(String exchange, String routingKey, boolean mandatory, boolean immediate, BasicProperties props, byte[] body)

mandatory:
true:如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,
那么会调用basic.return方法将消息返还给生产者。 false:出现上述情形broker会直接将消息扔掉 immediate:
true:如果exchange在将消息route到queue(s)时发现对应的queue上没有消费者,那么这条消息不会放入队列中。
当与消息routeKey关联的所有queue(一个或多个)都没有消费者时,该消息会通过basic.return方法返还给生产者。 BasicProperties :
需要注意的是BasicProperties.deliveryMode:
0:不持久化 1:持久化
这里指的是消息的持久化,配合channel(durable=true),queue(durable)可以实现,即使服务器宕机,消息仍然保留

fanout订阅模式(一个生产者,多个队列,多个消费者)

这种模式需要提前将Exchange与Queue进行绑定,

一个Exchange可以绑定多个Queue,一个Queue可以同多个Exchange进行绑定。

​ 一个生产者发送的消息会被多个消费者获取。

生产者:可以将消息发送到队列或者是交换机。
消费者:只能从队列中获取消息。 如果消息发送到没有队列绑定的交换机上,那么消息将丢失。 public static final String EXCHANGE_NAME = "exchange_fanout"; //生产者
public void producer() {
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明交换机 fanout
channel.exchangeDeclare(EXCHANGE_NAME, "fanout"); String message = "Hello World!";
channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes()); channel.close();
connection.close();
} //消费者1
public final static String QUEUE_NAME = "queue_fanout_1";
public void consumer1() {
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//绑定队列到交换机上
channel.queueBind(QUEUE_NAME, Send.EXCHANGE_NAME, "");
channel.basicQos(1);
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE_NAME, true, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(message);
}
}

direct路由模式(完全匹配、单播的模式)

1. 发送消息到交换机并且要指定路由key

2. 消费者将队列绑定到交换机时需要指定路由key

3. 完全匹配,只有匹配到的消费者才能消费消息

4. 一个队列可以绑定多个路由

    public static final String EXCHANGE_NAME = "exchange_direct";

    //生产者
public void producer() {
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明交换机 direct
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
String message = "Hello World!";
channel.basicPublish(EXCHANGE_NAME, "key", null, message.getBytes());
channel.close();
connection.close();
} //消费者1
public final static String QUEUE_NAME = "queue_direct_1"; public void consumer1() {
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//绑定队列到交换机上,并制定路由键为"key"
channel.queueBind(QUEUE_NAME, com.bw.rabbitmq.routing.Send.EXCHANGE_NAME, "key");
channel.basicQos(1);
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE_NAME, true, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(message);
}
}

topic通配符模式

两个通配符:符号“#”和符号“*”。#匹配0个或多个单词,*匹配一个单词

    //生产者
public static final String EXCHANGE_NAME = "exchange_topic"; public void producer() {
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明交换机 topic:交换机类型
channel.exchangeDeclare(EXCHANGE_NAME, "topic");
String message = "Hello World!";
channel.basicPublish(EXCHANGE_NAME, "key.1", null, message.getBytes());
System.out.println(message);
channel.close();
connection.close();
} //消费者1
public final static String QUEUE_NAME = "queue_topic_1"; public static void main(String[] args) throws Exception {
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//绑定队列到交换机上,并制定路由键匹配规则为"key.*"
channel.queueBind(QUEUE_NAME, com.bw.rabbitmq.topics.Send.EXCHANGE_NAME, "key.*");
channel.basicQos(1);
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE_NAME, true, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(message);
}
}

RabbitMQ 五种工作模式的更多相关文章

  1. rabbitmq的五种工作模式

    abbitmq的五种工作模式      

  2. Thrift 的五种工作模式

    一.thrift 共有5中工作模式,分成阻塞和非阻塞: 阻塞:TSimpleServer.TThreadPoolServer 非阻塞:TNonblockingServer.THsHaServer.TT ...

  3. 消息队列rabbitmq的五种工作模式(go语言版本)

    前言:如果你对rabbitmq基本概念都不懂,可以移步此篇博文查阅消息队列RabbitMQ 一.单发单收 二.工作队列Work Queue 三.发布/订阅 Publish/Subscribe 四.路由 ...

  4. 面试官:RabbitMQ有哪些工作模式?

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 今天又.又.又来面试了,还是老规 ...

  5. RabbitMQ入门及其几种工作模式

    1.简介 MQ全程Message Queue,用于应用程序和应用程序间进行通信.RabbitMQ采用Erlang编写,实现了AMQP(高级消息队列)协议,跨平台,支持各种主流的操作系统和多种客户端. ...

  6. RabbitMQ的六种工作模式总结

    最近学习RabbitMQ的使用方式,记录下来,方便以后使用,也方便和大家共享,相互交流. RabbitMQ的六种工作模式: 1.Work queues2.Publish/subscribe3.Rout ...

  7. ARM体系的7种工作模式

    一.ARM体系的CPU有以下7种工作模式:   用户模式(usr)    大多数程序运行于用户模式 特权模式   系统模式(sys)   运行具有特权的操作系统任务 异常模式 中断模式(irq)   ...

  8. 转:Windows下的PHP开发环境搭建——PHP线程安全与非线程安全、Apache版本选择,及详解五种运行模式。

    原文来自于:http://www.ituring.com.cn/article/128439 Windows下的PHP开发环境搭建——PHP线程安全与非线程安全.Apache版本选择,及详解五种运行模 ...

  9. AES五种加密模式(CBC、ECB、CTR、OCF、CFB)

    --转载https://www.cnblogs.com/starwolf/p/3365834.html https://www.freebuf.com/column/171939.html 分组密码有 ...

随机推荐

  1. LeetCode 183. Customers Who Never Order (从不订购的客户)

    题目标签: 题目给了我们 Customers 和 Orders 两个表格,让我们找到 从没订购过的客户. 首先从Orders 得到 订购过的CustomerId,然后再去Customers 里找 没有 ...

  2. mac的终端运行ifconfig

    lo0:loopback回环地址一般是127.0.0.0,loopback指本地环回接口(或地址),亦称回送地址().此类接口是应用最为广泛的一种虚接口,几乎在每台路由器上都会使用. gif0: so ...

  3. 洛谷P1860——新魔法药水

    传送门:QAQQAQ 题意:商店里有N种药水,每种药水都有一个售价和回收价.小S攒了V元钱,还会M种魔法,可以把一些药水合成另一种药水.他一天可以使用K次魔法,问他一天最多赚多少钱? N<=60 ...

  4. 夏令营501-511NOIP训练18——高二学堂

    传送门:QAQQAQ 题意:给你一个数$n$,把它拆分成至多$k$个正整数,使得这些数的和等于$n$且每一个正整数的个数不能超过$4$ 拆分的顺序是无序的,但取出每一个数方案是不同的(例如我要拆$1$ ...

  5. 剑指offer——30包含min函数的栈

    题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)).   题解: 借助辅助栈,新的数据<=f辅助栈顶时,就压入辅助栈,这样,就能保证辅 ...

  6. 剑指offer——14机器人的运动范围

    题目描述 地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子. 例如,当k为18时,机器人能 ...

  7. 3-MySQL高级-事务-命令(2)

    事务命令 表的引擎类型必须是innodb类型才可以使用事务,这是mysql表的默认引擎 查看表的创建语句,可以看到engine=innodb -- 选择数据库 use jing_dong; -- 查看 ...

  8. 牛客D-Where are you /// kruskal+tarjan找无向图内的环

    题目大意: https://ac.nowcoder.com/acm/contest/272/D 在一个无向图中,给定一个起点,从起点开始走遍图中所有点 每条边有边权wi,表示第一次经过该道路时的花费( ...

  9. 【POJ】1860 Currency Exchange

    真是气skr人..没把d[]换成double...de了一上午的bug// 记得用G++提交啊 题目链接:http://poj.org/problem?id=1860 题意:告诉你n个点,m条路.起始 ...

  10. List<VO>转成List<Map>

    List<A01090021BatchAddCheckVO> list = (ArrayList<A01090021BatchAddCheckVO>) result.get(& ...