rabbitmq - helloworld

定个小目标,写一个能跑起来的程序。

添加用户赋予管理员权限

开始编码之前,先创建一个账号,命令详细说明以后再说。

注意:命令要启动服务之后执行。

# 1. 添加用户和密码:
rabbitmqctl.bat add_user root root

# 2. 设置用户根为管理员角色:
rabbitmqctl.bat set_user_tags root administrator

# 3. 设置访问权限:
rabbitmqctl set_permissions -p / root ".*" ".*" ".*"

添加maven依赖

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

获取消息队列的连接

import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * @author Mr.css
 * @version 2021-06-23 16:52
 */
public class ConnectionUtil {
    private static final Logger logger = LoggerFactory.getLogger(ConnectionUtil.class);

    public static Connection getConnection() throws IOException, TimeoutException {
        ConnectionFactory factory = new ConnectionFactory();
        // 设置服务端地址(域名地址/ip)
        factory.setHost("127.0.0.1");
        // 设置服务器端口号,最易犯的错误就是填写为15672(网页端口),正确为5672
        factory.setPort(5672);
        // 设置虚拟主机(相当于数据库中的库)
        factory.setVirtualHost("/");
        // 设置用户名
        factory.setUsername("root");
        // 设置密码
        factory.setPassword("root");
        return factory.newConnection();
    }

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = getConnection();
        System.out.println(connection);
        connection.close();
    }
}

生产者

import com.rabbitmq.client.*;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.concurrent.TimeoutException;

/**
 * @author Mr.css
 * @version 2020-11-12 19:30
 */
public class Publish {
    /**
     * 队列名称
     */
    private static final String QUEUE_NAME = "queue_name";
    /**
     * 路由键,交换机会根据路由键,把消息推到队列,
     * 如果路由键与队列名称一致的情况,消息会被精准推送到同名的队列
     */
    private static final String ROUTING_KEY = QUEUE_NAME;

    public static void main(String[] args) {
        try {
            Connection connection = ConnectionUtil.getConnection();
            Channel channel = connection.createChannel();
            // 声明队列
            channel.queueDeclare(QUEUE_NAME, false, false, false, null);

            int cnt = 10;
            while (cnt-- > 0) {

                String message = "This is simple queue:" + cnt;

                // 发送消息
                channel.basicPublish("", ROUTING_KEY, null, message.getBytes(Charset.defaultCharset()));
                System.out.println("[send]:" + message);
            }

            channel.close();
            connection.close();
        } catch (IOException | TimeoutException e) {
            e.printStackTrace();
        }
    }
}

channel.queueDeclare()

作用

  1. 声明队列时,如果已经存在则放弃声明,如果不存在则会声明一个新队列;
  2. 队列名可以任意取值,但需要与消息接收者一致。

参数说明

  • String queue:队列名称
  • boolean durable:是否持久化
  • boolean exclusive:是否排他,只允许一个消费者
  • boolean autoDelete:自动删除,如果没有消息也没有消费者,自动删除队列
  • Map<String, Object> arguments:附加属性

channel.basicPublish() 参数说明

用于发送消息

  • String exchange:交换机名词,"" 表示不用交换机
  • String routingKey:队列名称,如果使用交换机,就是路由键,用于模糊匹配队列名的表达式
  • BasicProperties props: 消息头,消息的附加属性
  • byte[] body:消息体

消费者



import com.rabbitmq.client.*;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeoutException;

/**
 * @author Mr.css
 * @version 2020-11-12 19:31
 */
public class Receive {
    private static final String QUEUE_NAME = "queue_name";

    public static void main(String[] args) {
        try {
            Connection connection = ConnectionUtil.getConnection();
            Channel channel = connection.createChannel();

            // 消息消费者
            DefaultConsumer consumer = new DefaultConsumer(channel) {

                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
                                           byte[] body) {
                    String message = new String(body, StandardCharsets.UTF_8);
                    System.out.println("[Receive]:" + message);
                }
            };

            // 设置消息消费者
            channel.basicConsume(QUEUE_NAME, true, consumer);
        } catch (IOException | ShutdownSignalException | ConsumerCancelledException | TimeoutException e) {
            e.printStackTrace();
        }
    }
}

consumer.handleDelivery() 参数说明

consumerTag

消费者标签,每次重启都会被重新分配

Envelope

这个对象的直译是信封,非常形象的词,与现实信封的作用一致。

  • long _deliveryTag:标签,自增 ID,每次消息投递或者重新投递,都会递增
  • boolean _redeliver:是否重新投递
  • String _exchange:路由
  • String _routingKey:路由键

channel.basicConsume() 参数说明

autoAck:消息自动确认,置为 false 之后,需要我们在完成消费之后进行确认。

消息 ACK 机制,这是 MQ 通用的一种机制,MQ 都会存在相关设计。

我们拿到消息,不代表我们真的想要这个消息,瞅一眼,无法处理的话,还需要退还到对列中;

再举一个例子:消息消费过程中,程序被强制中断,需要有一个机制,将消息退还到队列中。

posted on   疯狂的妞妞  阅读(17)  评论(0编辑  收藏  举报

(评论功能已被禁用)
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
历史上的今天:
2020-03-25 SpringCloud(三)服务消费
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示