消息中间件系列教程(08) -RabbitMQ -案例代码(工作队列模式)

简介: 消息中间件系列教程(08) -RabbitMQ -案例代码(工作队列模式)

引言

代码已上传至Github,有兴趣的同学可以下载看看:https://github.com/ylw-github/RabbitMQ-Demo

前面博客讲解了RabbitMQ的五种队列形式《消息中间件系列教程(06) -RabbitMQ -五种队列形式》,主要讲解一下五种队列的代码实现。

主要分为:

  1. 点对点队列模式(简单)
  2. 工作队列模式(公平性)
  3. 发布订阅模式
  4. 路由模式Routing
  5. 通配符模式Topics

本文主要讲解工作队列模式。

工作队列模式

1.新建Maven项目RabbitMQ-Demo

2.添加Maven依赖:

<dependencies>
  <dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>3.6.5</version>
  </dependency>
</dependencies>

3.连接工具类

package com.ylw.rabbitmq;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class RabbitMQConnecUtils {
    public static Connection newConnection() throws IOException, TimeoutException {
        // 1.定义连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        // 2.设置服务器地址
        factory.setHost("127.0.0.1");
        // 3.设置协议端口号
        factory.setPort(5672);
        // 4.设置vhost
        factory.setVirtualHost("OrderHost");
        // 5.设置用户名称
        factory.setUsername("OrderAdmin");
        // 6.设置用户密码
        factory.setPassword("123456");
        // 7.创建新的连接
        Connection newConnection = factory.newConnection();
        return newConnection;
    }
}

1. 生产者

public class Producer {
    private static final String QUEUE_NAME = "add_order_work_queue";
    public static void main(String[] args) throws IOException, TimeoutException {
        // 1.获取连接
        Connection newConnection = RabbitMQConnecUtils.newConnection();
        // 2.创建通道
        Channel channel = newConnection.createChannel();
        // 3.创建队列声明
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        channel.basicQos(1);// 保证一次只分发一次,限制发送给同一个消费者,不得超过一条消息
        for (int i = 1; i <= 10; i++) {
            String msg = "index=" + i;
            System.out.println("生产者发送消息 -> " + msg);
            // 4.发送消息
            channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
        }
        channel.close();
        newConnection.close();
    }
}

2. 消费者

消费者1:

public class Consumer1 {
    private static final String QUEUE_NAME = "add_order_work_queue";
    public static void main(String[] args) throws IOException, TimeoutException {
        // 1.获取连接
        Connection newConnection = RabbitMQConnecUtils.newConnection();
        // 2.获取通道
        final Channel channel = newConnection.createChannel();
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        channel.basicQos(1);// 保证一次只分发一次 限制发送给同一个消费者 不得超过一条消息
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
                    throws IOException {
                String msgString = new String(body, "UTF-8");
                System.out.println("消费者1获取消息:" + msgString);
                // 手动回执消息
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        // 3.监听队列
        channel.basicConsume(QUEUE_NAME, false, defaultConsumer);
    }
}

消费者2:

public class Consumer2 {
    private static final String QUEUE_NAME = "add_order_work_queue";
    public static void main(String[] args) throws IOException, TimeoutException {
        // 1.获取连接
        Connection newConnection = RabbitMQConnecUtils.newConnection();
        // 2.获取通道
        final Channel channel = newConnection.createChannel();
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        channel.basicQos(1);// 保证一次只分发一次 限制发送给同一个消费者 不得超过一条消息
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
                    throws IOException {
                String msgString = new String(body, "UTF-8");
                System.out.println("消费者获取消息:" + msgString);
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    // 手动回执消息
                    channel.basicAck(envelope.getDeliveryTag(), false);
                }
            }
        };
        // 3.监听队列
        channel.basicConsume(QUEUE_NAME, false, defaultConsumer);
    }
}

3. 测试

启动消费者1和消费者2,在RabbitMQ控制台可以看到,消息已经注册到了队列了:

然后开始生产,启动生产者:

可以看到Consumer1比Comsumer2 消费多9个,因为Consumer延时了2:

这就是典型的工作队列模式,多劳多得。

相关实践学习
快速体验阿里云云消息队列RocketMQ版
本实验将带您快速体验使用云消息队列RocketMQ版Serverless系列实例进行获取接入点、创建Topic、创建订阅组、收发消息、查看消息轨迹和仪表盘。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
消息中间件 Java 数据库
RocketMQ实战—9.营销系统代码初版
本文主要介绍了实现营销系统四大促销场景的代码初版:全量用户推送促销活动、全量用户发放优惠券、特定用户推送领取优惠券消息、热门商品定时推送。
RocketMQ实战—9.营销系统代码初版
|
消息中间件
RabbitMQ的 RPC 消息模式你会了吗?
【9月更文挑战第11天】RabbitMQ 的 RPC(远程过程调用)消息模式允许客户端向服务器发送请求并接收响应。其基本原理包括:1) 客户端发送请求,创建回调队列并设置关联标识符;2) 服务器接收请求并发送响应至回调队列;3) 客户端根据关联标识符接收并匹配响应。实现步骤涵盖客户端和服务器的连接、信道创建及请求处理。注意事项包括关联标识符唯一性、回调队列管理、错误处理及性能考虑。RPC 模式适用于构建可靠的分布式应用程序,但需根据需求调整优化。
540 3
|
消息中间件 网络协议 RocketMQ
RocketMQ Controller 模式 始终更新成本机ip
ontrollerAddr=192.168.24.241:8878 但是日志输出Update controller leader address to 127.0.0.1:8878。导致访问失败
385 4
|
设计模式 监控 中间件
深入理解PHP中的中间件模式
【10月更文挑战第20天】探索PHP编程世界中的“交通枢纽”——中间件模式。从代码层面剖析如何实现请求和响应的高效管理,以及如何在开发中应用这一模式来增强项目的扩展性和维护性。
|
中间件 PHP 开发者
深入理解PHP中的中间件模式
【10月更文挑战第6天】在PHP开发中,中间件模式是一种优雅的处理请求和响应的方式。本文将带你探索中间件模式的概念、实现及其在PHP框架中的应用,同时提供实用的代码示例来加深理解。
252 4
|
JavaScript 前端开发 中间件
深入浅出Node.js中间件模式
【9月更文挑战第13天】本文将带你领略Node.js中间件模式的魅力,从概念到实战,一步步揭示如何利用这一强大工具简化和增强你的Web应用。我们将通过实际代码示例,展示中间件如何在不修改原有代码的情况下,为请求处理流程添加功能层。无论你是前端还是后端开发者,这篇文章都将为你打开一扇通往更高效、更可维护代码的大门。
|
设计模式 缓存 中间件
深入理解PHP中的中间件模式
【9月更文挑战第12天】本文旨在通过浅显易懂的语言和实际代码示例,引导读者了解PHP中如何实现和使用中间件模式,以及这一设计模式如何优化我们的应用程序结构。文章将逐步介绍中间件的概念、在PHP中的应用实例,以及如何自定义中间件来解决实际问题。
|
设计模式 缓存 中间件
探索PHP中的中间件模式
【10月更文挑战第33天】在编程世界中,设计模式是解决常见问题的模板。本文将带你领略PHP中中间件模式的魅力,它如何优雅地处理请求,并保持代码的整洁与可维护性。通过实际代码示例,我们将一步步实现一个简单的中间件框架,让你轻松理解并应用到自己的项目中。
|
设计模式 缓存 中间件
深入理解PHP中的中间件模式
【8月更文挑战第31天】 在PHP开发中,中间件模式是一种优雅的架构设计,它允许开发者以非侵入式的方式扩展应用程序的功能。本文将通过一个简单的示例,展示如何在PHP中实现和使用中间件,以及这种模式如何提高代码的可维护性和可测试性。
|
设计模式 中间件 PHP
深入理解PHP中的中间件模式
【8月更文挑战第31天】本文旨在通过深入浅出的方式,向读者展示如何在PHP中实现和利用中间件模式来增强代码的可维护性和扩展性。文章将介绍中间件模式的基本概念、核心价值以及如何将其应用于PHP项目。我们将从一个简单的例子出发,逐步构建起一个灵活且强大的中间件系统。无论你是PHP新手还是资深开发者,这篇文章都将为你提供新的视角和实用工具,让你的项目更加健壮和易于管理。