RabbitMQ简介及简单使用


参考蚂蚁课堂

1.RabbitMQ基本介绍

RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件),RabbitMQ服务器是用Erlang语言编写的。然后我们安装rabbitMQ就行了,安装完之后访问localhost://15672即可进入到rabbitMQ管理平台,然后输入账号密码登录,账号密码为guest,guest。

在这里插入图片描述

这里面有一个Virutual Hosts的概念,这个相当于RabbitMQ的虚拟消息服务器VirtualHost,每个VirtualHost相当于一个相对独立的RabbitMQ服务器,每个VirtualHost之间是相互隔离的,exchange,queue,message不能互通。

然后我们看一下RabbitMQ常见的端口号

15672 — RabbitMQ管理平台的端口号

25672 — 集群通信端口号

Amqp 5672 — RabbitMQ内部通信的一个端口号

2.RabbitMQ简单使用案例

RabbitMQ使用的一般步骤首先要在管理平台端创建一个队列,然后编写生产者代码,然后编写消费者代码。

2.1在RabbitMQ平台上创建一个队列

首先先创建一个VirtualHost,然后设置Permission设置成自己的账号guest

在这里插入图片描述

在这里插入图片描述

然后我们就可以在这个VirtualHost里面创建Queue。
添加队列的时候要指明这个队列属于哪个VirtualHost,然后设置一个队列名称,然后Durability设置是否可以持久化。然后添加就完事了。

2.2编写生产者代码

这个生产者的任务就是向消息队列中投放消息,首先他必须要和RabbitMQ建立一个连接。

public class RabbitMQConnection {
   
    public static Connection getConnection() throws IOException, TimeoutException {
   
        //1.创建connectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //2.配置Host
        connectionFactory.setHost("127.0.0.1");
        //3.设置Port
        connectionFactory.setPort(5672);
        //4.设置账户和密码
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        //5.设置VirtualHost
        connectionFactory.setVirtualHost("/wjzVirtualHost");
        return connectionFactory.newConnection();
    }
}

配置好我们的IP地址端口号和VirtualHost。然后我们编写生产者代码

public class Producer {
   
    private static final String QUEUE_NAME = "wjz-queue";

    public static void main(String[] args) throws IOException, TimeoutException {
   
        //1.创建一个新连接
        Connection connection = RabbitMQConnection.getConnection();
        //2.设置channel
        Channel channel = connection.createChannel();
        //3.发送消息
        String msg = "wjz,nb!!!";
        channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
        System.out.println("消息投递成功");
        channel.close();
        connection.close();
    }
}

生产者这边要建立和RabbitMQ服务器之间的连接,然后向消息队列中发送消息,然后关闭连接。然后basicPublish第一个参数是交换机我们这个比较简单就没有,然后第二个是消息队列名称你的队列的名叫啥你就写啥,第三个参数是props一些配置信息比如说过期时间,优先级,投递模式之类的,第四个参数是消息。

然后我们运行一下看看这条消息有没有被投递到MQ服务器。

在这里插入图片描述

在这里插入图片描述

如图所示,队列里的Ready为1,然后我们下一步就是把消息队列里的消息从队列中取出来。

2.3编写消费者代码

public class Consumer {
   
    private static final String QUEUE_NAME = "wjz-queue";

    public static void main(String[] args) throws IOException, TimeoutException, IOException, TimeoutException {
   
        // 1.创建连接
        Connection connection = RabbitMQConnection.getConnection();
        // 2.设置通道
        Channel channel = connection.createChannel();
        DefaultConsumer defaultConsumer = 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("消费者获取消息:" + msg);
                // 消费者完成 消费该消息
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        // 3.监听队列
        channel.basicConsume(QUEUE_NAME, false, defaultConsumer);

    }
}

消费者我们也是首先创建一个连接,然后设置通道,在这个通道里面拿到消息之后消费掉。最后这个监听队列这个,第二个参数如果设置为true就是自动签收,我获取成功了就会立即从消息队列中移除。但是如果说我这个消息正在处理然后处理失败了,这个时候我要做一个补偿,但是这个时候MQ里已经没有了这条消息。这是不对的所以我们一般都是手动签收把这个参数设置为false。手动签收就是我消费者收到消息之后如果成功消费了会发给MQ一个通知这个时候MQ才会清除。

好了解释完了运行一下看看结果。

在这里插入图片描述

在这里插入图片描述

3.RabbitMQ如何保证消息不丢失

MQ服务器端在默认的情况下都会对队列中的消息实现持久化。所以就算MQ宕机里面的消息也不会丢失。

在这里插入图片描述

如图所示为了保证消息不丢失RabbitMQ有一个消息确认机制,生产者向队列投递一条消息,同时MQ回向生产者返回一个消息确认。这样就确保了生产者投递信息到MQ一定是成功的。这个MQ发回给生产者的Ack可以使用同步或者异步机制,同步的话就是如果MQ服务器不返回确认生产者就会阻塞,异步的话就是有一个观察者监听是否投递成功,如果投递成功MQ返回一个确认给生产者。

消费者必须要将消息消费成功之后就会发一个通知给MQ服务器让MQ把消息从队列当中删除。

4.RabbitMQ工作队列

默认的传统队列是为均摊消费,存在不公平性;如果每个消费者速度不一样的情况下,均摊消费是不公平的。我们希望达到一个能者多劳的效果。这就需要我们采用工作队列。工作队列的实现就是两个消费者能者多劳,能力强的多分配,能力弱的少分配,我们可以通过channel.basicQos(int);这个函数来设置这个消费者一次要从队列中拉取多少条消息,同时给MQ服务器端发送一个Ack确认消息已经被处理了这样MQ会从队列中删除这条消息。

下面我们可以通过代码来演示一下这个效果

producer

public class Producer {
   
    private static final String QUEUE_NAME = "wjz-queue";

    public static void main(String[] args) throws IOException, TimeoutException {
   
        //1.创建一个新连接
        Connection connection = RabbitMQConnection.getConnection();
        //2.设置channel
        Channel channel = connection.createChannel();
        //3.发送消息
        for (int i = 0; i < 10; i++) {
   
            String msg = "wjz nb:i" + i;
            channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
        }
        System.out.println("消息投递成功");
        channel.close();
        connection.close();
    }
}

首先这个生产者会和MQ服务器建立一个连接,然后向MQ中投放10条消息。

consumer1

public class Consumer1 {
   
    private static final String QUEUE_NAME = "wjz-queue";

    public static void main(String[] args) throws IOException, TimeoutException, IOException, TimeoutException {
   
        // 1.创建连接
        Connection connection = RabbitMQConnection.getConnection();
        // 2.设置通道
        Channel channel = connection.createChannel();
        //指定我们消费者每次批量获取消息
        channel.basicQos(2);
        DefaultConsumer defaultConsumer = 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("消费者获取消息:" + msg);
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温JZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值