RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。

官网文档:https://www.rabbitmq.com/getstarted.html

Rabbit MQ有几种工作方式:

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

work模式:一个生产者,多个消费者,每个消费者获取到的消息唯一,平均消费。

订阅模式:一个生产者发送的消息会被多个消费者获取。

路由模式:发送消息到交换机并且要指定路由key ,消费者将队列绑定到交换机时需要指定路由key

topic模式:将路由键和某模式进行匹配,此时队列需要绑定在一个模式上,“#”匹配一个词或多个词,“*”只匹配一个词。

rpc模式:客户端向一个队列中发送消息,并注册一个回调的队列用于接收服务端返回的消息,该消息需要声明一个叫做correaltionId的属性,

该属性将是该次请求的唯一标识。服务端在接受到消息(在需要时可以验证correaltionId)后,处理消息,并将消息发送到客户端注册的回调队列中。

1、简单模式

配置:

public final static String SIMPLE_QUEUE = "simpleQueue";
@Bean
public Queue simpleQueue() {
return new Queue(SIMPLE_QUEUE, true);
} 生产者: rabbitTemplate.convertAndSend(RabbitConfig.SIMPLE_QUEUE, msg); 消费者:

@RabbitListener(queues = RabbitConfig.SIMPLE_QUEUE)
public void simpleListen(String msg) {
System.out.println("simple队列 接收到消息:" + msg);
}

2、work模式

一个生产者,多个消费者,每个消费者获取到的消息唯一。一条消息只能被其中一个消费掉,相互争夺资源。

配置:

public final static String WORK_QUEUE = "workQueue";
@Bean
public Queue workQueue() {
return new Queue(WORK_QUEUE, true);
} 生产者: public void sendWorkQueueMq(String msg) {
rabbitTemplate.convertAndSend(RabbitConfig.WORK_QUEUE, msg);
logger.info("发送消息:{}", msg);
} 消费者: @RabbitListener(queues = RabbitConfig.WORK_QUEUE)
public void workListen1(String msg) {
System.out.println("work模式1 接收到消息:" + msg);
} @RabbitListener(queues = RabbitConfig.WORK_QUEUE)
public void workListen2(String msg) {
System.out.println("work模式2 接收到消息:" + msg);
}

3、发布/订阅模式

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

配置:

public final static String FANOUT_QUEUE_ONE = "fanout_queue_one";
public final static String FANOUT_QUEUE_TWO = "fanout_queue_two";
public final static String FANOUT_EXCHANGE = "fanout_exchange";
// fanout 广播者模式队列
@Bean
public Queue fanoutQueueOne() {
return new Queue(FANOUT_QUEUE_ONE, true);
} @Bean
public Queue fanoutQueueTwo() {
return new Queue(FANOUT_QUEUE_TWO, true);
} // fanout 交换器
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange(FANOUT_EXCHANGE);
} // 广播模式绑定
@Bean
public Binding fanoutExchangeBingingOne() {
return BindingBuilder.bind(fanoutQueueOne()).to(fanoutExchange()); } @Bean
public Binding fanoutExchangeBingingTwo() {
return BindingBuilder.bind(fanoutQueueTwo()).to(fanoutExchange());
} 生产者: public void sendFanoutExchangeMq(String msg) {
rabbitTemplate.convertAndSend(RabbitConfig.FANOUT_EXCHANGE, "", msg);
logger.info("发送消息:{}", msg);
} 消费者: @RabbitListener(queues = RabbitConfig.FANOUT_QUEUE_ONE)
public void fanoutListen1(String msg) {
System.out.println("fanout模式1 接收到消息:" + msg);
} @RabbitListener(queues = RabbitConfig.FANOUT_QUEUE_TWO)
public void fanoutListen2(String msg) {
System.out.println("fanout模式2 接收到消息:" + msg);
}

4、路由模式

发送消息到交换机并且要指定路由key ,消费者将队列绑定到交换机时需要指定路由key。那么消息只会发送到相应key相同的队列,接着监听该队列的消费者消费消息。

配置:

public final static String DIRECT_QUEUE_ONE = "direct_queue_one";
public final static String DIRECT_QUEUE_TWO = "direct_queue_two";
public final static String DIRECT_EXCHANGE = "direct_exchange";
// direct 路由模式队列
@Bean
public Queue directQueueOne() {
return new Queue(DIRECT_QUEUE_ONE, true);
} @Bean
public Queue directQueueTwo() {
return new Queue(DIRECT_QUEUE_TWO, true);
} // direct 交换器
@Bean
public DirectExchange directExchange() {
return new DirectExchange(DIRECT_EXCHANGE);
} //路由模式绑定
@Bean
public Binding directExchangeBingingOne() {
return BindingBuilder.bind(directQueueOne()).to(directExchange()).with("orange");
} @Bean
public Binding directExchangeBingingTwo() {
return BindingBuilder.bind(directQueueTwo()).to(directExchange()).with("black");
} 生产者: public void sendDirectExchangeMq(String routingKey, String msg) {
rabbitTemplate.convertAndSend(RabbitConfig.DIRECT_EXCHANGE,"orange" , msg);
logger.info("发送消息:{}", msg);
} 消费者: @RabbitListener(queues = RabbitConfig.DIRECT_QUEUE_ONE)
public void directListenOne(String msg) {
System.out.println("direct模式1 接收到消息:" + msg);
} @RabbitListener(queues = RabbitConfig.DIRECT_QUEUE_TWO)
public void directListenTwo(String msg) {
System.out.println("direct模式2 接收到消息:" + msg);
}
如上代码,只有routingKey 为orange的能收到消息

5、topic模式

将路由键和某模式进行匹配,此时队列需要绑定在一个模式上,“#”匹配一个词或多个词,“*”只匹配一个词。

配置:

public final static String TOPIC_QUEUE_ONE = "topic_queue_one";
public final static String TOPIC_QUEUE_TWO = "topic_queue_two";
public final static String TOPIC_EXCHANGE = "topic_exchange"; public final static String TOPIC_ROUTINGKEY_ONE = "common.key";
public final static String TOPIC_ROUTINGKEY_TWO = "*.key";
// topic 订阅者模式队列
@Bean
public Queue topicQueueOne() {
return new Queue(TOPIC_QUEUE_ONE, true);
} @Bean
public Queue topicQueueTwo() {
return new Queue(TOPIC_QUEUE_TWO, true);
} // topic 交换器
@Bean
public TopicExchange topExchange() {
return new TopicExchange(TOPIC_EXCHANGE);
} // 订阅者模式绑定
@Bean
public Binding topicExchangeBingingOne() {
return BindingBuilder.bind(topicQueueOne()).to(topExchange()).with(TOPIC_ROUTINGKEY_ONE);
} @Bean
public Binding topicExchangeBingingTwo() {
return BindingBuilder.bind(topicQueueTwo()).to(topExchange()).with(TOPIC_ROUTINGKEY_TWO);
} 生产者: public void sendTopicExchangeMq(String routingKey, String msg) {
rabbitTemplate.convertAndSend(RabbitConfig.TOPIC_EXCHANGE, "common.key", msg);
logger.info("发送消息:{}", msg);
}
消费者: @RabbitListener(queues = RabbitConfig.TOPIC_QUEUE_ONE)
public void topicListenOne(String msg) {
System.out.println("topic模式1 接收到消息:" + msg);
} @RabbitListener(queues = RabbitConfig.TOPIC_QUEUE_TWO)
public void topicListenTwo(String msg) {
System.out.println("topic模式2 接收到消息:" + msg);
}
根据routingKey匹配对应的才能收到消息

6、rpc模式

客户端向一个队列中发送消息,并注册一个回调的队列用于接收服务端返回的消息,该消息需要声明一个叫做correaltionId的属性,

该属性将是该次请求的唯一标识。服务端在接受到消息(在需要时可以验证correaltionId)后,处理消息,并将消息发送到客户端注册的回调队列中。

配置:

public final static String RPC_SIMPLE_QUEUE_ONE = "rpcSimpleQueue_one";
public final static String RPC_SIMPLE_QUEUE_TWO = "rpcSimpleQueue_two";
// rpc简单模式队列
@Bean
public Queue rpcSimpleQueueOne() {
return new Queue(RPC_SIMPLE_QUEUE_ONE, true);
} @Bean
public Queue rpcSimpleQueueTwo() {
return new Queue(RPC_SIMPLE_QUEUE_TWO, true);
} @Value("${spring.rabbitmq.addresses}")
private String host; @Value("${spring.rabbitmq.username}")
private String username;
@Value("${spring.rabbitmq.password}")
private String password; @Autowired
ConnectionFactory connectionFactory; @Autowired
RabbitTemplate rabbitTemplate; @Bean(name = "connectionFactory")
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(host);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost("/");
return connectionFactory;
} public RabbitTemplate getRabbitTemplate() {
rabbitTemplate.setReplyAddress(RPC_SIMPLE_QUEUE_TWO);
rabbitTemplate.setReplyTimeout(2000);
return rabbitTemplate;
} @Bean(name = "replyMessageListenerContainer")
public SimpleMessageListenerContainer createReplyListenerContainer() {
SimpleMessageListenerContainer listenerContainer = new SimpleMessageListenerContainer();
listenerContainer.setConnectionFactory(connectionFactory);
listenerContainer.setQueueNames(RPC_SIMPLE_QUEUE_TWO);
listenerContainer.setMessageListener(getRabbitTemplate());
return listenerContainer;
} 生产者: public Message sendRpcSimpleQueueMq(Message msg) {
rabbitTemplate.setReplyAddress(RabbitConfig.RPC_SIMPLE_QUEUE_TWO);
rabbitTemplate.setReplyTimeout(2000);
Message message = rabbitTemplate.sendAndReceive(RabbitConfig.RPC_SIMPLE_QUEUE_ONE, msg);
logger.info("发送消息:{}", msg);
return message;
}
消费者: @RabbitListener(queues = RabbitConfig.RPC_SIMPLE_QUEUE_ONE)
public void rpcSimpleListenOne(Message msg) {
System.out.println("rpc simple 1队列 接收到消息:" + msg);
rabbitTemplate.send(RabbitConfig.RPC_SIMPLE_QUEUE_TWO, con("回复消息:" + new String(msg.getBody()), msg.getMessageProperties().getCorrelationId()));
} public Message con(String s, String id) {
MessageProperties mp = new MessageProperties();
byte[] src = s.getBytes(Charset.forName("UTF-8"));
mp.setCorrelationId(id);
mp.setContentType("application/json");
mp.setContentEncoding("UTF-8");
mp.setContentLength((long) s.length());
return new Message(src, mp);
}

、问题处理

Rabbit MQ的几种模式的更多相关文章

  1. Python操作Rabbit MQ的5种模式

    python版本:   2.7.14 一 消息生产者代码: # -*- coding: utf-8 -*- import json import pika import urllib import u ...

  2. 在 Windows 上安装Rabbit MQ 指南

    rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.他遵循Mozilla Public License开源协议.采用 Erlang 实现的工业级的消息队列(MQ)服务器. Ra ...

  3. (转)在 Windows 上安装Rabbit MQ 指南

    rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.他遵循Mozilla Public License开源协议.采用 Erlang 实现的工业级的消息队列(MQ)服务器. Ra ...

  4. celery rabbit mq 详解

    Celery介绍和基本使用 Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery, ...

  5. Rabbit MQ 消息确认和持久化机制

    一:确认种类 RabbitMQ的消息确认有两种.一种是消息发送确认,用来确认生产者将消息发送给交换器,交换器传递给队列的过程中消息是否成功投递.发送确认分为两步,一是确认是否到达交换器,二是确认是否到 ...

  6. Rabbit MQ 入门指南

    rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.他遵循Mozilla Public License开源协议.采用 Erlang 实现的工业级的消息队列(MQ)服务器. Ra ...

  7. 分布式消息中间件Rabbit Mq的了解与使用

    MQ(消息队列)作为现代比较流行的技术,在互联网应用平台中作为中间件,主要解决了应用解耦.异步通信.流量削锋.服务总线等问题,为实现高并发.高可用.高伸缩的企业应用提供了条件. 目前市面比较流行的消息 ...

  8. Spring Boot:使用Rabbit MQ消息队列

    综合概述 消息队列 消息队列就是一个消息的链表,可以把消息看作一个记录,具有特定的格式以及特定的优先级.对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息,对消息队列有读权限的进程则可以 ...

  9. Spring boot集成Rabbit MQ使用初体验

    Spring boot集成Rabbit MQ使用初体验 1.rabbit mq基本特性 首先介绍一下rabbitMQ的几个特性 Asynchronous Messaging Supports mult ...

  10. 使用Rabbit MQ消息队列

    使用Rabbit MQ消息队列 综合概述 消息队列 消息队列就是一个消息的链表,可以把消息看作一个记录,具有特定的格式以及特定的优先级.对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息 ...

随机推荐

  1. C++迭代器种类与编译期间多态

    迭代器分类 C++ STL 中根据移动能力将迭代器分成了 5 类: Input Iterator 输入迭代器,只支持 operator++ 操作. Output Iterator 输出迭代器,只支持 ...

  2. Selenium CHANGELOG[最新版本4.8.0 计划中]

    Selenium CHANGELOG[持续更新] 源文件 https://github.com/SeleniumHQ/selenium/blob/trunk/py/CHANGES 搬运工 对重点版本做 ...

  3. 【LeetCode字符串#05】基于个人理解的KMP算法图解,以及应用到strStr()函数实现

    KMP算法(用于实现 strStr()) strStr()函数是用来在一个字符串中搜索是否存在另一个字符串的函数,其匹配字符串方式为KMP算法 KMP算法基础理论 假设有如下两个字符串 文本串 aab ...

  4. elasticsearch-head-master安装

    1 简介 elasticsearch-head是一款专门针对于elasticsearch的客户端工具,elasticsearch-head是一个基于node.js的前端工程 2 依赖 需要安装node ...

  5. JSTL标签库C标签的使用注意事项

    今天在写jsp中在c标签上踩了不少坑,在此记录一下. <c:if>标签单独使用,不与<c:otherwise>配套使用,搭配使用会报错. <c:otherwise> ...

  6. ubuntu 备份系统

    1.安装Systemback: sudo add-apt-repository ppa:nemh/systemback sudo apt-get update sudo apt-get install ...

  7. 【TS】泛型以及多个泛型参数

    泛型 给函数或者属性定义类型的时候,类型是固定的,当业务发生变动时可能不好维护,例如:函数类型固定为string,后续需求更改不好维护,比如需要传入number类型,那么这个函数就不适用了 funct ...

  8. wordpress配置指南

    1.创建资源 在页面左侧,单击 云产品资源 下拉列表,查看本次实验所需资源. 单击屏幕右侧 创建资源 ,免费创建当前实验所需云产品资源. 资源创建过程需要1~3分钟.完成实验资源的创建后,您可以在 云 ...

  9. Trie 的一类应用

    \(\text{Trie}\) 先从 [十二省联考 \(2019\)] 异或粽子 谈起 不难想到堆加可持久化 \(Trie\) 的做法 这就和 \(\text{[NOI2010]}\) 超级钢琴 类似 ...

  10. python pip 升级失败解决方法

    今天花了一上午学习python,然后现在在研究做爬虫,结果发现python提示pip需要更高的版本,然后就研究了半天,解决方法如下: 一.检查版本: pip show pip 二.更新版本: pyth ...