目录
RabbitMQ是什么?
RabbitMQ内部作用是什么?
RabbitMQ的作用?
rabbitmq六种工作模式
简单模式
nio的理解,使用了
使用步骤
工作模式
负载均衡 ---轮询
合理分发请求--发送回执,发给别人
发送回执
手动确认发送回执
.basicConsume("helloworld", false, callback, cancel);
报错
合理分发请求
发布订阅模式
Exchanges 交换机--fanout只是将接收到的所有消息广播给它所知道的所有队列
路由模式
直连交换机 Direct exchange
主题模式--基于多个标准进行路由
主题交换机 Topic exchange
bindingKey有两个重要的特殊点:
RPC模式--远程调用模式--一个客户端和一个可以升级(扩展)的RPC服务器
RPC的工作方式
RabbitMQ是消息对列,是一种消息中间件,用来处理客户端的异步消息,服务器将发送的请求放入对列池中,接收端可以根据RabbitMQ配置的转发机制接收服务端发来的消息,RabbitMQ依据指定的转发规则进行消息的转发、缓冲和持久化操作,主要用在多服务器间或单服务器的子系统间进行通信,是分布式系统标准的配置。
生产者发送信息到Exchange,根据binding key规则将消息路由给服务器中的对列,ExchangeType决定了Exchange路由消息的行为。在RabbitMQ中,ExchangeType常用的有direct、Fanout和Topic三种。
异步调用:
只有一个消费者
多路复用是一种思想,多路是指多个客户端连接线路(TCP、Channel),复用是指使用一个线程重复使用,总的来说,就是单线程能同时处理多个请求。要实现这一点,就得改造BIO的连接模式了,BIO是客户端直接连接服务端,NIO采用的是多路复用器 (Selector),相当于客户端的连接不会直接连接服务端,而是连接到多路复用器。
参数含义:
* -queue: 队列名称
* -durable: 队列持久化,true表示RabbitMQ重启后队列仍存在
* -exclusive: 排他,true表示限制仅当前连接可用
* -autoDelete: 当最后一个消费者断开后,是否删除队列
* -arguments: 其他参数
.basicPublish("", "helloworld", null, "Hello world!".getBytes());
参数含义:
* -exchange: 交换机名称,空串表示默认交换机"(AMQP default)",不能用 null
* -routingKey: 对于默认交换机,路由键就是目标队列名称
* -props: 其他参数,例如头信息//设置消息持久化
* -body: 消息内容byte[]数组
spring boot封装的 rabbitmq api 中, 发送的消息默认是持久化消息.
任务封装为消息并将其发送到队列。后台运行的工作进程将获取任务并最终执行任务。当运行多个消费者时,任务将在它们之间分发
当一个消息被消费者接收到并且执行完成后,消费者会发送一个ack (acknowledgment) 给rabbitmq服务器, 成功,消息删除,信道关闭,连接关闭或者TCP链接丢失,重行放入对列,传给其他消费者, rabbitmq只在消费者挂掉时重新分派消息
.basicAck(deliveryTag:,multiple);
deliveryTag:该消息的index
multiple:是否批量.true:将一次性ack所有小于deliveryTag的消息。
.basicConsume("helloworld", false, callback, cancel);
一次只向服务者发送一条消息,没有回执,不发消息,发给其他空闲的位置
//第三个参数设置消息持久化
ch.basicPublish("", "task_queue",
MessageProperties.PERSISTENT_TEXT_PLAIN,
msg.getBytes());
spring boot 的自动配置类会自动发现交换机实例,FanoutExchange 并在 RabbitMQ 服务器中定义该交换机.
@RabbitListener(bindings = @QueueBinding( //这里进行绑定设置
value = @Queue, //这里定义随机队列,默认属性: 随机命名,非持久,排他,自动删除
exchange = @Exchange(name = "logs", declare = "false") //指定 logs 交换机,因为主程序中已经定义,这里不进行定义
))
同一消息传递到多个消费者。
RabbitMQ核心思想:生产者永远不会将任何消息直接发送到队列
类型:direct、topic、header和fanout
direct
交换机
- 主程序中使用
DirectExcnahge
对象封装交换机信息@RabbitListener(bindings = @QueueBinding( // 这里做绑定设置 value = @Queue, // 定义队列, 随机命名,非持久,排他,自动删除 exchange = @Exchange(name = "direct_logs", declare = "false"), // 指定绑定的交换机,主程序中已经定义过队列,这里不进行定义 key = {"error","info","warning"} // 设置绑定键 ))
传特定消息到队列里
ch.queueBind(queueName, "logs", ""); //键绑定
允许根据消息的严重性过滤消息,消息传递到bindingKey与routingKey完全匹配的队列
ch.exchangeDeclare("direct_logs", BuiltinExchangeType.DIRECT);参数2: 交换机类型
- 使用
topic
交换机- 使用特殊的绑定键和路由键规则
@RabbitListener(bindings = @QueueBinding( // 这里做绑定设置 value = @Queue, // 定义队列, 随机命名,非持久,排他,自动删除 exchange = @Exchange(name = "direct_logs", declare = "false"), // 指定绑定的交换机,主程序中已经定义过队列,这里不进行定义 key = {"*。*","info","warning。#"} // 设置绑定键 ))
发送到Topic交换机的消息,它的的routingKey,必须是由点分隔的多个单词。单词可以是任何东西,但通常是与消息相关的一些特性
*
可以通配单个单词。#
可以通配零个或多个单词。client.call() 发送一个RPC请求,并等待接收响应结果
对于RPC请求,客户端发送一条带有两个属性的消息:replyTo,设置为仅为请求创建的匿名独占队列,和correlationId,设置为每个请求的惟一id值。
请求被发送到rpc_queue队列。
RPC工作进程(即:服务器)在队列上等待请求。当一个请求出现时,它执行任务,并使用replyTo字段中的队列将结果发回客户机。
客户机在回应消息队列上等待数据。当消息出现时,它检查correlationId属性。如果匹配请求中的值,则向程序返回该响应数据。