RabbitMQ二、RabbitMQ的六种模式

一、RabbitMQ的六种模式

  1. RabbitMQ共有六种工作模式:
    • 简单模式(Simple)
    • 工作队列模式(Work Queue)
    • 发布订阅模式(Publish/Subscribe)
    • 路由模式(Routing)
    • 通配符模式(Topics)
    • 远程调用模式(RPC,不常用,不对此模式进行讲解)

1、RabbitMQ的简单模式

在这里插入图片描述

  1. rabbitmq简单模式的特点:
      1. 一个生产者对应一个消费者,通过队列进行消息传递。
      1. 该模式使用direct交换机,direct交换机是RabbitMQ默认交换机

JMS

  1. 由于MQ产品很多,操作方式各有不同,于是JAVA提供了一套规则——JMS,用于操作消息中间件。
  2. JMS即Java消息服务(JavaMessage Service)应用程序接口,是一个Java平台中关于面向消息中间件的API。
  3. JMS是JavaEE规范中的一种,类比JDBC。很多MQ产品都实现了JMS规范,例如ActiveMQ等产品。
    • RabbitMQ官方并没有实现JMS规范,但是开源社区有JMS的实现包。

java操作rabbitmq的简单模式

  1. 操作之前记得启动rabbitmq服务(rabbitmq的客户端不用开启也行)
docker start rabbitmq
  1. 注意:启动rabbitmq的web客户端是为了能访问它的客户端界面
docker exec -it rabbitmq rabbitmq-plugins enable rabbitmq_management
第一步:创建项目(使用简单的maven项目即可)并添加RabbitMQ依赖

在这里插入图片描述

  • 依赖
<dependencies><dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.14.0</version></dependency>
</dependencies>
第二步:生产者和消费者代码的编写
  • 创建生产者(producer)代码
package com.knife.demo01.simple;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.TimeoutException;// 生产者
public class Producer {public static void main(String[] args) throws IOException, TimeoutException {// 1.创建连接工厂ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost("192.168.70.130"); // 虚拟机ipconnectionFactory.setPort(5672);connectionFactory.setUsername("admin");connectionFactory.setPassword("admin");connectionFactory.setVirtualHost("/");// 2.创建连接Connection connection = connectionFactory.newConnection();// 3.建立信道Channel channel = connection.createChannel();// 4.创建队列,如果队列已存在,则使用该队列/*** 参数1:队列名* 参数2:是否持久化,true表示MQ重启后队列还在。* 参数3:是否私有化,false表示所有消费者都可以访问,true表示只有第一次拥有它的消费者才能访问* 参数4:是否自动删除,true表示不再使用队列时自动删除队列* 参数5:其他额外参数*/channel.queueDeclare("simple_queue",false,false,false,null);// 5.发送消息String message = "hello!rabbitmq!";/*** 参数1:交换机名,""表示默认交换机direct* 参数2:路由键,简单模式就是队列名* 参数3:其他额外参数* 参数4:要传递的消息字节数组*/channel.basicPublish("","simple_queue",null,message.getBytes());// 6.关闭信道和连接channel.close();connection.close();System.out.println("===发送成功===");}
}

运行生产者代码结果:
在这里插入图片描述
在这里插入图片描述

  • 创建消费者(consumer)代码
package com.knife.demo01.simple;import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;// 消费者
public class Consumer {public static void main(String[] args) throws IOException, TimeoutException {// 1.创建连接工厂ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost("192.168.70.130"); // 虚拟机ipconnectionFactory.setPort(5672); // 端口号connectionFactory.setUsername("admin");connectionFactory.setPassword("admin");connectionFactory.setVirtualHost("/");// 2.创建连接Connection connection = connectionFactory.newConnection();// 3.建立信道Channel channel = connection.createChannel();// 4.监听队列/*** 参数1:监听的队列名* 参数2:是否自动签收,如果设置为false,则需要手动确认消息已收到,否则MQ会一直发送消息* 参数3:Consumer的实现类,重写该类方法表示接受到消息后如何消费*/channel.basicConsume("simple_queue",true,new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//                接收消息String message = new String(body, "UTF-8");System.out.println("接受消息,消息为:"+message);}});}
}

运行消费者代码结果:
在这里插入图片描述

2、RabbitMQ的工作队列模式(相比简单模式,处理消息的消费者增多了)

在这里插入图片描述

  1. 工作队列模式(Work Queue)与简单模式相比,多了一些消费者,该模式也使用direct交换机(默认使用的交换机),应用于处理消息较多的情况。特点如下:

      1. 一个队列对应多个消费者。
      1. 一条消息只会被一个消费者消费。
      1. 消息队列默认采用轮询的方式将消息平均发送给消费者。
      1. 在一个队列中如果有多个消费者,那么消费者之间对于同一个消息的关系是竞争的关系
  2. Work Queues 对于任务过重或任务较多情况使用工作队列可以提高任务处理的速度。例如:短信服务部署多个,只需要有一个节点成功发送即可
    在这里插入图片描述

java操作rabbitmq的工作队列模式

  1. Work Queues 的入门程序与上面简单模式的代码几乎是一样的。可以完全复制,只是比简单模式的消费者多几个而已,可以让多个消费者同时对消费消息的测试。
  2. 在简单模式的基础下编写代码(直接用同一个项目)
    在这里插入图片描述
  • 消息生产者代码:
public class Producer {public static void main(String[] args) throws IOException, TimeoutException {
//        创建工厂连接ConnectionFactory cf = new ConnectionFactory();cf.setHost("192.168.70.130"); //虚拟机地址cf.setPort(5672); //rabbitmq的端口号cf.setUsername("admin"); // 用户名cf.setPassword("admin"); // 密码cf.setVirtualHost("/"); //        创建连接Connection connection = cf.newConnection();//        创建信道Channel channel = connection.createChannel();//        创建队列/*** 参数1:队列名称* 参数二:是否持久化* 参数三:是否私有化* 参数4:队列使用完毕后是否自动删除*/channel.queueDeclare("work_queue",true,false,false,null);//        发送消息/*** 参数1:交换机名,""表示默认交换机direct* 参数2:路由键,简单模式就是队列名* 参数3:其他额外参数* 参数4:要传递的消息字节数组*/for (int i = 1; i <= 10; i++) {channel.basicPublish("","work_queue", MessageProperties.PERSISTENT_TEXT_PLAIN,("你好,这是今天的第"+i+"条消息").getBytes());}//        关闭资源channel.close();connection.close();System.out.println("消息发送成功====");}
}
  • 消息消费者代码(多个消费者可以代码复用,复用下面的代码,多创几个类)
public class Consumer {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工程ConnectionFactory cf = new ConnectionFactory();cf.setHost("192.168.70.130");cf.setPort(5672);cf.setUsername("admin");cf.setPassword("admin");cf.setVirtualHost("/");//2.创建连接Connection conn = cf.newConnection();//3.创建信道Channel channel = conn.createChannel();//        4. 接收消息channel.basicConsume("work_queue",true,new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, StandardCharsets.UTF_8);System.out.println("消费者1 = " + msg);}});channel.close();conn.close();}}

代码运行的效果和上面简单模式的类似。

3、RabbitMQ的发布订阅模式(相比工作队列模式,交换机使用的类型是Fanout(广播类型))

在这里插入图片描述

  • 图解说明
    • P:生产者,向 Exchange 发送消息
    • X:Exchange(交换机),接收生产者的消息,然后把消息递交给与交换机绑定的队列
    • C1、C2:消费者,其所在队列要与交换机进行绑定
  1. 在开发过程中,有一些消息需要不同的消费者进行不同的处理
    • 如电商网站的同一条促销信息需要短信发送邮件发送站内信发送等。此时可以使用发布订阅模式(Publish/Subscribe)
  2. 在订阅模型中,多了一个Exchange角色,而且过程略有变化:
    • Producer:生产者,也就是要发送消息的程序,但是不再发送到队列中,而是发给X(交换机)
    • Consumer:消费者,消息的接收者,会一直等待消息到来
    • Queue:消息队列,接收消息、缓存消息
    • Exchange:交换机(X)。一方面,接收生产者发送的消息。另一方面,知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。Exchange有常见以下3种类型:
      • Fanout:广播类型,将消息交给所有绑定到交换机的队列
      • Direct:定向类型,把消息交给符合指定routing key 的队列
      • Topic:通配符类型,把消息交给符合routing pattern(路由模式) 的队列,Exchange(交换机)只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与 Exchange 绑定,或者没有符合路由规则的队列,那么消息会丢失!
  3. 特点:
      1. 生产者(Producer)将消息发送给交换机,交换机将消息转发到绑定此交换机的每个队列中(即可以转发到多个队列中)。
      1. 工作队列模式的交换机只能将消息发送给一个队列,发布订阅模式的交换机能将消息发送给多个队列。发布订阅模式使用fanout交换机

java操作rabbitmq的发布订阅模式

  1. 在简单模式的基础下编写代码(直接用同一个项目)
    在这里插入图片描述
    其实代码还是差不多的,只是使用到的交换机不一样了而已。
  • Producer
public class Producer {// 生产者public static void main(String[] args) throws IOException, TimeoutException {// 1.创建连接工厂ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost("192.168.70.130");connectionFactory.setPort(5672);connectionFactory.setUsername("admin");connectionFactory.setPassword("admin");connectionFactory.setVirtualHost("/");// 2.创建连接Connection connection = connectionFactory.newConnection();// 3.建立信道Channel channel = connection.createChannel();// 4.创建交换机/*** 参数1:交换机名* 参数2:交换机类型* 参数3:交换机持久化*/
//        BuiltinExchangeType.FANOUT:表示广播模式channel.exchangeDeclare("exchange_fanout", BuiltinExchangeType.FANOUT, true);// 5.创建队列
//        队列1channel.queueDeclare("SEND_MAIL", true, false, false, null);
//        队列2channel.queueDeclare("SEND_MESSAGE", true, false, false, null);
//        队列3channel.queueDeclare("SEND_STATION", true, false, false, null);// 6.交换机绑定队列/*** 参数1:队列的名称* 参数2:交换机名* 参数3:路由关键字,发布订阅模式写""即可*/channel.queueBind("SEND_MAIL", "exchange_fanout", "");channel.queueBind("SEND_MESSAGE", "exchange_fanout", "");channel.queueBind("SEND_STATION", "exchange_fanout", "");// 7.发送消息channel.basicPublish("exchange_fanout", "", null,("618商品开抢了!").getBytes(StandardCharsets.UTF_8));
//        for (int i = 1; i <= 10; i++) {
//            channel.basicPublish("exchange_fanout", "", null,
//                    ("你好,尊敬的用户,秒杀商品开抢了!" + i).getBytes(StandardCharsets.UTF_8));
//        }// 8.关闭资源channel.close();connection.close();}
}
  • ConsumerMail(消费者代码都类似)
public class ConsumerMail {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工程ConnectionFactory cf = new ConnectionFactory();cf.setHost("192.168.70.130");cf.setPort(5672);cf.setUsername("admin");cf.setPassword("admin");cf.setVirtualHost("/");//2.创建连接Connection conn = cf.newConnection();//3.创建信道Channel channel = conn.createChannel();//4.监听队列channel.basicConsume("SEND_MAIL",true,new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, StandardCharsets.UTF_8);System.out.println("发送邮件消息 = " + msg);}});}
}
  • ConsumerMesage
public class ConsumerMessage {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工程ConnectionFactory cf = new ConnectionFactory();cf.setHost("192.168.70.130");cf.setPort(5672);cf.setUsername("admin");cf.setPassword("admin");cf.setVirtualHost("/");//2.创建连接Connection conn = cf.newConnection();//3.创建信道Channel channel = conn.createChannel();//4.监听队列channel.basicConsume("SEND_MESSAGE",true,new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, StandardCharsets.UTF_8);System.out.println("发送短信消息 = " + msg);}});}
}
  • ConsumerStation
public class ConsumerStation {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工程ConnectionFactory cf = new ConnectionFactory();cf.setHost("192.168.70.130");cf.setPort(5672);cf.setUsername("admin");cf.setPassword("admin");cf.setVirtualHost("/");//2.创建连接Connection conn = cf.newConnection();//3.创建信道Channel channel = conn.createChannel();//4.监听队列channel.basicConsume("SEND_STATION",true,new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, StandardCharsets.UTF_8);System.out.println("发送站內信 = " + msg);}});}
}

4、RabbitMQ的路由模式(相比发布订阅模式,多了个Route Key)

  1. 使用发布订阅模式时,所有消息都会发送到绑定的队列中,但很多时候,不是所有消息都无差别的发布到所有队列中。比如电商网站的促销活动,双十一大促可能会发布到所有队列;而一些小的促销活动为了节约成本,只发布到站内信队列。此时需要使用路由模式(Routing)完成这一需求。
    在这里插入图片描述
  • 图解说明
    • P:生产者,向 Exchange 发送消息,发送消息时,会指定一个routing key
    • X:Exchange(交换机),接收生产者的消息,然后把消息递交给与 routing key 完全匹配的队列
    • C1:消费者,其所在队列指定了需要 routing key 为 error 的消息
    • C2:消费者,其所在队列指定了需要 routing key 为 info、error、warning 的消息
  1. 队列与交换机的绑定,不能是任意绑定了,而是要指定一个 RoutingKey(路由key),消息的发送方在向Exchange发送消息时,也必须指定消息的 RoutingKey,Exchange不再把消息交给每一个绑定的队列,而是根据消息的Routing Key进行判断,只有队列的Routingkey 与消息的 Routing key 完全一致,才会接收到消息。

java操作rabbitmq的路由模式

  1. 在简单模式的基础下编写代码(直接用同一个项目)
    在这里插入图片描述

其实代码还是差不多的,只是使用到的交换机不一样了,多了一个route Key。

  • Producer
public class Producer {// 生产者public static void main(String[] args) throws IOException, TimeoutException {// 1.创建连接工厂ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost("192.168.70.130");connectionFactory.setPort(5672);connectionFactory.setUsername("admin");connectionFactory.setPassword("admin");connectionFactory.setVirtualHost("/");// 2.创建连接Connection connection = connectionFactory.newConnection();// 3.建立信道Channel channel = connection.createChannel();// 4.创建交换机/*** 参数1:交换机名* 参数2:交换机类型* 参数3:交换机持久化*/
//      BuiltinExchangeType.DIRECTchannel.exchangeDeclare("routing_exchange", BuiltinExchangeType.DIRECT, true);// 5.创建队列
//        队列1channel.queueDeclare("SEND_MAILRoute", true, false, false, null);
//        队列2channel.queueDeclare("SEND_MESSAGERoute", true, false, false, null);
//        队列3channel.queueDeclare("SEND_STATIONRoute", true, false, false, null);// 6.交换机绑定队列/*** 参数1:队列的名称* 参数2:交换机名* 参数3:路由关键字(路由名称)*/channel.queueBind("SEND_MAILRoute", "routing_exchange", "import");channel.queueBind("SEND_MESSAGERoute", "routing_exchange", "import");channel.queueBind("SEND_STATIONRoute", "routing_exchange", "import");channel.queueBind("SEND_STATIONRoute", "routing_exchange", "normal");// 7.发送消息channel.basicPublish("routing_exchange", "import", null,("618商品开抢了!").getBytes(StandardCharsets.UTF_8));channel.basicPublish("routing_exchange", "normal", null,("normal路由的息").getBytes(StandardCharsets.UTF_8));
//        for (int i = 1; i <= 10; i++) {
//            channel.basicPublish("exchange_fanout", "", null,
//                    ("你好,尊敬的用户,秒杀商品开抢了!" + i).getBytes(StandardCharsets.UTF_8));
//        }// 8.关闭资源channel.close();connection.close();}
}
  • ConsumerMail(消费者代码都类似)
public class ConsumerMail {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工程ConnectionFactory cf = new ConnectionFactory();cf.setHost("192.168.70.130");cf.setPort(5672);cf.setUsername("admin");cf.setPassword("admin");cf.setVirtualHost("/");//2.创建连接Connection conn = cf.newConnection();//3.创建信道Channel channel = conn.createChannel();//4.监听队列channel.basicConsume("SEND_MAILRoute",true,new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, StandardCharsets.UTF_8);System.out.println("发送邮件消息 = " + msg);}});}
}
  • ConsumerMesage
public class ConsumerMessage {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工程ConnectionFactory cf = new ConnectionFactory();cf.setHost("192.168.70.130");cf.setPort(5672);cf.setUsername("admin");cf.setPassword("admin");cf.setVirtualHost("/");//2.创建连接Connection conn = cf.newConnection();//3.创建信道Channel channel = conn.createChannel();//4.监听队列channel.basicConsume("SEND_MESSAGERoute",true,new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, StandardCharsets.UTF_8);System.out.println("发送短信消息 = " + msg);}});}
}
  • ConsumerStation
public class ConsumerStation {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工程ConnectionFactory cf = new ConnectionFactory();cf.setHost("192.168.70.130");cf.setPort(5672);cf.setUsername("admin");cf.setPassword("admin");cf.setVirtualHost("/");//2.创建连接Connection conn = cf.newConnection();//3.创建信道Channel channel = conn.createChannel();//4.监听队列channel.basicConsume("SEND_STATIONRoute",true,new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, StandardCharsets.UTF_8);System.out.println("发送站內信 = " + msg);}});}
}

5、RabbitMQ的通配符模式(相比路由模式,路由的组成中带上了通配符)

在这里插入图片描述

  1. 通配符模式(Topic)是在路由模式的基础上,给队列绑定带通配符的路由关键字,只要消息的RoutingKey能实现通配符匹配,就会将消息转发到该队列。通配符模式比路由模式更灵活,使用topic交换机
  2. 通配符规则:
      1. 消息设置RoutingKey时,RoutingKey由多个单词构成,中间以.分割。
      1. 队列设置RoutingKey时,#可以匹配任意多个单词,*可以匹配任意一个单词。
        在这里插入图片描述
  • 红色 Queue:绑定的是 usa.# ,因此凡是以 usa. 开头的 routing key 都会被匹配到
  • 黄色 Queue:绑定的是 #.news ,因此凡是以 .news 结尾的 routing key 都会被匹配

java操作rabbitmq的通配符模式

  1. 在简单模式的基础下编写代码(直接用同一个项目)
    在这里插入图片描述
    其实代码还是差不多的,只是route Key的组成多了通配符。
  • Producer
public class Producer {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工厂ConnectionFactory cf = new ConnectionFactory();cf.setHost("192.168.126.10");cf.setPort(5672);cf.setUsername("admin");cf.setPassword("admin");cf.setVirtualHost("/");//2.创建连接Connection conn = cf.newConnection();//3.创建信道Channel channel = conn.createChannel();//4.创建交换机/*** 参数1:交换机名* 参数2:交换机类型* 参数3:交换机持久化*/channel.exchangeDeclare("exchange_topic", BuiltinExchangeType.TOPIC, true);/*** 参数1:队列名* 参数2:是否持久化,true表示MQ重启后队列还在。* 参数3:是否私有化,false表示所有消费者都可以访问,true表示只有第一次拥有它的消费者才能访问* 参数4:是否自动删除,true表示不再使用队列时自动删除队列* 参数5:其他额外参数*///5.创建队列(举例订单给手机发送,邮箱,站内)发送消息,3个队列channel.queueDeclare("SEND_MAIL3", true, false, false, null);channel.queueDeclare("SEND_MESSAGE3", true, false, false, null);channel.queueDeclare("SEND_STATION3", true, false, false, null);//6.将队列和交换机绑定/*** 参数1:队列名* 参数2:交换机名* 参数3:路由关键字,发布订阅模式写""即可*/channel.queueBind("SEND_MAIL3", "exchange_topic", "#.mail.#");channel.queueBind("SEND_MESSAGE3", "exchange_topic", "#.message.#");channel.queueBind("SEND_STATION3", "exchange_topic", "#.station.#");//8.发送消息channel.basicPublish("exchange_topic", "mail.message.station", null, "618大促销活动".getBytes(StandardCharsets.UTF_8));channel.basicPublish("exchange_topic", "station", null, "618小促销活动".getBytes(StandardCharsets.UTF_8));//9.关闭资源channel.close();conn.close();System.out.println("发送消息成功");}
}
  • ConsumerMail(消费者代码都类似)
public class ConsumerMail {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工程ConnectionFactory cf = new ConnectionFactory();cf.setHost("192.168.126.10");cf.setPort(5672);cf.setUsername("admin");cf.setPassword("admin");cf.setVirtualHost("/");//2.创建连接Connection conn = cf.newConnection();//3.创建信道Channel channel = conn.createChannel();//4.监听队列channel.basicConsume("SEND_MAIL3",true,new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, StandardCharsets.UTF_8);System.out.println("发送邮件消息 = " + msg);}});}
}
  • ConsumerMesage
public class ConsumerMessage {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工程ConnectionFactory cf = new ConnectionFactory();cf.setHost("192.168.126.10");cf.setPort(5672);cf.setUsername("admin");cf.setPassword("admin");cf.setVirtualHost("/");//2.创建连接Connection conn = cf.newConnection();//3.创建信道Channel channel = conn.createChannel();//4.监听队列channel.basicConsume("SEND_MESSAGE3",true,new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, StandardCharsets.UTF_8);System.out.println("发送短信消息 = " + msg);}});}
}
  • ConsumerStation
public class ConsumerStation {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工程ConnectionFactory cf = new ConnectionFactory();cf.setHost("192.168.126.10");cf.setPort(5672);cf.setUsername("admin");cf.setPassword("admin");cf.setVirtualHost("/");//2.创建连接Connection conn = cf.newConnection();//3.创建信道Channel channel = conn.createChannel();//4.监听队列channel.basicConsume("SEND_STATION3",true,new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, StandardCharsets.UTF_8);System.out.println("发送站內信 = " + msg);}});}
}

RabbitMQ一、RabbitMQ的介绍与安装(docker)
RabbitMQ三、springboot整合rabbitmq(消息可靠性、高级特性)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/20140.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第四十六天 | 完全背包理论基础、518. 零钱兑换 II、377. 组合总和 Ⅳ

完全背包理论基础 视频讲解&#xff1a; https://www.bilibili.com/video/BV1uK411o7c9 https://programmercarl.com/%E8%83%8C%E5%8C%85%E9%97%AE%E9%A2%98%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80%E5%AE%8C%E5%85%A8%E8%83%8C%E5%8C%85.html 完全和01背包的区别&#xff1a; …

通俗易懂->哈希表详解

目录 一、什么是哈希表&#xff1f; 1.1哈希表长什么样&#xff1f; 1.2为什么会有哈希表&#xff1f; 1.3哈希表的特点 1.3.1 取余法、线性探测 1.3.2 映射 1.3.3负载因子 1.4哈希桶 1.5闲散列与开散列 1.6总结 二、设计hash表 1、哈希表的设计 1&#xff09;插入…

Nginx实战:日志打印自定义请求头

nginx的日志可以打印很多内容&#xff0c;但是有时候自定义的请求头该怎么打印呢&#xff1f;像下面这种场景&#xff1a; 其实很简单&#xff0c;设置日志打印格式log_format的时候&#xff0c;自定义的请求头用 【$http_自定义请求头名】 的格式就可以打印出来 例如你的自定义…

如何掌握Spring事件发布和监听机制?

在软件设计和开发过程中&#xff0c;事件驱动是一种非常主流的架构模式&#xff0c;它的基本组成见下图&#xff0c;可以看到存在一个事件中心&#xff0c;而各个服务可以执行事件发布、订阅和消费等基本过程。 事件驱动架构代表的是一种架构设计风格&#xff0c;实现方法和工具…

[图解]企业应用架构模式2024新译本讲解05-表模块2

1 00:00:00,970 --> 00:00:03,440 接下来&#xff0c;我们就来看案例了 2 00:00:03,690 --> 00:00:09,260 案例跟上一次事务脚本案例是一样的 3 00:00:11,210 --> 00:00:13,130 也是收入确认这个案例 4 00:00:14,460 --> 00:00:15,580 这是表结构 5 00:00:15,7…

【Android】手动下载gradle插件包,解决gradle插件包下载不全问题。

问题描述 拉取别人的项目时&#xff0c;因为网络问题gradle插件包一直下载不全&#xff0c;一直build。 解决方案&#xff1a; 打开gradle>wrapper文件下gradle-wrapper.properties&#xff0c;查看需要下载gradle-7.2-bin.zip。 distributionBaseGRADLE_USER_HOME distr…

cmd窗口输出内容乱码问题

出现这样的问题是因为编码格式和解码格式不一样导致的&#xff0c;cmd窗口的默认解码格式为GBK&#xff0c;如想修改cmd默认编码格式可以按照下面步骤操作&#xff1a;打开cmd窗口输入&#xff1a;chcp 65001 65001指的是utf-8编码如果不清楚编码对应的 页面编码是是多少&#…

访问github加速方法续集dev-sidecar

访问github加速方法续集dev-sidecar dev-sidecar 重要提醒 ------------------------------重要提醒1--------------------------------- 注意&#xff1a;由于electron无法监听windows的关机事件&#xff0c;开着ds情况下直接重启电脑&#xff0c;会导致无法上网&#xff0c…

【网络层】IP地址基础 与 子网掩码

文章目录 IP地址基础IP地址概念IP地址分类公网地址和私网地址 子网掩码子网掩码作用默认子网掩码网络地址、主机地址、广播地址 IP地址基础 IP地址概念 IP地址&#xff1a;IP Address 在网络中&#xff0c;通信节点都需要有一个IP地址 IP地址以点分十进制表示&#xff0c;有…

建设人工智能平台,主流GPU卡选型分析

国内外主流GPU卡性能分析&#xff01;2024&#xff01; 大模型兴起助推算力需求激增 2024年&#xff0c;深度学习与人工智能技术飞速跃进&#xff0c;Transformer、GPT-3等大模型在自然语言处理、图像识别、语音合成等领域大放异彩&#xff0c;开启AI新纪元。其庞大的参数与数…

Matlab操作Excel筛选指定数据的对应数据

Matlab中在表格中寻找指定汉字&#xff0c;并返回其所在行数&#xff0c; 将该行数的另一列提取出来。 目录 一、前言 二、直接在命令行输出 三、保存筛选数据excel 一、前言 源数据excel&#xff1a; 指定汉子&#xff1a;买&#xff0c;得到下面数据&#xff1a; 二、直接…

微信小程序埋点监听方案

场景&#xff1a;运营小程序&#xff0c;需要根据系统访问情况来做决策时。 后台&#xff1a;开发可配置监听页面路径&#xff0c;参数&#xff0c;事件名称等&#xff0c;类似以下格式&#xff0c;进行json保存。 组装数据接口返回给前端缓存到本地&#xff0c;然后进行校验编…

MyBatis延迟加载缓存分页逆向工程

文章目录 延迟加载概述步骤 缓存一级缓存介绍原理 二级缓存介绍 设置缓存对象策略原理开启步骤属性解释是否使用一级缓存 分页插件使用步骤 逆向工程介绍搭建使用增删修改查 延迟加载 概述 延迟加载本身是依赖于多表查询的 延迟加载中返回值要选择resultMap返回的结果一定是D…

数学建模 —— 插值与拟合(1)

一、matlab画图 1.1 plot&#xff08;二维图形&#xff09; plot(x) —— 缺省自变量绘图格式 plot(x,y) —— 基本格式&#xff0c;以y(x)的函数关系作出直角坐标图&#xff0c;如果y为nm的矩阵&#xff0c;则以x为自变量&#xff0c;作出m条曲线 plot(x1,y1,x2,y2,…,xn,…

神经网络算法详解与前沿探索

神经网络算法详解与前沿探索 随着人工智能技术的迅猛发展&#xff0c;神经网络成为机器学习领域的重要组成部分&#xff0c;广泛应用于图像识别、自然语言处理和推荐系统等。本文将详细探讨神经网络的基本原理、结构、训练过程及其应用实例&#xff0c;并扩展至更多相关领域和…

基于标准库的STM32的外部中断EXTI

毕设已经告一段落了&#xff0c;接下来准备开始整理一下毕设中用到的知识与技术细节&#xff0c;今天整理的是STM32从编码器获取数据的方式-----外部中断&#xff08;EXTI&#xff09;&#xff1a; 外部中断分为四个硬件相关外设&#xff0c;GPIO/AFIO/EXTI/NVIC&#xff08;E…

戴尔向“数”而行,以“质”致远,做新质生产力的躬耕者

【全球存储观察 &#xff5c; 热点关注】 自1984年戴尔成立&#xff0c;一路走来&#xff0c;戴尔科技集团40年长期持续的技术创新&#xff0c;一直引领全球科技行业的技术趋势。 到如今&#xff0c;AIGC风行一时&#xff0c;在重塑千行百业的同时&#xff0c;也加速了科技行业…

选择算法之冒泡排序【图文详解】

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;LiUEEEEE                        …

北斗应急救援终端如何做好汛期重点行业安全防控?

【安全提示】 汛期各地高温多雨、极端天气增多 防汛和安全生产形势严峻复杂如何做好汛期重点行业企业安全生产风险防控&#xff1f; 顶坚北斗短报文终端V1单北斗定位终端 北斗应急救援终端在汛期重点行业安全防控中扮演着关键角色&#xff0c;其高可靠性、稳定性和丰富的功能扩…

达摩院AI早癌筛查技术闪耀联合国,癌症早治时代来临?

全文预计1200字左右&#xff0c;预计阅读需要6分钟。 5月30日&#xff0c;在日内瓦举行的联合国AI大会上&#xff0c;各国的代表性企业拿出最优秀的AI成果进行分享。其中代表中国的是阿里巴巴集团的下属机构-达摩院&#xff0c;其在现场播放的一段影像&#xff0c;让在场的所有…