Java使用RabbitMQ(六)--订阅发布

发布订阅模式
这一篇主要是java 客户端使用rabbitMQ发布和订阅消息。
前面几篇讲的是将一个消息只发给一个worker,这里讲的是将一个消息同时发给多个订阅者,也就是发布/订阅模式。

为了阐明这种模式,这里将创建一个简单的日志系统,这个系统由2部分组成:第一部分,发送日志消息;第二部分接收和打印日志消息。

在这个日志系统中,复制了一份receiver,一个接收者用来把收到的消息存储到硬盘中,另一个用来把消息展示到屏幕上。

在前面的文章中,我们通过队列发送和接收消息,现在将介绍一种新的消息模式。

Exchanges (交换机)

这种模式的核心思想是:生产者从不直接发送消息到任意一个队列中,也不知道消息将被发送到哪个队列中,而是把消息发送到交换机中,

交换机 是一个简单的东西,它一方面从生产者这里接收消息,另一方面将收到的消息发送到队列中。但交换机必须知道怎么处理它收到的消息,是放到指定的队列中?放到很多个队列中?还是应该丢弃?这个规则,由exchange type定义。
这里写图片描述

一些可用的交换机模型:direct, topic, match,trace,headers 和fanout。
默认使用的direct。
在前面的文章中,我们不知道交换机的存在,仍然能给发送消息到队列中,是因为使用了默认的交换机

channel.basicPublish("", "hello", null, message.getBytes());

第一个参数“”就是交换机的名字

channel.exchangeDeclare("logs", "fanout");

上面声明了交换机的名字和类型。
fanout是把它收到的消息广播给所有的它知道的队列(绑定到这个交换机的队列)。这也是这个日志系统所用到的。

String queueName = channel.queueDeclare().getQueue();

这会创建一个非持久的,唯一的,自动删除的队列。

如果没有消费者接收消息,消息会消失。
生产者代码:

public static void main(String[] args) {
        try(Connection connection=getConnection("guest","guest","localhost",5672,"/");
            Channel channel=connection.createChannel()) {

            channel.exchangeDeclare(args[0],"fanout");
            String queueName= channel.queueDeclare().getQueue();
            System.out.println(queueName);
            String message=getMessage(new String[]{"a","b","c"});
//            channel.queueBind(queueName,args[0],"");
            int i=0;
            while (true){
                Thread.sleep(1000);
                channel.basicPublish(args[0],queueName, MessageProperties.PERSISTENT_TEXT_PLAIN,(i+++message).getBytes("utf-8"));
            }

//            Thread.sleep(2000);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

消费者代码:

 public static void main(String[] args) {
        try(Connection connection=BaseTest2.getConnection("guest","guest","localhost",5672,"/");
            Channel channel=connection.createChannel()) {

            channel.exchangeDeclare(args[0],"fanout");
//            channel.queueDeclare(BaseTest2.queueName,true,false,false,null);
            String queueName= channel.queueDeclare().getQueue();
            channel.queueBind(queueName,args[0],"");
            System.out.println(queueName);
            Consumer consumer=new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                    String message = new String(body, "UTF-8");
                    try {
                        doWork(message);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        System.out.println(message+" [x] Done");
                    }
                    channel.basicAck(envelope.getDeliveryTag(),false);
                }
            };
            channel.basicConsume(queueName,false, consumer);
            Thread.sleep(200000);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 安装RabbitMQ 先下载RabbitMQ,然后安装,安装过程不再赘述。 2. 引入依赖 在pom.xml中加入以下依赖: ``` <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.6.0</version> </dependency> ``` 3. 发送消息 创建一个发送消息的类,代码如下: ```java public class Sender { private final static String QUEUE_NAME = "hello"; public static void main(String[] args) throws IOException, TimeoutException { // 创建连接工厂 ConnectionFactory factory = new ConnectionFactory(); // 设置连接的主机名 factory.setHost("localhost"); // 创建连接 Connection connection = factory.newConnection(); // 创建一个通道 Channel channel = connection.createChannel(); // 声明一个队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 发送消息 String message = "Hello World!"; channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8")); System.out.println(" [x] Sent '" + message + "'"); // 关闭通道和连接 channel.close(); connection.close(); } } ``` 4. 订阅消息 创建一个订阅消息的类,代码如下: ```java public class Receiver { private final static String QUEUE_NAME = "hello"; public static void main(String[] args) throws IOException, TimeoutException { // 创建连接工厂 ConnectionFactory factory = new ConnectionFactory(); // 设置连接的主机名 factory.setHost("localhost"); // 创建连接 Connection connection = factory.newConnection(); // 创建一个通道 Channel channel = connection.createChannel(); // 声明一个队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); System.out.println(" [*] Waiting for messages. To exit press CTRL+C"); // 创建消费者 Consumer consumer = new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body, "UTF-8"); System.out.println(" [x] Received '" + message + "'"); } }; // 监听队列 channel.basicConsume(QUEUE_NAME, true, consumer); } } ``` 5. 运行程序 先运行Receiver类,在控制台可以看到等待消息的提示。然后运行Sender类,在控制台可以看到发送的消息和接收到的消息。 这样就完成了使用Java采用RabbitMQ实现消息发送及订阅的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值