RabbitMQ 简单的 Hello World 程序

要想使用RabbitMQ客户端的API,首先要引入依赖。

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

无论是生产消息还是消费消息,都要先获取RabbitMQ的连接!

        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("49.232.202.201");
        //factory.setPort(5672);//默认端口是5672可以不设置
        factory.setUsername("gosuncn");
        factory.setPassword("123456");
        factory.setVirtualHost("/gosuncn");//根据虚拟主机权限设置,设置具有可访问权限的虚拟主机。

创建一个连接工厂,设置主机、端口、用户名、密码、虚拟主机等信息。

Connection connection = factory.newConnection();

通过连接工厂,获取一个信道 Channel ,通过信道进行数据传输;那么信道是什么?

我们知道:RabbitMQ通过TCP连接实现AMQP协议数据的交换,但TCP连接的创建和销毁都是非常消耗资源的!于是,RabbitMQ就通过信道的方式进行数据传输,具体来说,如果把TCP连接比作是一个大的管道,那么信道就是TCP这个大管道中的一个小管道。

Channel channel = connection.createChannel();

信道可以声明一个队列:如果声明的队列不存在,就创建一个队列;若已存在,就不创建。

        /**
         * String queue 队列名称
         * boolean durable 是否持久化
         * boolean exclusive 是否排外[比如:一个消费者已经连接该队列,如果设置为true,其他消费者就无法连接该队列]
         * boolean autoDelete 是否自动删除[没有信道连接该队列时,是否自动删除该队列]
         * Map<String, Object> arguments 参数
         */
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

Tip:若一个队列已经声明被创建,那么队列的属性就不可以更改,否则抛出异常

channel.queueDeclare(QUEUE_NAME, false, false, false, null);

再执行以下代码就会,抛出异常!

channel.queueDeclare(QUEUE_NAME, false, true, false, null);

属性不可再更改了!

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

public class SendMessage {
    private final static String QUEUE_NAME = "hello";
    private final static String MESSAGE = "Hello World";
    public static void main(String[] args) {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("49.232.202.201");
        //factory.setPort(5672);//默认端口是5672可以不设置
        factory.setUsername("gosuncn");
        factory.setPassword("123456");
        factory.setVirtualHost("/gosuncn");//根据虚拟主机权限设置,设置具有可访问权限的虚拟主机。
        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {
            /**
             * String queue 队列名称
             * boolean durable 是否持久化
             * boolean exclusive 是否排外[比如:一个消费者已经连接该队列,如果设置为true,其他消费者就无法连接该队列]
             * boolean autoDelete 是否自动删除[没有信道连接该队列时,是否自动删除该队列]
             * Map<String, Object> arguments 参数
             */
            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
            channel.basicPublish("", QUEUE_NAME, null, MESSAGE.getBytes());
            System.out.println("message [" + MESSAGE + "] be sent");
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}

将连接和信道声明在try后的括号中,可自动调用关闭方法。

上面代码,第一次运行会创建一个名为hello的队列,第二次运行就不会创建了,这样可以保证虚拟主机中有一个名为hello的队列。

channel.basicPublish("", QUEUE_NAME, null, MESSAGE.getBytes());

第一个参数是交换机的名称,"" 表示默认交换机,类型其实是属于直连交换机,以后会具体介绍交换机类型。

第二个参数是路由的名称,在连接默认交换机时,路由键其实就是队列的名称。

第三个参数是属性对象。

第四个参数是发送的消息字节数组。

运行结果:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
message [Hello World] be sent

Process finished with exit code 0


接下来,我们再看看消费者代码

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 ReceiveMessage {

    private final static String QUEUE_NAME = "hello";

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("49.232.202.201");
        //factory.setPort(5672);//默认端口是5672可以不设置
        factory.setUsername("gosuncn");
        factory.setPassword("123456");
        factory.setVirtualHost("/gosuncn");//根据虚拟主机权限设置,设置具有可访问权限的虚拟主机。
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        /**
         * String queue 队列名称
         * boolean durable 是否持久化
         * boolean exclusive 是否排外[比如:一个消费者已经连接该队列,如果设置为true,其他消费者就无法连接该队列]
         * boolean autoDelete 是否自动删除[没有信道连接该队列时,是否自动删除该队列]
         * Map<String, Object> arguments 参数
         */
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        channel.basicConsume(QUEUE_NAME, true, (consumerTag, message) -> {
            System.out.println("DeliverCallback's consumerTag is {" + consumerTag + "}");
            System.out.println("消费消息的内容 = " + new String(message.getBody()));
        }, consumerTag -> System.out.println("CancelCallback's consumerTag is {" + consumerTag + "}"));
    }
}

前面都是同样的声明,不同的是:

第一个:我们并没有将ConnectionChannel写在try的括号里。因为,我们不能关闭消费者,我们需要等待接收消息到来。

Connection connection = factory.newConnection();
Channel channel = connection.createChannel();

第二个:同样是要声明一个队列,来确保虚拟主机中,有这么一个队列存在,不然会抛出异常!但是不同的是我们需要消费消息:

        channel.basicConsume(QUEUE_NAME, true, (consumerTag, message) -> {
            System.out.println("DeliverCallback's consumerTag is {" + consumerTag + "}");
            System.out.println("消费消息的内容 = " + new String(message.getBody()));
        }, consumerTag -> System.out.println("CancelCallback's consumerTag is {" + consumerTag + "}"));

第一个参数:队列的名称。
第二个参数:是否自动确认消息。
第三个参数:收到消息后的消息回调。
第四个参数:消息被取消时的回调。

ReceiveMessage程序启动后,将进入阻塞状态,一直等待消息!


测试运行,第一步将ReceiveMessage程序启动,程序阻塞
在这里插入图片描述
第二步:运行SendMessage程序
在这里插入图片描述
图中,看到程序结束,消息被发送到了RabbitMQ中。紧接着,之前的ReceiveMessage程序收到消息,并输出的消息内容,如图:
在这里插入图片描述
第三步:再运行SendMessage程序一次,ReceiveMessage程序又收到一条消息
在这里插入图片描述
客官!到这里,RabbitMQ基本的操作和运行就结束了。拜拜~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值