3.RabbitMQ工作模式
1.简单队列模式-Hello World
用 Java 编写两个程序。发送单个消息的生产者和接收消息并打印出来的消费者。
依赖:
<!--指定 jdk 编译版本--> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>8</source> <target>8</target> </configuration> </plugin> </plugins> </build> <dependencies> <!--rabbitmq 依赖客户端--> <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.8.0</version> </dependency> <!--操作文件流的一个依赖--> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> </dependencies>
1.1 消息生产者
package com.hguo.producer; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import java.io.IOException; import java.util.concurrent.TimeoutException; /** * 消息生产者 * * @author leizi * @create 2022-02-04 16:09 */ public class Producer { /** * 队列 名称:hello */ private static final String QUEUE_NAME = "hello"; public static void main(String[] args) throws IOException, TimeoutException { // 创建连接工厂 ConnectionFactory factory = new ConnectionFactory(); // 设置连接主机ip、用户名、密码 factory.setHost("192.1.1.1"); factory.setUsername("admin"); factory.setPassword("admin123"); // 创建连接 Connection connection = factory.newConnection(); // 获取信道 Channel channel = connection.createChannel(); /** * 生成一个队列 * 1.队列名称 * 2.队列里面的消息是否持久化 默认消息存储在内存中 * 3.该队列是否只供一个消费者进行消费 是否进行共享 true 可以多个消费者消费 * 4.是否自动删除 最后一个消费者端开连接以后 该队列是否自动删除 true 自动删除 * 5.其他参数 */ channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 消息内容 String message = "hello word"; /** * 发送一个消息 * 1.发送到那个交换机 * 2.路由的 key 是哪个 * 3.其他的参数信息 * 4.发送消息的消息体 */ channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); System.out.println("消息推送完毕"); } }
1.2 消息消费者
package com.hguo.consumer; import com.rabbitmq.client.*; import java.io.IOException; import java.util.concurrent.TimeoutException; /** * 消息消费者 * * @author leizi * @create 2022-02-04 16:45 */ public class Consumer { // 队列 名称:hello private static final String QUEUE_NAME = "hello"; public static void main(String[] args) throws IOException, TimeoutException { // 创建连接工厂 ConnectionFactory factory = new ConnectionFactory(); // 设置连接主机ip、用户名、密码 factory.setHost("192.1.1.1"); factory.setUsername("admin"); factory.setPassword("admin123"); // 创建连接 Connection connection = factory.newConnection(); // 获取信道 Channel channel = connection.createChannel(); // 推送的消息进行消费的接口回调 DeliverCallback deliverCallback = (consumerTag, delivery) -> { String message = new String(delivery.getBody()); System.out.println(message); }; // 取消消费的一个回调接口 如在消费的时候队列被删除掉了 CancelCallback cancelCallback = (consumerTag) -> { System.out.println("消息消费被中断"); }; /** * 消费者消费消息 * 1.消费哪个队列 * 2.消费成功之后是否要自动应答 true 代表自动应答 false 手动应答 * 3.消费者未成功消费的回调 * 4.消费者取消消息的回调 */ channel.basicConsume(QUEUE_NAME, true, deliverCallback, cancelCallback); } }
运行结果:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. hello word Process finished with exit code 1
2.工作队列模式-Work Queues
工作队列(又称任务队列)的主要思想是避免立即执行资源密集型任务,而不得不等待它完成。相反我们安排任务在之后执行。我们把任务封装为消息并将其发送到队列。在后台运行的工作进程将弹出任务并最终执行作业。 当有多个工作线程时,这些工作线程将一起处理这些任务。
轮询分发消息
启动两个工作线程,一个消息发送线程
2.1 抽取工具类
package com.hguo.util; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; // 简单封装工具类,可测试使用即可 public class RabbitMqUtil { // 得到一个连接的 channel public static Channel getChannel() throws Exception { // 创建一个连接工厂 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("192.1.1.1"); factory.setUsername("admin"); factory.setPassword("admin123"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); return channel; } }
2.2 两个工作线程
启动两次
package com.hguo.consumer; import com.hguo.util.RabbitMqUtil; import com.rabbitmq.client.CancelCallback; import com.rabbitmq.client.Channel; import com.rabbitmq.client.DeliverCallback; public class Worker { private static final String QUEUE_NAME = "hello"; public static void main(String[] args) throws Exception { Channel channel = RabbitMqUtil.getChannel(); DeliverCallback deliverCallback = (consumerTag, delivery) -> { String receivedMessage = new String(delivery.getBody()); System.out.println("接收到消息:" + receivedMessage); }; CancelCallback cancelCallback = (consumerTag) -> { System.out.println(consumerTag + "消费者取消消费接口回调逻辑"); }; System.out.println("C1 消费者启动等待消费......"); channel.basicConsume(QUEUE_NAME, true, deliverCallback, cancelCallback); } }
2.3 一个发送线程
package com.hguo.producer; import com.hguo.util.RabbitMqUtil; import com.rabbitmq.client.Channel; import java.util.Scanner; public class Task { private static final String QUEUE_NAME = "hello"; public static void main(String[] args) throws Exception { try (Channel channel = RabbitMqUtil.getChannel();) { channel.queueDeclare(QUEUE_NAME, false, false, false, null); //从控制台当中接收信息 Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { String message = scanner.next(); channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); System.out.println("发送消息完成:" + message); } } } }
2.4 结果展示
通过程序执行发现生产者总共发送 4 个消息,消费者 1 和消费者 2 分别分得两个消息,并且是按照有序的一个接收一次消息。
本文来自博客园,作者:Lz_蚂蚱,转载请注明原文链接:https://www.cnblogs.com/leizia/p/15902522.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步