RabbitMQ自学笔记(高级理论暂未学习,以后补全)

RabbitMQ

MQ基本概念

概念

  • MQ全称Message Queue(消息队列),是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信

  • 分布式系统通信方法两种:直接远程调用和借助第三方完成间接调用

  • 由A系统传输消息到B系统通信,A系统为生产者,B系统为消费者,作为经过的第三方MQ则为中间件

优势与劣势

  • 优势:

    • 应用解耦:提升容错性和可维护性

    • 异步提速:提升用户体验和系统吞吐量(单位时间内处理请求的数目)

    • 削峰填谷:提高系统稳定性

  • 劣势:

    • 系统可用性降低:系统引入的外部依赖越多,系统稳定性越差

    • 系统复杂度提高:暂时无法保证消息是否被重复消费,如何处理消息丢失情况,是否保证消息传递的顺序性

    • 一致性问题:由MQ发消息数据给其他系统,如果其中存在一个系统处理失败,则暂时无法保证消息数据处理的一致性

常见的MQ产品

  • RabbitMQ

  • RocketMQ

  • ActiveMQ

  • Kafka

  • ZeroMQ

  • MetaMq

  • Redis充当消息队列

RabbitMQ简介

  • AMQP,全称Advanced Message Queuing Protocol(高级消息队列协议),是一个网络协议,是应用层协议的一个开发标准,为面向消息的中间件设计,类比HTTP

  • RabbitMQ是基于AMQP协议使用Erlang语言开发的一款消息队列产品

RabbitMQ基础架构

  • Broker:接收和分发消息的应用,RabbitMQ server就是message Broker

  • Virtual Host:出于多租户和安全因素设计的,把AMQP的基本组件划分到一个虚拟的分组中,类似于网络中的namespace概念,当多个不同的用户使用同一个RabbitMQ server提供的服务时,可以划分出多个vhost,每个用户在自己的vhost创建exchange/queue等

  • Connection:生产者/消费者和broker之间的TCP连接

  • Channel:如果每一次访问RabbitMQ都建立一个connection,在消息量大时开销大,效率低,channel是在connection内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的channel进行通讯,AMQP method包含了channel id帮助客户端和message broker识别channel,所以channel之间是完全隔离的,Channel作为轻量级的Connection极大减少了系统建立TCP connection的开销

  • Exchange:message到达broker的第一站,根据分发规则,匹配查询表中的routing key,分发消息到queue中去,常用的类型有:direct(point-to-point),topic(publish-subscribe),fanout(multicast)

  • Queue:消息最终被送到这里等待消费者取走

  • Binding:exchange和queue之间的虚拟连接,binding中可以包含routing key,Binding信息被保存到exchange中的查询表中,用于message的分发依据

RabbitMQ的六种工作模式

  • 简单模式

  • work queues

  • Publish/Subscribe发布与订阅模式

  • Routing路由模式

  • Topics主题模式

  • RPC远程调用模式(远程调用,不太算MQ)

JMS

  • JMS即Java消息服务(JavaMessage Service)应用程序接口,是一个Java平台中关于面向消息中间件的API

  • JMS是JavaEE规范中的一种,类比JDBC

  • RabbitMQ没有实现JMS规范,开源社区提供,ActiveMQ实现了JMS规范

RabbitMQ快速入门

简单模式完成消息队列

  • 创建工程(生产者,消费者)

    • Producer

    • Consumer

  • 添加依赖

    • <dependencies>
      <dependency>
         <!--RabbitMQ java客户端-->
      <groupId>com.rabbitmq</groupId>
         <artifactId>amqp-client</artifactId>
         <version>5.6.0</version>
       </dependency>
      </dependencies>
      <!--编译插件1.8版本-->
      <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>
  • 编写生产者发送消息

    • // 1.创建连接工厂
      ConnectionFactory factory = new ConnectionFactory();
      // 2.设置参数
      factory.setHost("IP地址");//IP 默认值为 localhost
      factory.setPort(5672);//端口 默认值为 5672
      factory.setVirtualHost("/xiangxi");//虚拟机 默认值为 /
      factory.setUsername("xiangxi");//用户名 默认值为 guest
      factory.setPassword("123456");//密码 默认值为 guest
      // 3.创建连接Connection
      Connection connection = factory.newConnection();
      // 4.创建Channel
      Channel channel = connection.createChannel();
      // 5.创建队列Queue(简单模式不需要交换机Exchange)
      /*
      queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
      参数:
      1. queue:队列名称
      2. durable:是否持久化,当mq重启之后,还在
      3. exclusive:
      (1)是否独占,只能有一个消费者监听这队列
      (2)当Connection关闭时,是否删除队列
      4. autoDelete:是否自动删除,当没有消费者时,自动删除掉
      5. arguments:参数信息
      */
      //如果不存在名字叫做hello_world的队列,则会创建该队列
      channel.queueDeclare("hello_world",true,false,false,null);
      // 6.发送消息
      /*
      basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
      参数:
      1. exchange:交换机名称(简单模式下交换机会使用默认的""空字符串)
      2. routingKey:路由名称
      3. props:配置信息
      4. body:发送消息数据
      */
      String body = "hello rabbitmq";
      channel.basicPublish("","hello_world",null,body.getBytes());
      // 7.释放资源
      channel.close();
      connection.close();
  • 编写消费者接收消息

    • // 1.创建连接工厂
      ConnectionFactory factory = new ConnectionFactory();
      // 2.设置参数
      factory.setHost("IP地址");//IP 默认值为 localhost
      factory.setPort(5672);//端口 默认值为 5672
      factory.setVirtualHost("/xiangxi");//虚拟机 默认值为 /
      factory.setUsername("xiangxi");//用户名 默认值为 guest
      factory.setPassword("123456");//密码 默认值为 guest
      // 3.创建连接Connection
      Connection connection = factory.newConnection();
      // 4.创建Channel
      Channel channel = connection.createChannel();
      // 5.创建队列Queue(简单模式不需要交换机Exchange)
      /*
      queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
      参数:
      1. queue:队列名称
      2. durable:是否持久化,当mq重启之后,还在
      3. exclusive:
      (1)是否独占,只能有一个消费者监听这队列
      (2)当Connection关闭时,是否删除队列
      4. autoDelete:是否自动删除,当没有消费者时,自动删除掉
      5. arguments:参数信息
      */
      //如果不存在名字叫做hello_world的队列,则会创建该队列
      channel.queueDeclare("hello_world",true,false,false,null);
      // 6.接收消息
      /*
      basicConsume(String queue, boolean autoAck, Consumer callback)
      参数:
      1. queue,:队列名称
      2. autoAck:是否自动确认(接收到消息自动给mq确认消息)
      3. callback:回调对象
      */
      Consumer consumer = new DefaultConsumer(channel){
       /*
      回调方法,当收到消息后,会自动执行该方法
      参数:
      1. consumerTag:标识
      2. envelope:获取一些信息(交换机,路由key...)
      3. properties:配置信息
      4. body:数据
       */
       @Override
       public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException{
         System.out.println("consumerTag:" + consumerTag);
         System.out.println("Exchange:" + envelope.getExchange());
         System.out.println("RoutingKey:" + envelope.getRoutingKey());
         System.out.println("properties" + properties);
         System.out.println("body" + new String(body));
      }
      }
      channel.basicConsume("hello_world",true,consumer);

RabbitMQ工作模式

简单模式/经典模式

  • 一个生产者对应一个消费者

Work Queues 工作队列模式

  • 一个生产者对应多个消费者,消费者之间对于同一个消息的关系是竞争关系

  • Work Queues对于任务过重或任务较多情况使用工作队列可以提高任务处理速度,例如:短信服务部署多个,只需要有一个节点成功发送即可

Pub/Sub 订阅模式

  • Exchange:交换机(X),一方面,接收生产者发送的消息,另一方面,知道如何处理消息,交换机只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与交换机绑定,或者没有符合路由规则的队列,消息则会丢失

  • Exchange常见三种类型:

    • Fanout:广播,将消息交给所有绑定到交换机的队列

    • Direct:定向,将消息交给符合制定routing key的队列

    • Topic:通配符,将消息交给符合routing pattern(路由模式)的队列

订阅模式生产者代码

// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("IP地址");//IP 默认值为 localhost
factory.setPort(5672);//端口 默认值为 5672
factory.setVirtualHost("/xiangxi");//虚拟机 默认值为 /
factory.setUsername("xiangxi");//用户名 默认值为 guest
factory.setPassword("123456");//密码 默认值为 guest
// 3.创建连接Connection
Connection connection = factory.newConnection();
// 4.创建Channel
Channel channel = connection.createChannel();
// 5.创建交换机Exchange
/*
exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments)
参数:
1. exchange:交换机名称
2. type:交换机类型(枚举)
DIRECT("direct"):定向
FANOUT("fanout"):扇形(广播)
TOPIC("topic"):通配符
HEADERS("headers"):参数匹配
   3. durable:是否持久化
   4. autoDelete:是否自动删除
   5. internal:内部使用
   6. arguments:参数信息
*/
channel.exchangeDeclare("test_fanout",BuiltinExchangeType.FANOUT,true,false,false,null);
// 6.创建队列Queue
/*
queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
参数:
1. queue:队列名称
2. durable:是否持久化,当mq重启之后,还在
3. exclusive:
(1)是否独占,只能有一个消费者监听这队列
(2)当Connection关闭时,是否删除队列
4. autoDelete:是否自动删除,当没有消费者时,自动删除掉
5. arguments:参数信息
*/
channel.queueDeclare("test_fanout_queue1",true,false,false,null);
channel.queueDeclare("test_fanout_queue2",true,false,false,null);
// 7.绑定交换机和队列
/*
queueBind(String queue, String exchange, String routingKey)
参数:
1. queue:队列名称
2. exchange:交换机名称
3. routingKey:路由key,绑定规则(使用fanout类型默认路由key为""空字符串)
*/
channel.queueBind("test_fanout_queue1","test_fanout","");
channel.queueBind("test_fanout_queue2","test_fanout","");
// 8.发送消息
/*
basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
参数:
1. exchange:交换机名称
2. routingKey:路由名称
3. props:配置信息
4. body:发送消息数据
*/
String body = "hello rabbitmq";
channel.basicPublish("test_fanout","",null,body.getBytes());
// 9.释放资源
channel.close();
connection.close();

订阅模式消费者代码

test_fanout_queue1消费者

// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("IP地址");//IP 默认值为 localhost
factory.setPort(5672);//端口 默认值为 5672
factory.setVirtualHost("/xiangxi");//虚拟机 默认值为 /
factory.setUsername("xiangxi");//用户名 默认值为 guest
factory.setPassword("123456");//密码 默认值为 guest
// 3.创建连接Connection
Connection connection = factory.newConnection();
// 4.创建Channel
Channel channel = connection.createChannel();
// 5.接收消息
/*
basicConsume(String queue, boolean autoAck, Consumer callback)
参数:
1. queue,:队列名称
2. autoAck:是否自动确认(接收到消息自动给mq确认消息)
3. callback:回调对象
*/
Consumer consumer = new DefaultConsumer(channel){
 /*
回调方法,当收到消息后,会自动执行该方法
参数:
1. consumerTag:标识
2. envelope:获取一些信息(交换机,路由key...)
3. properties:配置信息
4. body:数据
 */
 @Override
 public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException{
   System.out.println("consumerTag:" + consumerTag);
   System.out.println("Exchange:" + envelope.getExchange());
   System.out.println("RoutingKey:" + envelope.getRoutingKey());
   System.out.println("properties" + properties);
   System.out.println("body" + new String(body));
}
}
channel.basicConsume("test_fanout_queue1",true,consumer);

test_fanout_queue2消费者

// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("IP地址");//IP 默认值为 localhost
factory.setPort(5672);//端口 默认值为 5672
factory.setVirtualHost("/xiangxi");//虚拟机 默认值为 /
factory.setUsername("xiangxi");//用户名 默认值为 guest
factory.setPassword("123456");//密码 默认值为 guest
// 3.创建连接Connection
Connection connection = factory.newConnection();
// 4.创建Channel
Channel channel = connection.createChannel();
// 5.接收消息
/*
basicConsume(String queue, boolean autoAck, Consumer callback)
参数:
1. queue,:队列名称
2. autoAck:是否自动确认(接收到消息自动给mq确认消息)
3. callback:回调对象
*/
Consumer consumer = new DefaultConsumer(channel){
 /*
回调方法,当收到消息后,会自动执行该方法
参数:
1. consumerTag:标识
2. envelope:获取一些信息(交换机,路由key...)
3. properties:配置信息
4. body:数据
 */
 @Override
 public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException{
   System.out.println("consumerTag:" + consumerTag);
   System.out.println("Exchange:" + envelope.getExchange());
   System.out.println("RoutingKey:" + envelope.getRoutingKey());
   System.out.println("properties" + properties);
   System.out.println("body" + new String(body));
}
}
channel.basicConsume("test_fanout_queue2",true,consumer);

Routing 路由模式

  • 队列与交换机的绑定要制定一个RoutingKey(路由Key)

  • 消息的发送方在向交换机发送消息时,也必须指定消息的RoutingKey

  • 交换机不再把消息交给每一个绑定的队列,而是根据消息的RoutingKey进行判断,只有队列的RoutingKey与消息的RoutingKey完全一致,才会接收到消息

路由模式生产者代码

// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("IP地址");//IP 默认值为 localhost
factory.setPort(5672);//端口 默认值为 5672
factory.setVirtualHost("/xiangxi");//虚拟机 默认值为 /
factory.setUsername("xiangxi");//用户名 默认值为 guest
factory.setPassword("123456");//密码 默认值为 guest
// 3.创建连接Connection
Connection connection = factory.newConnection();
// 4.创建Channel
Channel channel = connection.createChannel();
// 5.创建交换机Exchange
/*
exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments)
参数:
1. exchange:交换机名称
2. type:交换机类型(枚举)
DIRECT("direct"):定向
FANOUT("fanout"):扇形(广播)
TOPIC("topic"):通配符
HEADERS("headers"):参数匹配
   3. durable:是否持久化
   4. autoDelete:是否自动删除
   5. internal:内部使用
   6. arguments:参数信息
*/
channel.exchangeDeclare("test_direct",BuiltinExchangeType.DIRECT,true,false,false,null);
// 6.创建队列Queue
/*
queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
参数:
1. queue:队列名称
2. durable:是否持久化,当mq重启之后,还在
3. exclusive:
(1)是否独占,只能有一个消费者监听这队列
(2)当Connection关闭时,是否删除队列
4. autoDelete:是否自动删除,当没有消费者时,自动删除掉
5. arguments:参数信息
*/
channel.queueDeclare("test_direct_queue1",true,false,false,null);
channel.queueDeclare("test_direct_queue2",true,false,false,null);
// 7.绑定交换机和队列
/*
queueBind(String queue, String exchange, String routingKey)
参数:
1. queue:队列名称
2. exchange:交换机名称
3. routingKey:路由key,绑定规则(使用fanout类型默认路由key为""空字符串)
*/
//test_direct_queue1的绑定 error
channel.queueBind("test_direct_queue1","test_direct","error");
//test_direct_queue2的绑定 error info warning
channel.queueBind("test_direct_queue2","test_direct","info");
channel.queueBind("test_direct_queue2","test_direct","error");
channel.queueBind("test_direct_queue2","test_direct","warning");
// 8.发送消息
/*
basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
参数:
1. exchange:交换机名称
2. routingKey:路由名称
3. props:配置信息
4. body:发送消息数据
*/
String body = "hello rabbitmq";
channel.basicPublish("test_direct","",null,body.getBytes());
// 9.释放资源
channel.close();
connection.close();

路由模式消费者代码

test_direct_queue1消费者

// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("IP地址");//IP 默认值为 localhost
factory.setPort(5672);//端口 默认值为 5672
factory.setVirtualHost("/xiangxi");//虚拟机 默认值为 /
factory.setUsername("xiangxi");//用户名 默认值为 guest
factory.setPassword("123456");//密码 默认值为 guest
// 3.创建连接Connection
Connection connection = factory.newConnection();
// 4.创建Channel
Channel channel = connection.createChannel();
// 5.接收消息
/*
basicConsume(String queue, boolean autoAck, Consumer callback)
参数:
1. queue,:队列名称
2. autoAck:是否自动确认(接收到消息自动给mq确认消息)
3. callback:回调对象
*/
Consumer consumer = new DefaultConsumer(channel){
 /*
回调方法,当收到消息后,会自动执行该方法
参数:
1. consumerTag:标识
2. envelope:获取一些信息(交换机,路由key...)
3. properties:配置信息
4. body:数据
 */
 @Override
 public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException{
   System.out.println("consumerTag:" + consumerTag);
   System.out.println("Exchange:" + envelope.getExchange());
   System.out.println("RoutingKey:" + envelope.getRoutingKey());
   System.out.println("properties" + properties);
   System.out.println("body" + new String(body));
}
}
channel.basicConsume("test_fanout_queue1",true,consumer);

test_direct_queue2消费者

// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("IP地址");		//IP 默认值为 localhost
factory.setPort(5672);			//端口 默认值为 5672
factory.setVirtualHost("/xiangxi");			//虚拟机 默认值为 /
factory.setUsername("xiangxi");			//用户名 默认值为 guest
factory.setPassword("123456");			//密码 默认值为 guest
// 3.创建连接Connection
Connection connection = factory.newConnection();
// 4.创建Channel
Channel channel = connection.createChannel();
// 5.接收消息
/*
	basicConsume(String queue, boolean autoAck, Consumer callback)
	参数:
		1. queue,:队列名称
		2. autoAck:是否自动确认(接收到消息自动给mq确认消息)
		3. callback:回调对象
*/
Consumer consumer = new DefaultConsumer(channel){
  /*
  	回调方法,当收到消息后,会自动执行该方法
  	参数:
  		1. consumerTag:标识
  		2. envelope:获取一些信息(交换机,路由key...)
  		3. properties:配置信息
  		4. body:数据
  */
  @Override
  public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException{
    System.out.println("consumerTag:" + consumerTag);
    System.out.println("Exchange:" + envelope.getExchange());
    System.out.println("RoutingKey:" + envelope.getRoutingKey());
    System.out.println("properties" + properties);
    System.out.println("body" + new String(body));
  }
}
channel.basicConsume("test_direct_queue2",true,consumer);

Topics 通配符模式

通配符模式生产者代码

// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("IP地址");		//IP 默认值为 localhost
factory.setPort(5672);			//端口 默认值为 5672
factory.setVirtualHost("/xiangxi");			//虚拟机 默认值为 /
factory.setUsername("xiangxi");			//用户名 默认值为 guest
factory.setPassword("123456");			//密码 默认值为 guest
// 3.创建连接Connection
Connection connection = factory.newConnection();
// 4.创建Channel
Channel channel = connection.createChannel();
// 5.创建交换机Exchange
/*
	exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments)
	参数:
		1. exchange:交换机名称
		2. type:交换机类型(枚举)
				DIRECT("direct"):定向
				FANOUT("fanout"):扇形(广播)
				TOPIC("topic"):通配符
				HEADERS("headers"):参数匹配
    3. durable:是否持久化
    4. autoDelete:是否自动删除
    5. internal:内部使用
    6. arguments:参数信息
*/
channel.exchangeDeclare("test_topic",BuiltinExchangeType.TOPIC,true,false,false,null);
// 6.创建队列Queue
/*
	queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
	参数:
		1. queue:队列名称
		2. durable:是否持久化,当mq重启之后,还在
		3. exclusive:
			(1)是否独占,只能有一个消费者监听这队列
			(2)当Connection关闭时,是否删除队列
		4. autoDelete:是否自动删除,当没有消费者时,自动删除掉
		5. arguments:参数信息
*/
channel.queueDeclare("test_topic_queue1",true,false,false,null);
channel.queueDeclare("test_topic_queue2",true,false,false,null);
// 7.绑定交换机和队列
/*
	queueBind(String queue, String exchange, String routingKey)
	参数:
		1. queue:队列名称
		2. exchange:交换机名称
		3. routingKey:路由key,绑定规则
				routingKey 系统名称.日志级别
					* 对应一个单词 # 对应零-多个单词
*/
//test_topic_queue1的绑定 #.error 任何一个的error级别信息
channel.queueBind("test_topic_queue1","test_topic","#.error");
//test_topic_queue1的绑定 order.* order下的所有级别信息
channel.queueBind("test_topic_queue1","test_topic","order.*");
//test_topic_queue2的绑定 *.* 所有级别的信息
channel.queueBind("test_topic_queue2","test_topic","*.*");
// 8.发送消息
/*
	basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
	参数:
		1. exchange:交换机名称
		2. routingKey:路由名称
		3. props:配置信息
		4. body:发送消息数据
*/
String body = "hello rabbitmq";
channel.basicPublish("test_topic","order.info",null,body.getBytes());
// 9.释放资源
channel.close();
connection.close();

通配符模式消费者代码

test_topic_queue1消费者

// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("IP地址");		//IP 默认值为 localhost
factory.setPort(5672);			//端口 默认值为 5672
factory.setVirtualHost("/xiangxi");			//虚拟机 默认值为 /
factory.setUsername("xiangxi");			//用户名 默认值为 guest
factory.setPassword("123456");			//密码 默认值为 guest
// 3.创建连接Connection
Connection connection = factory.newConnection();
// 4.创建Channel
Channel channel = connection.createChannel();
// 5.接收消息
/*
	basicConsume(String queue, boolean autoAck, Consumer callback)
	参数:
		1. queue,:队列名称
		2. autoAck:是否自动确认(接收到消息自动给mq确认消息)
		3. callback:回调对象
*/
Consumer consumer = new DefaultConsumer(channel){
  /*
  	回调方法,当收到消息后,会自动执行该方法
  	参数:
  		1. consumerTag:标识
  		2. envelope:获取一些信息(交换机,路由key...)
  		3. properties:配置信息
  		4. body:数据
  */
  @Override
  public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException{
    System.out.println("consumerTag:" + consumerTag);
    System.out.println("Exchange:" + envelope.getExchange());
    System.out.println("RoutingKey:" + envelope.getRoutingKey());
    System.out.println("properties" + properties);
    System.out.println("body" + new String(body));
  }
}
channel.basicConsume("test_topic_queue1",true,consumer);

test_topic_queue2消费者

// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("IP地址");		//IP 默认值为 localhost
factory.setPort(5672);			//端口 默认值为 5672
factory.setVirtualHost("/xiangxi");			//虚拟机 默认值为 /
factory.setUsername("xiangxi");			//用户名 默认值为 guest
factory.setPassword("123456");			//密码 默认值为 guest
// 3.创建连接Connection
Connection connection = factory.newConnection();
// 4.创建Channel
Channel channel = connection.createChannel();
// 5.接收消息
/*
	basicConsume(String queue, boolean autoAck, Consumer callback)
	参数:
		1. queue,:队列名称
		2. autoAck:是否自动确认(接收到消息自动给mq确认消息)
		3. callback:回调对象
*/
Consumer consumer = new DefaultConsumer(channel){
  /*
  	回调方法,当收到消息后,会自动执行该方法
  	参数:
  		1. consumerTag:标识
  		2. envelope:获取一些信息(交换机,路由key...)
  		3. properties:配置信息
  		4. body:数据
  */
  @Override
  public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException{
    System.out.println("consumerTag:" + consumerTag);
    System.out.println("Exchange:" + envelope.getExchange());
    System.out.println("RoutingKey:" + envelope.getRoutingKey());
    System.out.println("properties" + properties);
    System.out.println("body" + new String(body));
  }
}
channel.basicConsume("test_topic_queue2",true,consumer);

SpringBoot整合RabbitMQ

生产者

  • 创建生产者SpringBoot工程

  • 引入依赖坐标

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
  • 编写yml配置,基本信息配置

    # 配置RabbitMQ的基本信息
    spring:
      rabbitmq:
        host: 172.16.98.133 #ip
        port: 5672  #端口
        username: guest	
        password: guest
        virtual-host: /
  • 定义交换机,队列以及绑定关系的配置类

    @Configuration
    public class RabbitMQConfig {
    
      public static final String EXCHANGE_NAME = "boot_topic_exchange";
      public static final String QUEUE_NAME = "boot_queue";
    
      // 1.Exchange 交换机
      @Bean("getExchange")
      public Exchange getExchange() {
        return ExchangeBuilder.topicExchange(EXCHANGE_NAME).durable(true).build();
      }
    
      // 2.Queue 队列
      @Bean("getQueue")
      public Queue getQueue() {
        return QueueBuilder.durable(QUEUE_NAME).build();
      }
    
      // 3.Binding 交换机和队列的绑定关系
      @Bean
      public Binding bindQueueExchange(@Qualifier("getQueue") Queue queue, @Qualifier("getExchange") Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with("boot.#").noargs();
      }
    }
  • 注入RabbitTemplate,调用方法,完成消息发送

//ProducerTest生产者测试类
//@RunWith是一个运行器,指定测试环境来运行
@SpringBootTest
@RunWith(SpringRunner.class)
public class ProducerTest {
    // 1.注入RabbitTemplate
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void testSend(){
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME,"boot.heihei","hello springboot");
    }
}

消费者

  • 创建消费者SpringBoot工程

  • 引入依赖坐标

    <dependency>  
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
  • 编写yml配置,基本信息配置

    # 配置RabbitMQ的基本信息
    spring:
      rabbitmq:
        host: 172.16.98.133 #ip
        port: 5672  #端口
        username: guest	
        password: guest
        virtual-host: /
  • 定义监听类,使用@RabbitListener注解完成队列监听

    @Component
    public class RabbitMQListener {
    
      @RabbitListener(queues = "boot_queue")
      public void ListenerQueue(Message message) {
        //System.out.println(message);
        System.out.println(message.getBody());
      }
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XiangXi响希

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值