RabbitMQ常见面试题总结

1. 对于MQ的理解

MQ全称为Message Queue,即消息队列。它是典型的:生产者、消费者模型。生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。可以看出消息的生产和消费都是异步的,生产者和消费者只关心消息的发送和接收,没有业务逻辑的侵入,这样就实现了生产者和消费者的解耦。

RabbitMQ是erlang语言开发的并且开源,支持多种语言。对于消息的丢失,消息重复问题等问题都有比较成熟的解决方案。SpringBoot对于RabbitMQ提供了很好的支持,整合十分方便。
它的异步处理、服务解耦、流量控制(削峰)都是我们目前互联网系统所亟需的。

RabbitMQ常见面试题总结



2. 怎么保证MQ的高可用

RabbitMQ 有三种模式:单机模式,普通集群模式,镜像集群模式。

  • 单机模式:就是demo级别的,一般就是你本地启动了玩玩儿的,没人生产用单机模式
  • 普通集群模式:意思就是在多台机器上启动多个RabbitMQ实例,每个机器启动一个。
  • 镜像集群模式:这种模式,才是所谓的RabbitMQ的高可用模式,跟普通集群模式不一样的是,你创建的queue,无论元数据(元数据指RabbitMQ的配置数据)还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。


3. 如何设置消息过期时间

目前有2种方法设置消息的过期时间。
方法一:通过队列属性设置,队列中所有消息都有相同的过期时间。一旦消息过期,就会从队列中抹去
方法二:通过消息本身进行单独设置,每条消息的过期时间可以不同。若消息过期,也不会马上从队列中抹去,因为每条消息是否过期是在即将投递到消费者之前判定的。
如果上面2种方法同时使用,那么消息过期时间以最先到期的时间为准。

方法一:通过队列属性设置

    /**
     * 1、声明交换机
     */
    @Test
    public void decalreExchange() throws Exception {
 
        String exchange = "hello_ttl";
        // 获取到连接
        Connection connection = ConnectionUtil.getConnection();
        // 获取通道
        Channel channel = connection.createChannel();
 
        // 声明exchange,指定类型为direct
        channel.exchangeDeclare(exchange, BuiltinExchangeType.DIRECT,true,false,false,new HashMap<>());
    }





    /**
     * 2、声明队列并绑定到交换机
     */
    @Test
    public void decalreQueueAndBind() throws Exception {
 
        String exchange = "hello_ttl";
        // 获取到连接
        Connection connection = ConnectionUtil.getConnection();
        // 获取通道
        Channel channel = connection.createChannel();
 
        //将队列hello_ttl_c1 绑定到交换机hello_ttl上
        String queueName1 = "hello_ttl_c1";
        Map<String, Object> argss = new HashMap<String , Object>();
        argss.put("x-message-ttl" , 30*1000);//***************设置队列里消息的ttl的时间30s******************
        // 声明队列
        channel.queueDeclare(queueName1, true, false, false, argss);
        // 绑定队列到交换机
        channel.queueBind(queueName1, exchange, "aaa");
    }




    /**
     * 测试队列设置的ttl
     * @throws Exception
     */
    @Test
    public void sendMessage1() throws Exception {
        String exchange = "hello_ttl";
        // 获取到连接
        Connection connection = ConnectionUtil.getConnection();
        // 获取通道
        Channel channel = connection.createChannel();
        // 消息内容
        String message = "Less is more";
        channel.basicPublish(exchange, "aaa", null, message.getBytes());
        log.debug("Producer send message:{}",message);
        channel.close();
        connection.close();
    }

方法二:通过消息本身进行单独设置

    /**
     * 1、声明交换机
     */
    @Test
    public void decalreExchange() throws Exception {
 
        String exchange = "hello_ttl";
        // 获取到连接
        Connection connection = ConnectionUtil.getConnection();
        // 获取通道
        Channel channel = connection.createChannel();
 
        // 声明exchange,指定类型为direct
        channel.exchangeDeclare(exchange, BuiltinExchangeType.DIRECT,true,false,false,new HashMap<>());
    }



    /**
     * 2、声明队列并绑定到交换机
     */
    @Test
    public void decalreQueueAndBind() throws Exception {
 
        String exchange = "hello_ttl";
        // 获取到连接
        Connection connection = ConnectionUtil.getConnection();
        // 获取通道
        Channel channel = connection.createChannel();
 
 
        //队列hello_ttl_c2  这个是为了测试通过发送时设置ttl
        String queueName2 = "hello_ttl_c2";
        // 声明队列
        channel.queueDeclare(queueName2, true, false, false, null);
        // 绑定队列到交换机
        channel.queueBind(queueName2, exchange, "bbb");
 
    }




    /**
     * 测试消息发送时设置ttl
     * @throws Exception
     */
    @Test
    public void sendMessage2() throws Exception {
        String exchange = "hello_ttl";
        // 获取到连接
        Connection connection = ConnectionUtil.getConnection();
        // 获取通道
        Channel channel = connection.createChannel();
        // 消息内容
        String message = "Less is more";
        AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
        builder.deliveryMode(2); //DeliveryMode等于2就说明这个消息是persistent的。1是默认,不是持久的。
        builder.expiration("30000");// *******************设置TTL=30000ms**********************
        AMQP.BasicProperties properties = builder. build() ;

        channel.basicPublish(exchange, "bbb", properties, message.getBytes());
        log.debug("Producer send message:{}",message);
        channel.close();
        connection.close();
    }

4. 消息的持久化是如何实现的

RabbitMQ常见面试题总结

上一篇:JpaRepository 增删改查


下一篇:3_mongoose ODM框架及其安装