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. 2023牛客寒假算法基础集训营5 A-L

    比赛链接 A 题解 知识点:前缀和,二分. 找到小于等于 \(x\) 的最后一个物品,往前取 \(k\) 个即可,用前缀和查询. 时间复杂度 \(O(n + q\log n)\) 空间复杂度 \(O( ...

  2. JAVA虚拟机-01-JAVA虚拟机家族简介

    JAVA虚拟机家族简介 Classic VM JDK1.0发布,第一款商议的JAVA虚拟机.纯解释器方式来执行java代码的的JAVA虚拟机.如果要使用即时编译就需要外挂编译器.如果外挂了编译器,及时 ...

  3. 生成式AI对业务流程有哪些影响?企业如何应用生成式AI?一文看懂

    集成与融合类ChatGPT工具与技术,以生成式AI变革业务流程 ChatGPT背后的生成式AI,聊聊生成式AI如何改变业务流程 ChatGPT月活用户过亿,生成式AI对组织的业务流程有哪些影响? 生成 ...

  4. MySQL数据库报1055错误

    有点坑啊,当初装MySQL数据库的时候没有整配置文件,结果MySQL报1055错误的时候,网上的解决办法都说如果需要永久生效的话,只能通过改配置文件实现,but,我没有配置文件,蜜汁尴尬啊 1.已安装 ...

  5. C#中的Byte,String,Int,Hex之间的转换函数

    /// <summary> Convert a string of hex digits (ex: E4 CA B2) to a byte array. </summary> ...

  6. 安卓逆向 ARM基础篇 二

    1.寄存器寻址的八中方法 1.立即寻址 二 寄存器寻址 三 寄存器移位寻址 过程 R2 移位 传给R0 四 寄存器间接寻址 五 基址寻址 六 多寄存器寻址 七 堆栈寻址 七 堆栈寻址

  7. 权限维持之:DSRM 域控权限维持

    目录 1 修改 DSRM 密码 2 DSRM 域后门操作过程 3 DSRM 域后门防御 目录服务恢复模式(DSRM,Directory Services Restore Mode),是Windows服 ...

  8. Django中多数据库的配置,实现分库分表,主从复制,读写分离

    在django项目中, 一个工程中存在多个APP应用很常见. 有时候希望不同的APP连接不同的数据库,这个时候需要建立多个数据库连接. 1. 修改项目的 settings 配置 在 settings. ...

  9. 【10】java之final关键字

    1.使用final 定义的变量就变成了常量,常量必须在定义的时候就设置好内容且不能修改. public static final 声明的就是全局常量. public static final Stri ...

  10. 修改文件名或文件内容编码-convmv

    问题的出现 开发小伙伴把之前运行在windows server上的项目迁移到ubuntu上之后出现了中文乱码的问题,分析其原因是代码中创建文件未指定编码,所以就自动匹配了操作系统的编码,也就是从GBK ...