RabbitMq工作模式

RabbitMq工作模式

工作队列(又称任务队列)的主要思想是避免立即执行资源密集型任务,而不得不等待它完成。相反我们安排任务在之后执行。我们把任务封装为消息并将其发送到队列。在后台运行的工作进程将弹出任务并最终执行作业。当有多个工作线程时,这些工作线程将一起处理这些任务。

在这个案例中我们会启动两个工作线程,一个消息发送线程,我们来看看他们两个工作线程是如何工作的。

编写获取信道工具类

/**
 * @author zjh
 */
public class RabbitMqUtils {

    public static Channel getChannel() throws Exception {
        // 创建一个连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        // 工厂IP 连接RabbitMq的队列
        factory.setHost("localhost);
        // 用户名
        factory.setUsername("zjh");
        // 密码
        factory.setPassword("zjh");

        // 创建连接
        Connection connection = factory.newConnection();
        // 获取信道
        return connection.createChannel();
    }
}

定义一个生产者, 发送大量消息

/**
 * @author zjh
 * 生产者 发送大量消息
 */
public class TaskOne {

    /**
     * 队列名称
     */
    public static final String QUEUE_NAME = "hello";

    /**
     * 发送大量消息
     */
    public static void main(String[] args) throws Exception {
        // 获取信道
        Channel channel = RabbitMqUtils.getChannel();

        /*
            生成一个队列
            1.队列名称
            2.队列里面的消息是否持久化,默认情况消息存储在内存中
            3.该队列是否只提供一个消费者进行消费 是否进行消息共享,true可以多个消费者消费
            4.是否自动删除 最后一个消费者断开连接以后 该队列是否自动删除 true自动删除 false不自动删除
            5.其他参数
         */
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);
        // 从控制台当中接受信息
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String message = scanner.next();
            /*
                发送一个消费
                1.发送到哪个交换机
                2.路由的Key是哪个,本次队列的名称
                3.其他的参数信息
                4.发送消息的消息体
             */
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
            System.out.println("发送消息完成:" + message);
        }
    }
}

消费者一

/**
 * @author zjh
 * 这是一个工作线程
 */
public class WorkerOne {

    /**
     * 队列名称
     */
    public static final String QUEUE_NAME = "hello";

    /**
     *
     */
    public static void main(String[] args) throws Exception {
        // 获取信道
        Channel channel = RabbitMqUtils.getChannel();

        // 消息接收的回调
        DeliverCallback deliverCallback = (consumerTag, message) -> System.out.println("接收到的消息:" + new String(message.getBody()));

        // 消息接收被取消时,执行以下内容
        CancelCallback cancelCallback = consumerTag -> System.out.println(consumerTag + "消息者取消消费接口回调逻辑");

        /*
            消费者消费信息
            1.消费哪个队列
            2.消费成功之后是否要自动应答 true代表自动应答 false代表手动应答
            3.消费者未成功消费的回调
            4.消费者取消消费的回调
         */
        System.out.println("WorkerOne等待接收消息...");
        channel.basicConsume(QUEUE_NAME, true, deliverCallback, cancelCallback);
    }
}

消费者二

/**
 * @author zjh
 * 这是一个工作线程
 */
public class WorkerTwo {

    /**
     * 队列名称
     */
    public static final String QUEUE_NAME = "hello";

    /**
     *
     */
    public static void main(String[] args) throws Exception {
        // 获取信道
        Channel channel = RabbitMqUtils.getChannel();

        // 消息接收的回调
        DeliverCallback deliverCallback = (consumerTag, message) -> System.out.println("接收到的消息:" + new String(message.getBody()));

        // 消息接收被取消时,执行以下内容
        CancelCallback cancelCallback = consumerTag -> System.out.println(consumerTag + "消息者取消消费接口回调逻辑");

        /*
            消费者消费信息
            1.消费哪个队列
            2.消费成功之后是否要自动应答 true代表自动应答 false代表手动应答
            3.消费者未成功消费的回调
            4.消费者取消消费的回调
         */
        System.out.println("WorkerTwo等待接收消息...");
        channel.basicConsume(QUEUE_NAME, true, deliverCallback, cancelCallback);
    }
}

结果为

默认是以轮询的方式进行消费的 消费者一消费一次,消费者二消费一次以此类推

设置分发方式

/*
    分发模式通过 channel.basicQos设置
    1. 轮询分发:0        默认值
    2. 不公平分发:1      性能好的执行的多,性能不好的执行少
    3. 预取值 也就是指定消费多少条:> 1    指定某个消费者消费多少条数据
 */
channel.basicQos(2);
posted @ 2022-11-15 10:26  橙香五花肉  阅读(19)  评论(0编辑  收藏  举报