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. immutable.js学习笔记(五)----- Set

    一.Set 二.API (一)add:添加值 (二)delete:删除值 注意:删除后的Set是无序的 (三)clear:清空并返回新Set (四)union:N个set合并为一个set (五)int ...

  2. C-04\IDE基础知识和分支,循环语句

    一.浮点数特性及比较方法 浮点数在多参数传参的时候默认是会进行精度转换,由float转换到double,浮点数是一个近视值,不能进行直接等于比较,一般可以用区间法比较但是会存在精度丢失的问题. 浮点数 ...

  3. Ribbon负载均衡 (源码分析)

    Ribbon负载均衡 SpringCloud已经删除了ribbon组件,所以需要手动导入依赖.(要学是因为很多项目业务已经使用了ribbon) 服务拉取的时候添加了@LoadBalanced注解,实现 ...

  4. Listen 1音乐播放器

    Listen 1 Listen 1可以搜索和播放来自网易云音乐,QQ音乐,酷狗音乐,酷我音乐,Bilibili,咪咕音乐网站的歌曲,让你的曲库更全面.还支持歌单功能,你可以方便的播放,收藏和创建自己的 ...

  5. 剑指 Offer 34. 二叉树中和为某一值的路径(java解题)

    目录 1. 题目 2. 解题思路 3. 数据类型功能函数总结 4. java代码 1. 题目 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总 ...

  6. EPICS Archiver Appliance存储waveform记录的尝试

    https://blog.csdn.net/u013894429/article/details/79724454 按上面的指导很容易跑起来,试了一下,也能archive短些的waveform记录,很 ...

  7. 关于vue项目和内嵌iframe页面之间的通信问题

    最近项目中遇到一个与内嵌iframe页面之间通信的问题,起初与原生之间通信很简单,没想到过与vue项目通信的问题,霎时间一脸懵*啊,百度了一下,原来是那么简单,这里记录下以供下次参考 //vue页面 ...

  8. vue-element-admin 怎么改后端 可以调跳过登录并且发送接口请求

    1.找到根目录的 vue.config.js 添加 proxy 内容 注释掉mock 2.清空 .env.development 里的 VUE_APP_BASE_API  路径 3.user.js 方 ...

  9. 关于 Knex update 语句报错:Undefined binding(s) detected when compiling UPDATE

    下图是详细的报错截图,我敢保证前端传递的数据一个不漏,但还是报我没有绑定对应的字段: 官方文档的使用案例基本上都是where 子句在 update 语句之前.但,select 语句的 where 子句 ...

  10. 银河麒麟V10安装MySQL5.7

      环境: Kylin-Server-10-SP2-Release-Build09-20210524-x86_64.isomysql-5.7.28-linux-glibc2.12-x86_64.tar ...