RabbitMQ Publish/Subscribe for Java【入门教程 3】

 首先通过上面两个入门教程我们引入本文:

Publish/Subscribe:在上一章中,我们学习创建了一个消息队列,她的每个任务消息只发送给一个队列,然后队列的信息由消费者各自消费。这一章,我们会将同一个任务消息发送给多个队列。这种模式就是“发布/订阅”。为了将消息发送到把那个队列上 我们讲迎来一个新的概念 交换机 。

交换机: RabbitMQ中消息传递模型的核心思想是:生产者不直接发送消息到队列。实际的运行环境中,生产者是不知道消息会发送到那个队列上,她只会将消息发送到一个交换器,交换器也像一个生产线,她一边接收生产者发来的消息,另外一边则根据交换规则,将消息放到队列中。交换器必须知道她所接收的消息是什么?它应该被放到那个队列中?它应该被添加到多个队列吗?还是应该丢弃?这些规则都是按照交换器的规则来确定的。 
 

这里写图片描述 P 是生产者 X是交换机 交换机来决定规则

交换器的规则有:

  • direct (直连)
  • topic (主题)
  • headers (标题)
  • fanout (分发)也有翻译为扇出的。

先直接上代码吧 目录结构如下

生产者:

package wxtest.rabbitMq.Publish_Subscribe;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import wxtest.rabbitMq.ConnectionUtil;

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

public class msgProduce {

    private static String exchage_name = "Msg_exchange";//设置一个交换机

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
//这里开始定义一个交换机  前面介绍的都是直接定义队列
        channel.exchangeDeclare(exchage_name, "fanout");//fanout属于主题订阅方式

        //分发消息
        for (int i = 0; i < 5; i++) {
            String message = "我是交换机的消息 " + i;
            //basicPublish发布的第一个参数属于交换机  第二个参数属于按照routingKey方式发放
            channel.basicPublish(exchage_name, "", null, message.getBytes());
            System.out.println(" [x] Sent '" + message + "'");
        }
        channel.close();
        connection.close();
    }
}

 

email消费者:

package wxtest.rabbitMq.Publish_Subscribe;

import com.rabbitmq.client.*;
import wxtest.rabbitMq.ConnectionUtil;

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

public class emailConsumer {
    private static String exchage_name = "Msg_exchange";//设置一个交换机

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        channel.exchangeDeclare(exchage_name, "fanout");//绑定交换机  定义交换机
        String queueName = channel.queueDeclare().getQueue();//获取队列
        channel.queueBind(queueName, exchage_name, "");//绑定交换机和所对应的队列
        System.out.println(" emailConsumer Waiting for messages. To exit press CTRL+C");
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String msg = new String(body, "UTF-8");
                System.out.println(" consumer1 [x] Received '" + msg + "'");
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        channel.basicConsume(queueName, true, consumer);
    }
}

sms消费者:

package wxtest.rabbitMq.Publish_Subscribe;

import com.rabbitmq.client.*;
import wxtest.rabbitMq.ConnectionUtil;

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

public class smsComsumer {
    private static String exchage_name = "Msg_exchange";//设置一个交换机

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        channel.exchangeDeclare(exchage_name, "fanout");//绑定交换机
        String queueName = channel.queueDeclare().getQueue();
        channel.queueBind(queueName, exchage_name, "");//绑定交换机所对应的队列
        System.out.println(" smsComsumer Waiting for messages. To exit press CTRL+C");
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String msg = new String(body, "UTF-8");
                System.out.println(" smsComsumer [x] Received '" + msg + "'");
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        channel.basicConsume(queueName, true, consumer);
    }
}

emailConsumer输出结构如下:

smsConsumer输出结果如下:

 

可以看出只要我们的消费者绑定了我们消费者的交换机  那么我们交换机的信息就会分发到各路的消费者对应的队列里 供应消费者消费。那么发布订阅就到此为止 下面我们将引入路由routingKey实现固定分发,详情请看本作者博客。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值