RabbitMQ

MQ简介

  • MQ全称为Message Queue,消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。

  • 消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。

  • 同步调用

    • A服务调用B服务,需要等待B服务执行完毕的返回值,A服务才可以继续往下执行
    • 同步调用可以通过REST和RCP完成
      • REST: ribbon、Feign
      • RCP:Dubbo
  • 异步调用

    • A服务调用B服务,而无需等待B服务的执行结果,也就是说在B服务执行的同时A服务可以继续往下执行
    • 通过消息队列实现异步调用

4.1 RabbitMQ介绍

  • RabbitMQ是一个在AMQP基础上完成的,可复用的企业消息系统。他遵循Mozilla Public License开源协议。
  • AMQP,即Advanced Message Queuing Protocol, 一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。Erlang中的实现有 RabbitMQ等。
  • 主要特性:
    • 保证可靠性:使用一些机制来保证可靠性,如持久化、传输确认、发布确认
    • 灵活的路由功能
    • 可伸缩性:支持消息集群,多台RabbitMQ服务器可以组成一个集群
    • 高可用性:RabbitMQ集群中的某个节点出现问题时队列任然可用
    • 支持多种协议
    • 支持多语言客户端
    • 提供良好的管理界面
    • 提供跟踪机制:如果消息出现异常,可以通过跟踪机制分析异常原因
    • 提供插件机制:可通过插件进行多方面扩展

RabbitMQ工作模式

  • 简单模式:
    做某事 的最简单的事情
    在这里插入图片描述
    一个队列只有一个消费者,生产者将消息发送到队列,消费者从队列取出数据

  • 工作模式:
    在工人之间分配任务(竞争的消费者模式)
    在这里插入图片描述
    多个消费者监听同一个队列,多个消费者监听同一个队列,但多个消费者中只有一个消费者会成功的消费消息

  • 发布/订阅模式:
    一次向许多消费者发送消息
    在这里插入图片描述
    一个交换机绑定多个消息队列,每个消息队列有一个消费者监听,消息生产者发送的消息可以被每一个消费者接收

  • 路由模式:
    有选择地接收消息
    在这里插入图片描述
    一个交换机绑定多个消息队列,每个消息队列都由自己唯一的key,每个消息队列有一个消费者监听

    @Service
    public class TestService {
        @Resource
        private AmqpTemplate amqpTemplate;
        public void sendMsg(String msg){
            //1. 发送消息到队列
            amqpTemplate.convertAndSend("queue1",msg);
            //2. 发送消息到交换机(订阅交换机)
            amqpTemplate.convertAndSend("ex1","",msg);
            //3. 发送消息到交换机(路由交换机)
            amqpTemplate.convertAndSend("ex2","a",msg);
        }
    }
    
    @Service
    //@RabbitListener(queues = {"queue1","queue2"})
    @RabbitListener(queues = "queue1")
    public class ReceiveMsgService {
        @RabbitHandler
        public void receiveMsg(String msg){
            System.out.println("接收MSG:"+msg);
        }
    }
    

使用RabbitMQ传递对象

使用序列化对象
使用序列化字节数组
使用JSON字符串传递

消息的可靠性

  • RabbitMQ事务
    当在消息发送过程中添加了事务,处理效率降低几十倍甚至上百倍
channel.txSelect();  //开启事务
try{
    channel.basicPublish("ex4", "k1", null, msg.getBytes());
    System.out.println("发送:" + msg);
    channel.txCommit(); //提交事务
}catch (Exception e){
    channel.txRollback(); //事务回滚
}
  • RabbitMQ消息确认和return机制

消息确认机制:确认消息提供者是否成功发送消息到交换机
return机制:确认消息是否成功的从交换机分发到队列

@Component
public class MsgConfirmAndReturn implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback {

    Logger logger = LoggerFactory.getLogger(MsgConfirmAndReturn.class);

    @Resource
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init(){
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
        //此方法用于监听消息确认结果(消息是否发送到交换机)
        if(b){
            logger.info("-------消息成功发送到交换机");
        }else{
            logger.warn("-------消息发送到交换机失败");
        }
    }

    @Override
    public void returnedMessage(Message message, int i, String s, String s1, String s2) {
        //此方法用于return监听(当交换机分发消息到队列失败时执行)
        logger.warn("~~~~~~~交换机分发消息到队列失败");
    }
}

延迟机制

5.1 延迟队列

  • 延迟队列——消息进入到队列之后,延迟指定的时间才能被消费者消费
  • AMQP协议和RabbitMQ队列本身是不支持延迟队列功能的,但是可以通过TTL(Time To Live)特性模拟延迟队列的功能
  • TTL就是消息的存活时间。RabbitMQ可以分别对队列和消息设置存活时间
    • 在创建队列的时候可以设置队列的存活时间,当消息进入到队列并且在存活时间内没有消费者消费,则此消息就会从当前队列被移除;
    • 创建消息队列没有设置TTL,但是消息设置了TTL,那么当消息的存活时间结束,也会被移除;
    • 当TTL结束之后,我们可以指定将当前队列的消息转存到其他指定的队列

RabbitMQ官方API:rabbitmq.

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页