RabbitMQ——简单模式

简单模式(Simple)

在这一部分中,我们将用Java编写两个程序;
一个是生产者发送单个消息,另一个是接收消息并将其打印出来的消费者。
简单模式
P:生产者;红色部分:队列;C:消费者

The Java client library
RabbitMQ支持多种协议。本教程使用AMQP 0-9-1,它是一种开放的,通用的消息传递协议。
RabbitMQ有许多不同语言的客户端。我们将使用RabbitMQ提供的Java客户端。
下载客户端库及其依赖项(SLF4J API和SLF4J Simple)。
请注意SLF4J Simple足以用于教程,但您应该使用像生产中的Logback这样的完整日志库。
(RabbitMQ Java客户端也位于Maven中央存储库中,包含groupId com.rabbitmq和artifactId amqp-client。)

现在我们有了Java客户端及其依赖项,我们可以编写一些代码。

Sending

Sending

我们消息发布者(sender)定义为对象Send,消息消费者(接收者)定义为对象Recv。发布者将连接到RabbitMQ,发送单个消息,然后退出。
导入相关依赖:

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

获取MQ连接:

import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class ConnectionUtils {

    public static Connection getConnection() throws Exception{
        //定义连接工厂
        ConnectionFactory factory=new ConnectionFactory();
        //设置服务地址
        factory.setHost("localhost");
        //设置端口
        factory.setPort(5672);
        //设置账号信息:用户名、密码、vhost
        factory.setVirtualHost("testhost");
        factory.setUsername("admin");
        factory.setPassword("123456");
        //通过工程获取连接
        Connection connection=factory.newConnection();
        return connection;
    }
}

生产者发送消息到队列:

public class Send {
    private final static String QUEUE_NAME="hello";     //命名队列
    public static void main(String[] args) throws Exception{

        try (Connection connection= ConnectionUtils.getConnection(); Channel channel=connection.createChannel()){
            //声明队列
            channel.queueDeclare(QUEUE_NAME,false,false,false,null);
            String message="hello rabbitMQ!";
            channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
            System.out.println("[x] Sent '"+message+"'");
        }
    }
}

获取连接后创建一个频道,这是完成任务的大部分API所在的位置。注意我们可以使用try-with-resources语句,因为Connection和Channel都实现了java.io.Closeable。
这样我们就不需要在代码中明确地关闭它们。

声明队列是幂等的 —— 只有在它不存在的情况下才会创建它。

管理工具中查看消息

Send代码运行之后,可以在管理工具中看到消息
在这里插入图片描述
点击上面的Name对应的名称,查询具体的队列中的信息:

在这里插入图片描述

Receiving

刚才的是发布者(publisher)。我们的消费者应该一直监听来自RabbitMQ的消息,因此与发布单个消息的发布者不同,我们将保持其运行以监听消息并将其打印出来。

receiving
消费者从队列中获取消息:

public class Recv {
    private final static String QUEUE_NAME="hello";

    public static void main(String[] args) throws Exception{
		//获取连接以及频道
        Connection connection= ConnectionUtils.getConnection();
        Channel channel=connection.createChannel();
		//声明队列
        channel.queueDeclare(QUEUE_NAME,false,false,false,null);
        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
		
        DeliverCallback callback=(consumerTag,delivery)->{
            String message=new String(delivery.getBody(),"UTF-8");
            System.out.println(" [x] Received '" + message + "'");
        };
        //监听队列
        channel.basicConsume(QUEUE_NAME,true,callback,consumerTag->{});
    }
}

请注意,我们也在这里声明了队列。因为我们可能在发布者之前启动消费者,所以我们希望在使用消息之前确保队列存在。

为什么我们这里不使用try-with-resource语句来自动关闭通道和连接?
如果这样做,程序会先运行,然后关闭所有连接,然后退出!这将是尴尬的,因为我们希望在消费者异步监听消息到达时,该进程保持活动状态。

我们要告诉服务器把队列中的消息传递给我。因为它会异步地向我们发送消息,所以我们以对象的形式提供一个回调,它将缓冲消息,直到我们准备好使用它们。这就是DeliverCallback的作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值