RabbitMQ

RabbitMQ

一、消息中间件概述

1.什么是消息中间件

在这里插入图片描述
在这里插入图片描述

2.AMQP 和 JMS

MQ是消息通信的模型;实现MQ的大致有两种主流方式:AMQP、JMS。

AMQP

AMQP是一种协议,更准确的说是一种binary wire-level protocol(链接协议)。这是其和JMS的本质差别,AMQP不从API层进行限定,而是直接定义网络交换的数据格式。

JMS

JMS即Java消息服务(JavaMessage Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

AMQP 与 JMS 区别

在这里插入图片描述

3.消息队列产品

在这里插入图片描述

4.RabbitMQ

在这里插入图片描述

二、安装及配置RabbitMQ

1.安装依赖环境

在这里插入图片描述

2.安装Erlang

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.安装RabbitMQ

在这里插入图片描述

4.开启管理界面及配置

在这里插入图片描述

5.启动

在这里插入图片描述

6.配置虚拟主机及用户

用户角色

在这里插入图片描述
在这里插入图片描述

Virtual Hosts配置

在这里插入图片描述

创建Virtual Hosts

在这里插入图片描述

设置Virtual Hosts权限

在这里插入图片描述

三、RabbitMQ入门

1.搭建示例工程

创建工程

在这里插入图片描述

添加依赖

在这里插入图片描述

2.编写生产者

编写消息生产者com.itheima.rabbitmq.simple.Producer

package com.itheima.rabbitmq.simple;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class Producer {
  static final String QUEUE_NAME = "simple_queue";
  public static void main(String[] args) throws Exception {
    //创建连接工厂
    ConnectionFactory connectionFactory = new ConnectionFactory();
    //主机地址;默认为 localhost
    connectionFactory.setHost("localhost");
    //连接端口;默认为 5672
    connectionFactory.setPort(5672);
    //虚拟主机名称;默认为 /
    connectionFactory.setVirtualHost("/itcast");
    //连接用户名;默认为guest
    connectionFactory.setUsername("heima");
    //连接密码;默认为guest
    connectionFactory.setPassword("heima");
    //创建连接
    Connection connection = connectionFactory.newConnection();
    // 创建频道
    Channel channel = connection.createChannel();
    // 声明(创建)队列
    /**
    * 参数1:队列名称
    * 参数2:是否定义持久化队列
    * 参数3:是否独占本次连接
    * 参数4:是否在不使用的时候自动删除队列
    * 参数5:队列其它参数
    */
    channel.queueDeclare(QUEUE_NAME, true, false, false, null);
    // 要发送的信息
    String message = "你好;小兔子!";
    /**
    * 参数1:交换机名称,如果没有指定则使用默认Default Exchage
    * 参数2:路由key,简单模式可以传递队列名称
    * 参数3:消息其它属性
    * 参数4:消息内容
    */
    channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
    System.out.println("已发送消息:" + message);
    // 关闭资源
    channel.close();
    connection.close();
 }
}

在这里插入图片描述

3.编写消费者

抽取创建connection的工具类com.itheima.rabbitmq.util.ConnectionUtil;

package com.itheima.rabbitmq.util;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class ConnectionUtil {
  public static Connection getConnection() throws Exception {
    //创建连接工厂
    ConnectionFactory connectionFactory = new ConnectionFactory();
    //主机地址;默认为 localhost
    connectionFactory.setHost("localhost");
    //连接端口;默认为 5672
    connectionFactory.setPort(5672);
    //虚拟主机名称;默认为 /
    connectionFactory.setVirtualHost("/itcast");
    //连接用户名;默认为guest
    connectionFactory.setUsername("heima");
    //连接密码;默认为guest
    connectionFactory.setPassword("heima");
    //创建连接
    return connectionFactory.newConnection();
 }
}

编写消息的消费者com.itheima.rabbitmq.simple.Consumer

package com.itheima.rabbitmq.simple;
import com.itheima.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumer {
  public static void main(String[] args) throws Exception {
    Connection connection = ConnectionUtil.getConnection();
    // 创建频道
    Channel channel = connection.createChannel();
    // 声明(创建)队列
    /**
    * 参数1:队列名称
    * 参数2:是否定义持久化队列
    * 参数3:是否独占本次连接
    * 参数4:是否在不使用的时候自动删除队列
    * 参数5:队列其它参数
    */
    channel.queueDeclare(Producer.QUEUE_NAME, true, false, false, null);
    //创建消费者;并设置消息处理
    DefaultConsumer consumer = new DefaultConsumer(channel){
      @Override
            /**
      * consumerTag 消息者标签,在channel.basicConsume时候可以指定
      * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消
息失败后是否需要重新发送)
      * properties 属性信息
      * body 消息
      */
      public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
        //路由key
        System.out.println("路由key为:" + envelope.getRoutingKey());
        //交换机
        System.out.println("交换机为:" + envelope.getExchange());
        //消息id
        System.out.println("消息id为:" + envelope.getDeliveryTag());
        //收到的消息
        System.out.println("接收到的消息为:" + new String(body, "utf-8"));
     }
   };
    //监听消息
    /**
    * 参数1:队列名称
    * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,
设置为false则需要手动确认
    * 参数3:消息接收到后回调
    */
    channel.basicConsume(Producer.QUEUE_NAME, true, consumer);
    //不关闭资源,应该一直监听消息
    //channel.close();
    //connection.close();
 }
}

4.小结

在这里插入图片描述

四、AMQP

1.相关概念介绍

在这里插入图片描述

2.RabbitMQ运转流程

在这里插入图片描述
在这里插入图片描述

3.生产者流转过程说明

在这里插入图片描述

4. 消费者流转过程说明

在这里插入图片描述

五、RabbitMQ工作模式

1.Work queues工作队列模式

模式说明

在这里插入图片描述

代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

测试

在这里插入图片描述
在这里插入图片描述

小结

在一个队列中如果有多个消费者,那么消费者之间对于同一个消息的关系是竞争的关系。

2.订阅模式类型

在这里插入图片描述
在这里插入图片描述

3.Publish/Subscribe发布与订阅模式

模式说明

在这里插入图片描述

代码

生产者

package com.itheima.rabbitmq.ps;
import com.itheima.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
/**
* 发布与订阅使用的交换机类型为:fanout
*/
public class Producer {
  //交换机名称
  static final String FANOUT_EXCHAGE = "fanout_exchange";
  //队列名称
  static final String FANOUT_QUEUE_1 = "fanout_queue_1";
  //队列名称
  static final String FANOUT_QUEUE_2 = "fanout_queue_2";
  public static void main(String[] args) throws Exception {
    //创建连接
    Connection connection = ConnectionUtil.getConnection();
    // 创建频道
    Channel channel = connection.createChannel();
    /**
    * 声明交换机
    * 参数1:交换机名称
    * 参数2:交换机类型,fanout、topic、direct、headers
    */
    channel.exchangeDeclare(FANOUT_EXCHAGE, BuiltinExchangeType.FANOUT);
    // 声明(创建)队列
    /**
    * 参数1:队列名称
    * 参数2:是否定义持久化队列
    * 参数3:是否独占本次连接
    * 参数4:是否在不使用的时候自动删除队列
    * 参数5:队列其它参数
    */
    channel.queueDeclare(FANOUT_QUEUE_1, true, false, false, null);
    channel.queueDeclare(FANOUT_QUEUE_2, true, false, false, null);
    //队列绑定交换机
    channel.queueBind(FANOUT_QUEUE_1, FANOUT_EXCHAGE, "");
    channel.queueBind(FANOUT_QUEUE_2, FANOUT_EXCHAGE, "");
    for (int i = 1; i <= 10; i++) {
      // 发送信息
      String message = "你好;小兔子!发布订阅模式--" + i;
      /**
      * 参数1:交换机名称,如果没有指定则使用默认Default Exchage
      * 参数2:路由key,简单模式可以传递队列名称
      * 参数3:消息其它属性
      * 参数4:消息内容
      */
      channel.basicPublish(FANOUT_EXCHAGE, "", null, message.getBytes());
      System.out.println("已发送消息:" + message);
   }
    // 关闭资源
    channel.close();
        connection.close();
 }
}

消费者1

package com.itheima.rabbitmq.ps;
import com.itheima.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumer1 {
  public static void main(String[] args) throws Exception {
    Connection connection = ConnectionUtil.getConnection();
    // 创建频道
    Channel channel = connection.createChannel();
    //声明交换机
    channel.exchangeDeclare(Producer.FANOUT_EXCHAGE, BuiltinExchangeType.FANOUT);
    // 声明(创建)队列
    /**
    * 参数1:队列名称
    * 参数2:是否定义持久化队列
    * 参数3:是否独占本次连接
    * 参数4:是否在不使用的时候自动删除队列
    * 参数5:队列其它参数
    */
    channel.queueDeclare(Producer.FANOUT_QUEUE_1, true, false, false, null);
    //队列绑定交换机
    channel.queueBind(Producer.FANOUT_QUEUE_1, Producer.FANOUT_EXCHAGE, "");
    //创建消费者;并设置消息处理
    DefaultConsumer consumer = new DefaultConsumer(channel){
      @Override
      /**
      * consumerTag 消息者标签,在channel.basicConsume时候可以指定
      * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消
息失败后是否需要重新发送)
      * properties 属性信息
      * body 消息
      */
      public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
        //路由key
        System.out.println("路由key为:" + envelope.getRoutingKey());
                //交换机
        System.out.println("交换机为:" + envelope.getExchange());
        //消息id
        System.out.println("消息id为:" + envelope.getDeliveryTag());
        //收到的消息
        System.out.println("消费者1-接收到的消息为:" + new String(body, "utf-8"));
     }
   };
    //监听消息
    /**
    * 参数1:队列名称
    * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,
设置为false则需要手动确认
    * 参数3:消息接收到后回调
    */
    channel.basicConsume(Producer.FANOUT_QUEUE_1, true, consumer);
 }
}

消费者2

package com.itheima.rabbitmq.ps;
import com.itheima.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumer2 {
  public static void main(String[] args) throws Exception {
    Connection connection = ConnectionUtil.getConnection();
    // 创建频道
    Channel channel = connection.createChannel();
    //声明交换机
    channel.exchangeDeclare(Producer.FANOUT_EXCHAGE, BuiltinExchangeType.FANOUT);
    // 声明(创建)队列
    /**
    * 参数1:队列名称
    * 参数2:是否定义持久化队列
    * 参数3:是否独占本次连接
    * 参数4:是否在不使用的时候自动删除队列
    * 参数5:队列其它参数
    */
    channel.queueDeclare(Producer.FANOUT_QUEUE_2, true, false, false, null);
    //队列绑定交换机
    channel.queueBind(Producer.FANOUT_QUEUE_2, Producer.FANOUT_EXCHAGE, "");
        //创建消费者;并设置消息处理
    DefaultConsumer consumer = new DefaultConsumer(channel){
      @Override
      /**
      * consumerTag 消息者标签,在channel.basicConsume时候可以指定
      * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消
息失败后是否需要重新发送)
      * properties 属性信息
      * body 消息
      */
      public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
        //路由key
        System.out.println("路由key为:" + envelope.getRoutingKey());
        //交换机
        System.out.println("交换机为:" + envelope.getExchange());
        //消息id
        System.out.println("消息id为:" + envelope.getDeliveryTag());
        //收到的消息
        System.out.println("消费者2-接收到的消息为:" + new String(body, "utf-8"));
     }
   };
    //监听消息
    /**
    * 参数1:队列名称
    * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,
设置为false则需要手动确认
    * 参数3:消息接收到后回调
    */
    channel.basicConsume(Producer.FANOUT_QUEUE_2, true, consumer);
 }
}
测试

在这里插入图片描述
在这里插入图片描述

小结

在这里插入图片描述

4.Routing路由模式

模式说明

在这里插入图片描述
在这里插入图片描述

代码

在编码上与 Publish/Subscribe发布与订阅模式 的区别是交换机的类型为:Direct,还有队列绑定交换机的时候需要指定routing key。
生产者

package com.itheima.rabbitmq.routing;
import com.itheima.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
/**
* 路由模式的交换机类型为:direct
*/
public class Producer {
  //交换机名称
  static final String DIRECT_EXCHAGE = "direct_exchange";
  //队列名称
  static final String DIRECT_QUEUE_INSERT = "direct_queue_insert";
   //队列名称
  static final String DIRECT_QUEUE_UPDATE = "direct_queue_update";
  public static void main(String[] args) throws Exception {
    //创建连接
    Connection connection = ConnectionUtil.getConnection();
    // 创建频道
    Channel channel = connection.createChannel();
    /**
    * 声明交换机
    * 参数1:交换机名称
    * 参数2:交换机类型,fanout、topic、direct、headers
    */
    channel.exchangeDeclare(DIRECT_EXCHAGE, BuiltinExchangeType.DIRECT);
    // 声明(创建)队列
    /**
    * 参数1:队列名称
    * 参数2:是否定义持久化队列
    * 参数3:是否独占本次连接
    * 参数4:是否在不使用的时候自动删除队列
    * 参数5:队列其它参数
    */
    channel.queueDeclare(DIRECT_QUEUE_INSERT, true, false, false, null);
    channel.queueDeclare(DIRECT_QUEUE_UPDATE, true, false, false, null);
    //队列绑定交换机
    channel.queueBind(DIRECT_QUEUE_INSERT, DIRECT_EXCHAGE, "insert");
    channel.queueBind(DIRECT_QUEUE_UPDATE, DIRECT_EXCHAGE, "update");
    // 发送信息
    String message = "新增了商品。路由模式;routing key 为 insert " ;
    /**
    * 参数1:交换机名称,如果没有指定则使用默认Default Exchage
    * 参数2:路由key,简单模式可以传递队列名称
    * 参数3:消息其它属性
    * 参数4:消息内容
    */
    channel.basicPublish(DIRECT_EXCHAGE, "insert", null, message.getBytes());
    System.out.println("已发送消息:" + message);
    // 发送信息
    message = "修改了商品。路由模式;routing key 为 update" ;
    /**
    * 参数1:交换机名称,如果没有指定则使用默认Default Exchage
    * 参数2:路由key,简单模式可以传递队列名称
    * 参数3:消息其它属性
    * 参数4:消息内容
    */
    channel.basicPublish(DIRECT_EXCHAGE, "update", null, message.getBytes()); 
    System.out.println("已发送消息:" + message);
    // 关闭资源
    channel.close();
    connection.close();
 }
}

消费者1

package com.itheima.rabbitmq.routing;
import com.itheima.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumer1 {
  public static void main(String[] args) throws Exception {
    Connection connection = ConnectionUtil.getConnection();
    // 创建频道
    Channel channel = connection.createChannel();
    //声明交换机
    channel.exchangeDeclare(Producer.DIRECT_EXCHAGE, BuiltinExchangeType.DIRECT);
    // 声明(创建)队列
    /**
    * 参数1:队列名称
    * 参数2:是否定义持久化队列
    * 参数3:是否独占本次连接
    * 参数4:是否在不使用的时候自动删除队列
    * 参数5:队列其它参数
    */
    channel.queueDeclare(Producer.DIRECT_QUEUE_INSERT, true, false, false, null);
    //队列绑定交换机
    channel.queueBind(Producer.DIRECT_QUEUE_INSERT, Producer.DIRECT_EXCHAGE, "insert");
    //创建消费者;并设置消息处理
    DefaultConsumer consumer = new DefaultConsumer(channel){
      @Override
      /**
      * consumerTag 消息者标签,在channel.basicConsume时候可以指定
      * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消
息失败后是否需要重新发送)
      * properties 属性信息
      * body 消息
      */
            public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
        //路由key
        System.out.println("路由key为:" + envelope.getRoutingKey());
        //交换机
        System.out.println("交换机为:" + envelope.getExchange());
        //消息id
        System.out.println("消息id为:" + envelope.getDeliveryTag());
        //收到的消息
        System.out.println("消费者1-接收到的消息为:" + new String(body, "utf-8"));
     }
   };
    //监听消息
    /**
    * 参数1:队列名称
    * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,
设置为false则需要手动确认
    * 参数3:消息接收到后回调
    */
    channel.basicConsume(Producer.DIRECT_QUEUE_INSERT, true, consumer);
 }
}

消费者2

package com.itheima.rabbitmq.routing;
import com.itheima.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumer2 {
  public static void main(String[] args) throws Exception {
    Connection connection = ConnectionUtil.getConnection();
    // 创建频道
    Channel channel = connection.createChannel();
    //声明交换机
    channel.exchangeDeclare(Producer.DIRECT_EXCHAGE, BuiltinExchangeType.DIRECT);
    // 声明(创建)队列
    /**
    * 参数1:队列名称
    * 参数2:是否定义持久化队列
    * 参数3:是否独占本次连接
    * 参数4:是否在不使用的时候自动删除队列
    * 参数5:队列其它参数
    */
    channel.queueDeclare(Producer.DIRECT_QUEUE_UPDATE, true, false, false, null);
        //队列绑定交换机
    channel.queueBind(Producer.DIRECT_QUEUE_UPDATE, Producer.DIRECT_EXCHAGE, "update");
    //创建消费者;并设置消息处理
    DefaultConsumer consumer = new DefaultConsumer(channel){
      @Override
      /**
      * consumerTag 消息者标签,在channel.basicConsume时候可以指定
      * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消
息失败后是否需要重新发送)
      * properties 属性信息
      * body 消息
      */
      public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
        //路由key
        System.out.println("路由key为:" + envelope.getRoutingKey());
        //交换机
        System.out.println("交换机为:" + envelope.getExchange());
        //消息id
        System.out.println("消息id为:" + envelope.getDeliveryTag());
        //收到的消息
        System.out.println("消费者2-接收到的消息为:" + new String(body, "utf-8"));
     }
   };
    //监听消息
    /**
    * 参数1:队列名称
    * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,
设置为false则需要手动确认
    * 参数3:消息接收到后回调
    */
    channel.basicConsume(Producer.DIRECT_QUEUE_UPDATE, true, consumer);
 }
}
测试

在这里插入图片描述
在这里插入图片描述

小结

Routing模式要求队列在绑定交换机时要指定routing key,消息会转发到符合routing key的队列。

5.Topics通配符模式

模式说明

在这里插入图片描述
在这里插入图片描述

代码

生产者
使用topic类型的Exchange,发送消息的routing key有3种: item.insert 、 item.update 、 item.delete:

package com.itheima.rabbitmq.topic;
import com.itheima.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
/**
* 通配符Topic的交换机类型为:topic
*/
public class Producer {
  //交换机名称
  static final String TOPIC_EXCHAGE = "topic_exchange";
  //队列名称
  static final String TOPIC_QUEUE_1 = "topic_queue_1";
  //队列名称
  static final String TOPIC_QUEUE_2 = "topic_queue_2";
  public static void main(String[] args) throws Exception {
    //创建连接
    Connection connection = ConnectionUtil.getConnection();
    // 创建频道
    Channel channel = connection.createChannel();
    /**
    * 声明交换机
    * 参数1:交换机名称
    * 参数2:交换机类型,fanout、topic、topic、headers
    */
    channel.exchangeDeclare(TOPIC_EXCHAGE, BuiltinExchangeType.TOPIC);
    // 发送信息
    String message = "新增了商品。Topic模式;routing key 为 item.insert " ;
    channel.basicPublish(TOPIC_EXCHAGE, "item.insert", null, message.getBytes());
    System.out.println("已发送消息:" + message);
    // 发送信息
    message = "修改了商品。Topic模式;routing key 为 item.update" ;
    channel.basicPublish(TOPIC_EXCHAGE, "item.update", null, message.getBytes());
    System.out.println("已发送消息:" + message);
    // 发送信息
    message = "删除了商品。Topic模式;routing key 为 item.delete" ;
    channel.basicPublish(TOPIC_EXCHAGE, "item.delete", null, message.getBytes());
    System.out.println("已发送消息:" + message);
    // 关闭资源
    channel.close();
    connection.close();
     }
}

消费者1
接收两种类型的消息:更新商品和删除商品

package com.itheima.rabbitmq.topic;
import com.itheima.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumer1 {
  public static void main(String[] args) throws Exception {
    Connection connection = ConnectionUtil.getConnection();
    // 创建频道
    Channel channel = connection.createChannel();
    //声明交换机
    channel.exchangeDeclare(Producer.TOPIC_EXCHAGE, BuiltinExchangeType.TOPIC);
    // 声明(创建)队列
    /**
    * 参数1:队列名称
    * 参数2:是否定义持久化队列
    * 参数3:是否独占本次连接
    * 参数4:是否在不使用的时候自动删除队列
    * 参数5:队列其它参数
    */
    channel.queueDeclare(Producer.TOPIC_QUEUE_1, true, false, false, null);
    //队列绑定交换机
    channel.queueBind(Producer.TOPIC_QUEUE_1, Producer.TOPIC_EXCHAGE, "item.update");
    channel.queueBind(Producer.TOPIC_QUEUE_1, Producer.TOPIC_EXCHAGE, "item.delete");
    //创建消费者;并设置消息处理
    DefaultConsumer consumer = new DefaultConsumer(channel){
      @Override
      /**
      * consumerTag 消息者标签,在channel.basicConsume时候可以指定
      * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消
息失败后是否需要重新发送)
      * properties 属性信息
      * body 消息
      */
      public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
        //路由key
                System.out.println("路由key为:" + envelope.getRoutingKey());
        //交换机
        System.out.println("交换机为:" + envelope.getExchange());
        //消息id
        System.out.println("消息id为:" + envelope.getDeliveryTag());
        //收到的消息
        System.out.println("消费者1-接收到的消息为:" + new String(body, "utf-8"));
     }
   };
    //监听消息
    /**
    * 参数1:队列名称
    * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,
设置为false则需要手动确认
    * 参数3:消息接收到后回调
    */
    channel.basicConsume(Producer.TOPIC_QUEUE_1, true, consumer);
 }
}

消费者2
接收所有类型的消息:新增商品,更新商品和删除商品。

package com.itheima.rabbitmq.topic;
import com.itheima.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumer2 {
  public static void main(String[] args) throws Exception {
    Connection connection = ConnectionUtil.getConnection();
    // 创建频道
    Channel channel = connection.createChannel();
    //声明交换机
    channel.exchangeDeclare(Producer.TOPIC_EXCHAGE, BuiltinExchangeType.TOPIC);
    // 声明(创建)队列
    /**
    * 参数1:队列名称
    * 参数2:是否定义持久化队列
    * 参数3:是否独占本次连接
    * 参数4:是否在不使用的时候自动删除队列
    * 参数5:队列其它参数
    */
    channel.queueDeclare(Producer.TOPIC_QUEUE_2, true, false, false, null);
        //队列绑定交换机
    channel.queueBind(Producer.TOPIC_QUEUE_2, Producer.TOPIC_EXCHAGE, "item.*");
    //创建消费者;并设置消息处理
    DefaultConsumer consumer = new DefaultConsumer(channel){
      @Override
      /**
      * consumerTag 消息者标签,在channel.basicConsume时候可以指定
      * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消
息失败后是否需要重新发送)
      * properties 属性信息
      * body 消息
      */
      public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
        //路由key
        System.out.println("路由key为:" + envelope.getRoutingKey());
        //交换机
        System.out.println("交换机为:" + envelope.getExchange());
        //消息id
        System.out.println("消息id为:" + envelope.getDeliveryTag());
        //收到的消息
        System.out.println("消费者2-接收到的消息为:" + new String(body, "utf-8"));
     }
   };
    //监听消息
    /**
    * 参数1:队列名称
    * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,
设置为false则需要手动确认
    * 参数3:消息接收到后回调
    */
    channel.basicConsume(Producer.TOPIC_QUEUE_2, true, consumer);
 }
}
测试

在这里插入图片描述
在这里插入图片描述

小结

Topic主题模式可以实现 Publish/Subscribe发布与订阅模式 和 Routing路由模式 的功能;只是Topic在配置routing key 的时候可以使用通配符,显得更加灵活。

6.模式总结

在这里插入图片描述

六、Spring 整合RabbitMQ

1.搭建生产者工程

创建工程

在这里插入图片描述

添加依赖

在这里插入图片描述
在这里插入图片描述

配置整合

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:rabbit="http://www.springframework.org/schema/rabbit"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context
   https://www.springframework.org/schema/context/spring-context.xsd
   http://www.springframework.org/schema/rabbit
   http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
  <!--加载配置文件-->
  <context:property-placeholder location="classpath:properties/rabbitmq.properties"/>
  <!-- 定义rabbitmq connectionFactory -->
  <rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}"
               port="${rabbitmq.port}"
               username="${rabbitmq.username}"
               password="${rabbitmq.password}"
               virtual-host="${rabbitmq.virtual-host}"/>
  <!--定义管理交换机、队列-->
  <rabbit:admin connection-factory="connectionFactory"/>
  <!--定义持久化队列,不存在则自动创建;不绑定到交换机则绑定到默认交换机
  默认交换机类型为direct,名字为:"",路由键为队列的名称
    -->
  <rabbit:queue id="spring_queue" name="spring_queue" auto-declare="true"/>
  <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~广播;所有队列都能收到消息~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
  <!--定义广播交换机中的持久化队列,不存在则自动创建-->
  <rabbit:queue id="spring_fanout_queue_1" name="spring_fanout_queue_1" auto-
declare="true"/>
  <!--定义广播交换机中的持久化队列,不存在则自动创建-->
  <rabbit:queue id="spring_fanout_queue_2" name="spring_fanout_queue_2" auto-
declare="true"/>
  <!--定义广播类型交换机;并绑定上述两个队列-->
  <rabbit:fanout-exchange id="spring_fanout_exchange" name="spring_fanout_exchange" auto-
declare="true">
    <rabbit:bindings>
      <rabbit:binding queue="spring_fanout_queue_1"/>
      <rabbit:binding queue="spring_fanout_queue_2"/>
    </rabbit:bindings>
  </rabbit:fanout-exchange>
  <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~通配符;*匹配一个单词,#匹配多个单词
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
  <!--定义广播交换机中的持久化队列,不存在则自动创建-->
  <rabbit:queue id="spring_topic_queue_star" name="spring_topic_queue_star" auto-
declare="true"/>
  <!--定义广播交换机中的持久化队列,不存在则自动创建-->
  <rabbit:queue id="spring_topic_queue_well" name="spring_topic_queue_well" auto-
declare="true"/>
  <!--定义广播交换机中的持久化队列,不存在则自动创建-->
  <rabbit:queue id="spring_topic_queue_well2" name="spring_topic_queue_well2" auto-
declare="true"/>
  <rabbit:topic-exchange id="spring_topic_exchange" name="spring_topic_exchange" auto-
declare="true">
    <rabbit:bindings>
      <rabbit:binding pattern="heima.*" queue="spring_topic_queue_star"/>
      <rabbit:binding pattern="heima.#" queue="spring_topic_queue_well"/>
      <rabbit:binding pattern="itcast.#" queue="spring_topic_queue_well2"/>
    </rabbit:bindings>
  </rabbit:topic-exchange>
  <!--定义rabbitTemplate对象操作可以在代码中方便发送消息-->
  <rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"/>
</beans>
发送消息

创建测试文件 spring-rabbitmq-producer\src\test\java\com\itheima\rabbitmq\ProducerTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/spring-rabbitmq.xml")
public class ProducerTest {
  @Autowired
  private RabbitTemplate rabbitTemplate;
  /**
  * 只发队列消息
  * 默认交换机类型为 direct
  * 交换机的名称为空,路由键为队列的名称
  */
  @Test
  public void queueTest(){
    //路由键与队列同名
    rabbitTemplate.convertAndSend("spring_queue", "只发队列spring_queue的消息。");
 }
  /**
  * 发送广播
  * 交换机类型为 fanout
  * 绑定到该交换机的所有队列都能够收到消息
  */
  @Test
  public void fanoutTest(){
    /**
    * 参数1:交换机名称
    * 参数2:路由键名(广播设置为空)
    * 参数3:发送的消息内容
    */
    rabbitTemplate.convertAndSend("spring_fanout_exchange", "", "发送到
spring_fanout_exchange交换机的广播消息");
 }
  /**
  * 通配符
  * 交换机类型为 topic
  * 匹配路由键的通配符,*表示一个单词,#表示多个单词
  * 绑定到该交换机的匹配队列能够收到对应消息
  */
  @Test
  public void topicTest(){
    /**
    * 参数1:交换机名称
    * 参数2:路由键名
    * 参数3:发送的消息内容
    */
    rabbitTemplate.convertAndSend("spring_topic_exchange", "heima.bj", "发送到
spring_topic_exchange交换机heima.bj的消息");
    rabbitTemplate.convertAndSend("spring_topic_exchange", "heima.bj.1", "发送到
spring_topic_exchange交换机heima.bj.1的消息");
    rabbitTemplate.convertAndSend("spring_topic_exchange", "heima.bj.2", "发送到
spring_topic_exchange交换机heima.bj.2的消息");
    rabbitTemplate.convertAndSend("spring_topic_exchange", "itcast.cn", "发送到
spring_topic_exchange交换机itcast.cn的消息");
 }
}

2.搭建消费者工程

创建工程

在这里插入图片描述

添加依赖

在这里插入图片描述
在这里插入图片描述

配置整合

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

消息监听器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

七、Spring Boot整合RabbitMQ

1.简介

在这里插入图片描述

2.搭建生产者工程

创建工程

在这里插入图片描述

添加依赖

在这里插入图片描述
在这里插入图片描述

启动类

在这里插入图片描述

配置RabbitMQ

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.搭建消费者工程

创建工程

在这里插入图片描述

添加依赖

在这里插入图片描述

启动类

在这里插入图片描述

配置RabbitMQ

在这里插入图片描述

消息监听处理类

在这里插入图片描述

4.测试

在这里插入图片描述
在这里插入图片描述

八、RabbitMQ 高级特性

1.消息可靠性投递

在这里插入图片描述

confirm确认模式代码实现

在这里插入图片描述

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.7.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.amqp</groupId>
        <artifactId>spring-rabbit</artifactId>
        <version>2.1.8.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.1.7.RELEASE</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                 http://www.springframework.org/schema/beans/spring-beans.xsd
                 http://www.springframework.org/schema/context
                 https://www.springframework.org/schema/context/spring-context.xsd
                 http://www.springframework.org/schema/rabbit
                 http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
    <!--加载配置文件-->
    <context:property-placeholder location="classpath:rabbitmq.properties"/>

    <!-- 定义rabbitmq connectionFactory  1. 设置  publisher-confirms="true" -->
    <rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}"
                               port="${rabbitmq.port}"
                               username="${rabbitmq.username}"
                               password="${rabbitmq.password}"
                               virtual-host="${rabbitmq.virtual-host}"
                               
                               publisher-confirms="true"
                               />
    <!--定义管理交换机、队列-->
    <rabbit:admin connection-factory="connectionFactory"/>

    <!--定义rabbitTemplate对象操作可以在代码中方便发送消息-->
    <rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"/>

    <!--2. 消息可靠性投递(生产端)-->
   <rabbit:queue id="test_queue_confirm" name="test_queue_confirm"></rabbit:queue>
    <rabbit:direct-exchange name="test_exchange_confirm">
        <rabbit:bindings>
            <rabbit:binding queue="test_queue_confirm" key="confirm">			               </rabbit:binding>
        </rabbit:bindings>
    </rabbit:direct-exchange>
    
</beans>

在这里插入图片描述

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-rabbitmq-producer.xml")
public class ProducerTest {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 确认模式:
     * 步骤:
     * 1. 确认模式开启:ConnectionFactory中开启publisher-confirms="true"
     * 2. 在rabbitTemplate定义ConfirmCallBack回调函数
     */
    @Test
    public void testConfirm() {

        //2. 定义回调 **
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             *
             * @param correlationData 相关配置信息
             * @param ack   exchange交换机 是否成功收到了消息。true 成功,false代表失败
             * @param cause 失败原因
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("confirm方法被执行了....");

                if (ack) {
                    //接收成功
                    System.out.println("接收成功消息" + cause);
                } else {
                    //接收失败
                    System.out.println("接收失败消息" + cause);
                    //做一些处理,让消息再次发送。
                }
            }
        });

        //3. 发送消息
        rabbitTemplate.convertAndSend("test_exchange_confirm111", "confirm", "message confirm....");
    }
}

在这里插入图片描述

return退回模式代码实现

在这里插入图片描述

/**
 * 步骤:
 * 1. 开启回退模式:publisher-returns="true"
 * 2. 设置ReturnCallBack
 * 3. 设置Exchange处理消息的模式:
 *  1. 如果消息没有路由到Queue,则丢弃消息(默认)
 *  2. 如果消息没有路由到Queue,返回给消息发送方ReturnCallBack
 */

@Test
public void testReturn() {

    //设置交换机处理失败消息的模式
    rabbitTemplate.setMandatory(true);

    //2.设置ReturnCallBack
    rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
        /**
         *
         * @param message   消息对象
         * @param replyCode 错误码
         * @param replyText 错误信息
         * @param exchange  交换机
         * @param routingKey 路由键
         */
        @Override
        public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
            System.out.println("return 执行了....");

            System.out.println(message);
            System.out.println(replyCode);
            System.out.println(replyText);
            System.out.println(exchange);
            System.out.println(routingKey);

            //处理
        }
    });


    //3. 发送消息   
    rabbitTemplate.convertAndSend("test_exchange_confirm", "confirm", "message confirm....");
}

设置 routingKey 为一个不符合规则的key,观察控制台打印结果。

小结

在这里插入图片描述

2.Consumer ACK

在这里插入图片描述

代码实现

在这里插入图片描述

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.amqp</groupId>
        <artifactId>spring-rabbit</artifactId>
        <version>2.1.8.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.1.7.RELEASE</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans.xsd
             http://www.springframework.org/schema/context
             https://www.springframework.org/schema/context/spring-context.xsd
             http://www.springframework.org/schema/rabbit
             http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
    <!--加载配置文件-->
    <context:property-placeholder location="classpath:rabbitmq.properties"/>

    <!-- 定义rabbitmq connectionFactory -->
    <rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}"
                               port="${rabbitmq.port}"
                               username="${rabbitmq.username}"
                               password="${rabbitmq.password}"
                               virtual-host="${rabbitmq.virtual-host}"/>


    <context:component-scan base-package="com.itheima.listener" />

    <!--定义监听器容器  添加  acknowledge="manual" 手动-->
    <rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual" >
        <rabbit:listener ref="ackListener" queue-names="test_queue_confirm">	
        </rabbit:listener>
    </rabbit:listener-container>

</beans>

在这里插入图片描述

package com.itheima.listener;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * Consumer ACK机制:
 *  1. 设置手动签收。acknowledge="manual"
 *  2. 让监听器类实现ChannelAwareMessageListener接口
 *  3. 如果消息成功处理,则调用channel的 basicAck()签收
 *  4. 如果消息处理失败,则调用channel的basicNack()拒绝签收,broker重新发送给consumer
 */
@Component
public class AckListener implements ChannelAwareMessageListener {

    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();

        try {
            //1.接收转换消息
            System.out.println(new String(message.getBody()));

            //2. 处理业务逻辑
            System.out.println("处理业务逻辑...");
            int i = 3/0;//出现错误
            //3. 手动签收
            channel.basicAck(deliveryTag,true);
        } catch (Exception e) {
            //e.printStackTrace();

            //4.拒绝签收
            /*
            第三个参数:requeue:重回队列。如果设置为true,则消息重新回到queue,broker会重新发送该消息给消费端
             */
            channel.basicNack(deliveryTag,true,true);
            // 了解
            //channel.basicReject(deliveryTag,true);
        }
    }
}

在这里插入图片描述

小结

在这里插入图片描述

3.消费端限流

在这里插入图片描述

代码实现

在这里插入图片描述

小结

在这里插入图片描述

4.TTL

在这里插入图片描述

代码实现
设置队列的过期时间

在这里插入图片描述

设置单个消息的过期时间

编写代码测试,并且设置队列的过期时间为100s, 单个消息的过期时间为5s

@Test
public void testTtl() {

  // 消息后处理对象,设置一些消息的参数信息
    MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {

        @Override
        public Message postProcessMessage(Message message) throws AmqpException {
            //1.设置message的信息
            message.getMessageProperties().setExpiration("5000");//消息的过期时间
            //2.返回该消息
            return message;
        }
    };

    //消息单独过期
    rabbitTemplate.convertAndSend("test_exchange_ttl", 
                                  "ttl.hehe", "message ttl....",messagePostProcessor);

    for (int i = 0; i < 10; i++) {
        if(i == 5){
            //消息单独过期
            rabbitTemplate.convertAndSend("test_exchange_ttl", "ttl.hehe", "message ttl....",messagePostProcessor);
        }else{
            //不过期的消息
            rabbitTemplate.convertAndSend("test_exchange_ttl", "ttl.hehe", "message ttl....");

        }

    }
}

在这里插入图片描述

5.死信队列

在这里插入图片描述
在这里插入图片描述

代码实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

小结

在这里插入图片描述

6.延迟队列

在这里插入图片描述
在这里插入图片描述

代码实现

在这里插入图片描述
在这里插入图片描述

小结

在这里插入图片描述

7.日志与监控

RabbitMQ日志

在这里插入图片描述
在这里插入图片描述

web管控台监控

在这里插入图片描述
在这里插入图片描述

8.消息追踪

在这里插入图片描述

消息追踪-Firehose

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

消息追踪-rabbitmq_tracing

在这里插入图片描述
在这里插入图片描述

九、RabbitMQ应用问题

1.消息可靠性保障

在这里插入图片描述
在这里插入图片描述

2.消息幂等性处理

在这里插入图片描述

十、RabbitMQ集群搭建

在这里插入图片描述

1.集群方案的原理

在这里插入图片描述

2.单机多实例部署

在这里插入图片描述

[root@super ~]# rabbitmqctl status
Status of node rabbit@super ...
[{pid,10232},
 {running_applications,
     [{rabbitmq_management,"RabbitMQ Management Console","3.6.5"},
      {rabbitmq_web_dispatch,"RabbitMQ Web Dispatcher","3.6.5"},
      {webmachine,"webmachine","1.10.3"},
      {mochiweb,"MochiMedia Web Server","2.13.1"},
      {rabbitmq_management_agent,"RabbitMQ Management Agent","3.6.5"},
      {rabbit,"RabbitMQ","3.6.5"},
      {os_mon,"CPO  CXC 138 46","2.4"},
      {syntax_tools,"Syntax tools","1.7"},
      {inets,"INETS  CXC 138 49","6.2"},
      {amqp_client,"RabbitMQ AMQP Client","3.6.5"},
      {rabbit_common,[],"3.6.5"},
      {ssl,"Erlang/OTP SSL application","7.3"},
      {public_key,"Public key infrastructure","1.1.1"},
      {asn1,"The Erlang ASN1 compiler version 4.0.2","4.0.2"},
      {ranch,"Socket acceptor pool for TCP protocols.","1.2.1"},
      {mnesia,"MNESIA  CXC 138 12","4.13.3"},
      {compiler,"ERTS  CXC 138 10","6.0.3"},
      {crypto,"CRYPTO","3.6.3"},
      {xmerl,"XML parser","1.3.10"},
      {sasl,"SASL  CXC 138 11","2.7"},
      {stdlib,"ERTS  CXC 138 10","2.8"},
      {kernel,"ERTS  CXC 138 10","4.2"}]},
 {os,{unix,linux}},
 {erlang_version,
     "Erlang/OTP 18 [erts-7.3] [source] [64-bit] [async-threads:64] [hipe] [kernel-poll:true]\n"},
 {memory,
     [{total,56066752},
      {connection_readers,0},
      {connection_writers,0},
      {connection_channels,0},
      {connection_other,2680},
      {queue_procs,268248},
      {queue_slave_procs,0},
      {plugins,1131936},
      {other_proc,18144280},
      {mnesia,125304},
      {mgmt_db,921312},
      {msg_index,69440},
      {other_ets,1413664},
      {binary,755736},
      {code,27824046},
      {atom,1000601},
      {other_system,4409505}]},
 {alarms,[]},
 {listeners,[{clustering,25672,"::"},{amqp,5672,"::"}]},
 {vm_memory_high_watermark,0.4},
 {vm_memory_limit,411294105},
 {disk_free_limit,50000000},
 {disk_free,13270233088},
 {file_descriptors,
     [{total_limit,924},{total_used,6},{sockets_limit,829},{sockets_used,0}]},
 {processes,[{limit,1048576},{used,262}]},
 {run_queue,0},
 {uptime,43651},
 {kernel,{net_ticktime,60}}]

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.集群管理

在这里插入图片描述

4.RabbitMQ镜像集群配置

在这里插入图片描述

5.负载均衡-HAProxy

在这里插入图片描述

安装HAProxy

在这里插入图片描述

配置HAProxy

配置文件路径:/etc/haproxy/haproxy.cfg

#logging options
global
	log 127.0.0.1 local0 info
	maxconn 5120
	chroot /usr/local/haproxy
	uid 99
	gid 99
	daemon
	quiet
	nbproc 20
	pidfile /var/run/haproxy.pid

defaults
	log global
	
	mode tcp

	option tcplog
	option dontlognull
	retries 3
	option redispatch
	maxconn 2000
	contimeout 5s
   
     clitimeout 60s

     srvtimeout 15s	
#front-end IP for consumers and producters

listen rabbitmq_cluster
	bind 0.0.0.0:5672
	
	mode tcp
	#balance url_param userid
	#balance url_param session_id check_post 64
	#balance hdr(User-Agent)
	#balance hdr(host)
	#balance hdr(Host) use_domain_only
	#balance rdp-cookie
	#balance leastconn
	#balance source //ip
	
	balance roundrobin
	
        server node1 127.0.0.1:5673 check inter 5000 rise 2 fall 2
        server node2 127.0.0.1:5674 check inter 5000 rise 2 fall 2

listen stats
	bind 172.16.98.133:8100
	mode http
	option httplog
	stats enable
	stats uri /rabbitmq-stats
	stats refresh 5s

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值