RabbitMQ-Pub/Sub

Pub/Sub订阅模式

RabbitMQ-Pub/Sub_第1张图片
P:生产者,也就是要发送消息的程序,但是不再发送到队列中,而是发给X (交换机)

C:消费者,消息的接收者,会-直等待消息到来

Queue: 消息队列,接收消息、缓存消息

Exchange: 交换机(X) 。- -方面,接收生产者发送的消息。另- -方面,知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。Exchange有 常见以下3种类型:

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

  2. Direct: 定向,把消息交给符合指定routing key的队列

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

Exchange (交换机)只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定,或者没有符合路由规则的队列,那么消息将会丢失。

代码实现

生产者:

package com.sx.producer;

import com.rabbitmq.client.BuiltinExchangeType;
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_PubSub {
     
    public static void main(String[] args) throws IOException, TimeoutException {
     
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.1.3");
        factory.setPort(5672);
        factory.setVirtualHost("/sx");
        factory.setUsername("sx");
        factory.setPassword("123456");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        //创建交换机
        /**
         *  public DeclareOk exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map arguments) throws IOException {
         *         return this.exchangeDeclare(exchange, type.getType(), durable, autoDelete, internal, arguments);
         *     }
         *     exchange:交换机名称
         *     type:交换机类型
         *          DIRECT("direct"),定向
         *          FANOUT("fanout"),广播,发送消息到每一个与之绑定的队列
         *          TOPIC("topic"),通配符
         *          HEADERS("headers");参数匹配
         *      durable:是否持久化
         *      autoDelete:是否自动删除
         *      internal:内部使用,false
         *      arguments:参数
         */

        String exchangeName = "test_fanout";
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.FANOUT, true, false, false, null);

        //创建队列 2个
        String queue1 = "test_fanout_queue1";
        String queue2 = "test_fanout_queue2";
        channel.queueDeclare(queue1, true, false, false, null);
        channel.queueDeclare(queue2, true, false, false, null);

        //绑定队列和交换机
        /**
         * public com.rabbitmq.client.AMQP.Queue.BindOk queueBind(String queue, 
         * String exchange, String routingKey) throws IOException {
         *         return this.queueBind(queue, exchange, routingKey, (Map)null);
         *     }
         *     queue:队列名称
         *     exchange:交换机名称
         *     routingKey:路由键,绑定规则
         *          交换机类型为fanout,routingKey设置为""
         */
        channel.queueBind(queue1, exchangeName, "");
        channel.queueBind(queue2, exchangeName, "");

        String body = "log";
        //发送消息
        channel.basicPublish(exchangeName, "", null, body.getBytes());

        //释放资源
        channel.close();
        connection.close();

    }
}

消费者C1

package com.sx.consumer;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Consumer_PubSubC1 {
     
    public static void main(String[] args) throws IOException, TimeoutException {
     
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.1.3");
        factory.setPort(5672);
        factory.setVirtualHost("/sx");
        factory.setUsername("sx");
        factory.setPassword("123456");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        Consumer consumer = new DefaultConsumer(channel) {
     
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
     
                System.out.println("body = " + new String(body));
                System.out.println("完成事件A");
            }
        };
        channel.basicConsume("test_fanout_queue1", true, consumer);
    }
}

消费者C2

package com.sx.consumer;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Consumer_PubSubC2 {
     
    public static void main(String[] args) throws IOException, TimeoutException {
     
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.1.3");
        factory.setPort(5672);
        factory.setVirtualHost("/sx");
        factory.setUsername("sx");
        factory.setPassword("123456");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        Consumer consumer = new DefaultConsumer(channel) {
     
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
     
                System.out.println("body = " + new String(body));
                System.out.println("完成事件B");
            }
        };
        channel.basicConsume("test_fanout_queue2", true, consumer);
    }
}

运行结果

RabbitMQ-Pub/Sub_第2张图片
RabbitMQ-Pub/Sub_第3张图片
每一个消费者都监听他自己的队列,生产者发送消息后每一个消费者都可以收到对应的消息并进行相应的处理。

你可能感兴趣的:(rabbitmq,java)