Rabbit MQ的几种模式
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的几种模式的更多相关文章
- Python操作Rabbit MQ的5种模式
python版本: 2.7.14 一 消息生产者代码: # -*- coding: utf-8 -*- import json import pika import urllib import u ...
- 在 Windows 上安装Rabbit MQ 指南
rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.他遵循Mozilla Public License开源协议.采用 Erlang 实现的工业级的消息队列(MQ)服务器. Ra ...
- (转)在 Windows 上安装Rabbit MQ 指南
rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.他遵循Mozilla Public License开源协议.采用 Erlang 实现的工业级的消息队列(MQ)服务器. Ra ...
- celery rabbit mq 详解
Celery介绍和基本使用 Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery, ...
- Rabbit MQ 消息确认和持久化机制
一:确认种类 RabbitMQ的消息确认有两种.一种是消息发送确认,用来确认生产者将消息发送给交换器,交换器传递给队列的过程中消息是否成功投递.发送确认分为两步,一是确认是否到达交换器,二是确认是否到 ...
- Rabbit MQ 入门指南
rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.他遵循Mozilla Public License开源协议.采用 Erlang 实现的工业级的消息队列(MQ)服务器. Ra ...
- 分布式消息中间件Rabbit Mq的了解与使用
MQ(消息队列)作为现代比较流行的技术,在互联网应用平台中作为中间件,主要解决了应用解耦.异步通信.流量削锋.服务总线等问题,为实现高并发.高可用.高伸缩的企业应用提供了条件. 目前市面比较流行的消息 ...
- Spring Boot:使用Rabbit MQ消息队列
综合概述 消息队列 消息队列就是一个消息的链表,可以把消息看作一个记录,具有特定的格式以及特定的优先级.对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息,对消息队列有读权限的进程则可以 ...
- Spring boot集成Rabbit MQ使用初体验
Spring boot集成Rabbit MQ使用初体验 1.rabbit mq基本特性 首先介绍一下rabbitMQ的几个特性 Asynchronous Messaging Supports mult ...
- 使用Rabbit MQ消息队列
使用Rabbit MQ消息队列 综合概述 消息队列 消息队列就是一个消息的链表,可以把消息看作一个记录,具有特定的格式以及特定的优先级.对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息 ...
随机推荐
- 12月15日内容总结——ORM执行原生SQL语句、双下划线数据查询、ORM外键字段的创建、外键字段的相关操作、ORM跨表查询、基于对象的跨表查询、基于双下划线的跨表查询、进阶查询操作
目录 一.ORM执行SQL语句 二.神奇的双下划线查询 三.ORM外键字段的创建 复习MySQL外键关系 外键字段的创建 1.创建基础表(书籍表.出版社表.作者表.作者详情) 2.确定外键关系 3.O ...
- statefulset详解及为何结合headless service部署有状态应用
1.1 有状态应用管理statefulset StatefulSet(有状态集,缩写为sts)常用于部署有状态的且需要有序启动的应用程序,比如在进行SpringCloud项目容器化时,Eureka的部 ...
- 为什么要使用 chmod 777
如上图所示, 不使用sudo,报错没有权限 使用sudo,报错找不到命令 只好chmod 777一下了
- 编写antd的Cascader 级联选择组件市级地区数据
下面是该组件的使用数据的格式 options: [ { value: 'zhejiang', label: 'Zhejiang', children: [ { value: 'hangzhou', l ...
- Vue37 常用的组件库
1 移动端 vant ui:https://vant-ui.github.io/vant/#/zh-CN (https://vant-ui.github.io/vant/#/zh-CN) cube u ...
- 云萌 V2.6.3.0 win10,win11 Windows永久激活工具
Windows如果一直不激活,其实用起来问题也不大,除了无法修改壁纸.颜色.锁屏.主题以及无法使用微软账号的同步功能等之外,绝大多数的基本功能都可以正常使用.不过该激活还是得激活的.别的不说,就桌面右 ...
- C++练习2 强制类型转换
const可以把有关的数据定义为常量. const类型可以修饰:对象,指针,引用 使用const_cast为强制类型转换,将常量强制转换非常量. 1 #include <iostream> ...
- EPICS Archiver Appliance在Centos7的定制部署
EPICS Archiver Appliance的定制部署1 EPICS Archiver Appliance的定制部署2 上面两篇是在Centos8下成功,后来又想在Centos7下跑成功,按上面的 ...
- Rocky Linux安装
1.下载 VirtualBox并安装 https://www.virtualbox.org/wiki/Downloads 2.下载Rocky Linux 选择 Rocky-9.1-x86_64-dvd ...
- metasploit2-practice
Metasploittable2打靶教程 本次靶机练习主要熟悉:高危端口利用:metasploit中search,show及各个模块使用. 一.环境准备 1.把靶场放在vmware打开,启用nat模式 ...