RabbitMQ基础总结

RabbitMQ

注:
其中大部分笔记来自B站狂神说–飞哥讲解
视频地址 :https://www.bilibili.com/video/BV1dX4y1V73G?p=1
笔记地址:
https://www.kuangstudy.com/zl/rabbitmq

RabbitMQ简介:

RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue Protocol)的开源实现。

核心概念

Message

消息,消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组

成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出

该消息可能需要持久性存储)等。

Publisher

消息的生产者,也是一个向交换器发布消息的客户端应用程序。

Exchange

交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。

Exchange有4种类型:direct(默认),fanout, topic, 和headers,不同类型的Exchange转发消息的策略有

所区别

Queue

消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息

可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。

Binding

绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连

接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。

Exchange 和Queue的绑定可以是多对多的关系。

Connection

网络连接,比如一个TCP连接。

Channel

信道,多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内的虚

拟连接,AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这

些动作都是通过信道完成。因为对于操作系统来说建立和销毁 TCP 都是非常昂贵的开销,所

以引入了信道的概念,以复用一条 TCP 连接。Consumer

消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。

Virtual Host

虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加

密环境的独立服务器域。每个 vhost 本质上就是一个 mini 版的 RabbitMQ 服务器,拥有

自己的队列、交换器、绑定和权限机制。vhost 是 AMQP 概念的基础,必须在连接时指定,

RabbitMQ 默认的 vhost 是 / 。

Broker

表示消息队列服务器实体

在这里插入图片描述

img

02、RabbitMQ的运行流程

img

03、RabbitMQ支持消息的模式

参考官网:https://www.rabbitmq.com/getstarted.html

03-1、简单模式 Simple

  • 参考第12章节

03-2、工作模式 Work

  • web操作查看视频
  • 类型:无
  • 特点:分发机制

03-3、发布订阅模式

  • web操作查看视频
  • 类型:fanout
  • 特点:Fanout—发布与订阅模式,是一种广播机制,它是没有路由key的模式。

03-4、路由模式

  • web操作查看视频
  • 类型:direct
  • 特点:有routing-key的匹配模式

03-5、主题Topic模式

  • web操作查看视频
  • 类型:topic
  • 特点:模糊的routing-key的匹配模式

03-6、参数模式

  • web操作查看视频
  • 类型:headers
  • 特点:参数匹配模式

小结

  • rabbitmq发送消息一定有一个交换机
  • 如果队列没有指定交换机会默认绑定一个交换机
    img

img

工作模式介绍

• Work queues(工作队列模式)

• Publish/Subscribe(发布订阅模式)

• Routing(路由模式)

• Topics(通配符模式)

• RPC

• Headers(使用较少,不进行详细介绍)

Work queues (工作队列模式)

在这里插入图片描述

需要指定唯一的消息队列进行消息传递,并且可 以有多个消息消费者。在这种模式下,多个消息 消费者通过轮询的方式依次接收消息队列中存储 的消息,一旦消息被某一个消费者接收,消息队 列会将消息移除,而接收并处理消息的消费者必 须在消费完一条消息后再准备接收下一条消息。

适用于那些较为繁重,并且可以进行拆分处理的业务,这种情况下可以分派给多个 消费者轮流处理业务

Publish/Subscribe(发布订阅模式)、

在这里插入图片描述

在Publish/Subscribe工作模式中,必须先配置一 个fanout类型的交换器,不需要指定对应的路由 (Routingkey),同时会将消息路由到每一 个消息队列上,然后每个消息队列都可以对相同 的消息进行接收存储,进而由各自消息队列关联 的消费者进行消费

适用于进行相同业务功能处理的场合

Routing(路由模式)

在这里插入图片描述

在Routing工作模式中,必须先配置一个direct类 型的交换器,并指定不同的路由键值(Routing key)将对应的消息从交换器路由到不同的消息 队列进行存储,由消费者进行各自消费

适用于进行不同类型消息分类处理的场合

Topics(通配符模式)

在这里插入图片描述

在Topics工作模式中,必须先配置一个topic类型 的交换器,并指定不同的路由键值(Routing key)将对应的消息从交换器路由到不同的消息 队列进行存储,然后由消费者进行各自消费

适用于根据不同需求动态传递处理业务的场合

RPC 介绍

在这里插入图片描述

RPC模式是一个回环结构,主要针对分布式架构 的消息传递业务,客户端Client先发送消息到消 息队列,远程服务端Server获取消息,然后再写 入另一个消息队列,向原始客户端Client响应消 息处理结果。

适用于远程服务调用的业务处理场合

消息队列协议

01、什么是协议

img

我们知道消息中间件负责数据的传递,存储,和分发消费三个部分,数据的存储和分发的过程中肯定要遵循某种约定成俗的规范,你是采用底层的TCP/IP,UDP协议还是其他的自己取构建等,而这些约定成俗的规范就称之为:协议。

所谓协议是指
1:计算机底层操作系统和应用程序通讯时共同遵守的一组约定,只有遵循共同的约定和规范,系统和底层操作系统之间才能相互交流。
2:和一般的网络应用程序的不同它主要负责数据的接受和传递,所以性能比较的高。
3:协议对数据格式和计算机之间交换数据都必须严格遵守规范。

02、网络协议的三要素

1.语法。语法是用户数据与控制信息的结构与格式,以及数据出现的顺序。
2.语义。语义是解释控制信息每个部分的意义。它规定了需要发出何种控制信息,以及完成的动作与做出什么样的响应。
3.时序。时序是对事件发生顺序的详细说明。

比如我MQ发送一个信息,是以什么数据格式发送到队列中,然后每个部分的含义是什么,发送完毕以后的执行的动作,以及消费者消费消息的动作,消费完毕的响应结果和反馈是什么,然后按照对应的执行顺序进行处理。如果你还是不理解:大家每天都在接触的http请求协议:

1:语法:http规定了请求报文和响应报文的格式。
2:语义:客户端主动发起请求称之为请求。(这是一种定义,同时你发起的是post/get请求)
3:时序:一个请求对应一个响应。(一定先有请求在有响应,这个是时序)

而消息中间件采用的并不是http协议,而常见的消息中间件协议有:OpenWire、AMQP、MQTT、Kafka,OpenMessage协议。

面试题:为什么消息中间件不直接使用http协议呢?
1: 因为http请求报文头和响应报文头是比较复杂的,包含了cookie,数据的加密解密,状态码,响应码等附加的功能,但是对于一个消息而言,我们并不需要这么复杂,也没有这个必要性,它其实就是负责数据传递,存储,分发就行,一定要追求的是高性能。尽量简洁,快速。
2:大部分情况下http大部分都是短链接,在实际的交互过程中,一个请求到响应很有可能会中断,中断以后就不会就行持久化,就会造成请求的丢失。这样就不利于消息中间件的业务场景,因为消息中间件可能是一个长期的获取消息的过程,出现问题和故障要对数据或消息就行持久化等,目的是为了保证消息和数据的高可靠和稳健的运行。

03:AMQP协议

AMQP:(全称:Advanced Message Queuing Protocol) 是高级消息队列协议。由摩根大通集团联合其他公司共同设计。是一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。Erlang中的实现有RabbitMQ等。
特性:
1:分布式事务支持。
2:消息的持久化支持。
3:高性能和高可靠的消息处理优势。

AMQP协议的支持者:
img

04:MQTT协议

MQTT协议:(Message Queueing Telemetry Transport)消息队列是IBM开放的一个即时通讯协议,物联网系统架构中的重要组成部分。
特点:
1:轻量
2:结构简单
3:传输快,不支持事务
4:没有持久化设计。
应用场景:
1:适用于计算能力有限
2:低带宽
3:网络不稳定的场景。
支持者:

img

05、OpenMessage协议

img

是近几年由阿里、雅虎和滴滴出行、Stremalio等公司共同参与创立的分布式消息中间件、流处理等领域的应用开发标准。
特点:
1:结构简单
2:解析速度快
3:支持事务和持久化设计。

06、Kafka协议

img

Kafka协议是基于TCP/IP的二进制协议。消息内部是通过长度来分割,由一些基本数据类型组成。
特点是:
1:结构简单
2:解析速度快
3:无事务支持
4:有持久化设计

07、小结

协议:是在tcp/ip协议基础之上构建的一种约定成俗的规范和机制、它的主要目的可以让客户端(应用程序 java,go)进行沟通和通讯。并且这种协议下规范必须具有持久性,高可用,高可靠的性能。

消息队列持久化

1、持久化

简单来说就是将数据存入磁盘,而不是存在内存中随服务器重启断开而消失,使数据能够永久保存。

img

02、常见的持久化方式

ActiveMQRabbitMQKafkaRocketMQ
文件存储支持支持支持支持
数据库支持///

消息的分发策略

1、消息的分发策略

MQ消息队列有如下几个角色

1:生产者
2:存储消息
3:消费者

那么生产者生成消息以后,MQ进行存储,消费者是如何获取消息的呢?一般获取数据的方式无外乎推(push)或者拉(pull)两种方式,典型的git就有推拉机制,我们发送的http请求就是一种典型的拉取数据库数据返回的过程。而消息队列MQ是一种推送的过程,而这些推机制会适用到很多的业务场景也有很多对应推机制策略。

2、场景分析一

img

比如我在APP上下了一个订单,我们的系统和服务很多,我们如何得知这个消息被那个系统或者那些服务或者系统进行消费,那这个时候就需要一个分发的策略。这就需要消费策略。或者称之为消费的方法论。

3、场景分析二

img

在发送消息的过程中可能会出现异常,或者网络的抖动,故障等等因为造成消息的无法消费,比如用户在下订单,消费MQ接受,订单系统出现故障,导致用户支付失败,那么这个时候就需要消息中间件就必须支持消息重试机制策略。也就是支持:出现问题和故障的情况下,消息不丢失还可以进行重发。

4、消息分发策略的机制和对比

  • 发布订阅
  • 轮询分发
  • 公平分发
  • 重发
  • 消息拉取
ActiveMQRabbitMQKafkaRocketMQ
发布订阅支持支持支持支持
轮询分发支持支持支持/
公平分发/支持支持/
重发支持支持/支持
消息拉取/支持支持支持

RabbitMQ-SpringBoot案例 -fanout模式

整体核心

img

01、目标

使用springboot完成rabbitmq的消费模式-Fanout

img

02、实现步骤

1:创建生产者工程:sspringboot-rabbitmq-fanout-producer
2:创建消费者工程:springboot-rabbitmq-fanout-consumer
3:引入spring-boot-rabbitmq的依赖
4:进行消息的分发和测试
5:查看和观察web控制台的状况

具体实现

03、生产者

1、创建生产者工程:sspringboot-rabbitmq-fanout-producer

img

2、在pom.xml中引入依赖

<!--rabbitmq的springbooot依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

3、在application.yml进行配置

server:
  port: 8080

# rabbit配置
spring:
  rabbitmq:
    username: admin
    password: admin
    virtual-host: /
    host: localhost
    port: 5672

4:定义订单的生产者

package com.xuexiangban.rabbitmq.springbootrabbitmqfanoutproducer.service;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * @description:
 * @author: xuke
 * @time: 2021/3/4 22:10
 */
@Component
public class OrderService {


    // 模板方法模式
    @Autowired
    private RabbitTemplate rabbitTemplate;

    // 交换机
    private String exchangeName = "fanout_order_ex";
    // 路由key
    private String routingKey = "";


    /**
     * @return void
     * @Author xuke
     * @Description 下单方法
     * @Date 22:17 2021/3/4
     * @Param [userId, productId, num]
     **/
    public String makeorder(String userId, String productId, Integer num) {
        // 1: 根据用户查询用户是否存在
        // 2: 根据产品id查询产品信息
        String orderId = num+"";
        // 3: 保存订单
        // 4: 发送邮件,sms,短信
        System.out.println("用户:" + userId + ",购买了一个产品:" + productId + "保存订单是:" + orderId);
        // 发送消息
        rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);

        return "success";
    }

}

4、绑定关系

package com.lmh.springboot.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author lai
 * @version 1.0
 * @date 2021/6/24 21:30
 * @description fanout 模式
 */
@Configuration
public class RabbitMqConfig {


    /**
     * 1 声明交换机
     * 2 声明队列
     * 3 绑定关系
     */

    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("mq_fanout_ex",true,false);
    }

    @Bean
    public Queue emailQueue(){
        return new Queue("mq.email.fanout.queue");
    }
    @Bean
    public Queue smsQueue(){
        return new Queue("mq.sms.fanout.queue");
    }
    @Bean
    public Queue weiXinQueue(){
        return new Queue("mq.wx.fanout.queue");
    }

    @Bean
    public Binding binding(){
        return BindingBuilder.bind(emailQueue()).to(fanoutExchange());
    }

    @Bean
    public Binding binding1(){
        return BindingBuilder.bind(smsQueue()).to(fanoutExchange());
    }

    @Bean
    public Binding binding2(){
        return BindingBuilder.bind(weiXinQueue()).to(fanoutExchange());
    }

}

5、进行测试

package com.xuexiangban.rabbitmq.springbootrabbitmqfanoutproducer;

import com.xuexiangban.rabbitmq.springbootrabbitmqfanoutproducer.service.OrderService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootRabbitmqFanoutProducerApplicationTests {

    @Autowired
    private OrderService orderService;

    @Test
    public void contextLoads()  throws  Exception{

        for (int i = 1; i <= 10; i++) {
            String result = orderService.makeorder("100", "100", i);
            Thread.sleep(1000);
            System.out.println(result);
        }
    }

}

04、定义消费者

1、创建消费者工程:springboot-rabbitmq-fanout-consumer

img

2、引入依赖pom.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

3、在application.yml进行配置

server:
  port: 8080

# rabbit配置
spring:
  rabbitmq:
    username: admin
    password: admin
    virtual-host: /
    host: localhost
    port: 5672

4、消费者 - 邮件服务

package com.lmh.springboot.service;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

/**
 * @author lai
 * @version 1.0
 * @date 2021/6/24 22:15
 * @description 邮件服务
 */
@Service
@RabbitListener(queues = {"mq.sms.fanout.queue"})
public class EmailService {

    @RabbitHandler
    public void receiver(String message){
        System.out.println("邮件开始接收消息:" + message);
    }

}

5、消费者 - 短信服务

package com.lmh.springboot.service;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

/**
 * @author lai
 * @version 1.0
 * @date 2021/6/24 22:16
 * @description 短信服务
 */
@Service
@RabbitListener(queues = {"mq.email.fanout.queue"})
public class SmsService {

    @RabbitHandler
    public void receiver(String message){
        System.out.println("短信开始接收消息:" + message);
    }

}

6、消费者 - 微信服务

package com.lmh.springboot.service;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

/**
 * @author lai
 * @version 1.0
 * @date 2021/6/24 22:07
 * @description 微信消息服务
 */
@Service
@RabbitListener(queues = {"mq.wx.fanout.queue"})
public class WeiXinService {

    @RabbitHandler
    public void receiver(String message){
        System.out.println("微信开始接收消息:" + message);
    }

}

7、启动服务SpringbootRabbitmqFanoutConsumerApplication,查看效果

img

RabbitMQ-SpringBoot案例 -direct模式

整合代码代完善

整体核心

img

01、目标

使用springboot完成rabbitmq的消费模式-Fanout

img

02、实现步骤

1:创建生产者工程:sspringboot-rabbitmq-direct-producer
2:创建消费者工程:springboot-rabbitmq-direct-consumer
3:引入spring-boot-rabbitmq的依赖
4:进行消息的分发和测试
5:查看和观察web控制台的状况

具体实现

03、生产者

1、创建生产者工程:sspringboot-rabbitmq-direct-producer

img

2、在pom.xml中引入依赖


3、在application.yml进行配置


4:定义订单的生产者


4、绑定关系


5、进行测试


04、定义消费者

1、创建消费者工程:springboot-rabbitmq-fanout-consumer

img

2、引入依赖pom.xml


3、在application.yml进行配置


4、消费者 - 邮件服务


5、消费者 - 短信服务


6、消费者 - 微信服务


7、启动服务SpringbootRabbitmqFanoutConsumerApplication,查看效果

img

RabbitMQ-SpringBoot案例 -topic模式

整体核心

img

01、目标

使用springboot完成rabbitmq的消费模式-Fanout

img

02、实现步骤

1:创建生产者工程:sspringboot-rabbitmq-direct-producer
2:创建消费者工程:springboot-rabbitmq-direct-consumer
3:引入spring-boot-rabbitmq的依赖
4:进行消息的分发和测试
5:查看和观察web控制台的状况

具体实现

03、生产者

1、创建生产者工程:sspringboot-rabbitmq-direct-producer

img

2、在pom.xml中引入依赖


3、在application.yml进行配置


4:定义订单的生产者


4、绑定关系


5、进行测试


04、定义消费者

1、创建消费者工程:springboot-rabbitmq-fanout-consumer

img

2、引入依赖pom.xml


3、在application.yml进行配置


4、消费者 - 邮件服务


5、消费者 - 短信服务


6、消费者 - 微信服务


7、启动服务SpringbootRabbitmqFanoutConsumerApplication,查看效果

img

RabbitMQ-过期时间TTL

1、概述

过期时间TTL表示可以对消息设置预期的时间,在这个时间内都可以被消费者接收获取;过了之后消息将自动被删除。RabbitMQ可以对消息和队列设置TTL。目前有两种方法可以设置。

  • 第一种方法是通过队列属性设置,队列中所有消息都有相同的过期时间。
  • 第二种方法是对消息进行单独设置,每条消息TTL可以不同。

如果上述两种方法同时使用,则消息的过期时间以两者之间TTL较小的那个数值为准。消息在队列的生存时间一旦超过设置的TTL值,就称为dead message被投递到死信队列, 消费者将无法再收到该消息。

1-1、 设置队列TTL

代码设置


测试类


参数 x-message-ttl 的值 必须是非负 32 位整数 (0 <= n <= 2^32-1) ,以毫秒为单位表示 TTL 的值。这样,值 6000 表示存在于 队列 中的当前 消息 将最多只存活 6 秒钟。

img

1-2、 设置消息TTL

消息的过期时间;只需要在发送消息(可以发送到任何队列,不管该队列是否属于某个交换机)的时候设置过期时间即可。在测试类中编写如下方法发送消息并设置过期时间到队列:


img

expiration 字段以微秒为单位表示 TTL 值。且与 x-message-ttl 具有相同的约束条件。因为 expiration 字段必须为字符串类型,broker 将只会接受以字符串形式表达的数字。
当同时指定了 queue 和 message 的 TTL 值,则两者中较小的那个才会起作用。

RabbitMQ高级-死信队列

概述

DLX,全称为Dead-Letter-Exchange , 可以称之为死信交换机,也有人称之为死信邮箱。当消息在一个队列中变成死信(dead message)之后,它能被重新发送到另一个交换机中,这个交换机就是DLX ,绑定DLX的队列就称之为死信队列。
消息变成死信,可能是由于以下的原因:

  • 消息被拒绝
  • 消息过期
  • 队列达到最大长度

DLX也是一个正常的交换机,和一般的交换机没有区别,它能在任何的队列上被指定,实际上就是设置某一个队列的属性。当这个队列中存在死信时,Rabbitmq就会自动地将这个消息重新发布到设置的DLX上去,进而被路由到另一个队列,即死信队列。
要想使用死信队列,只需要在定义队列的时候设置队列参数 x-dead-letter-exchange 指定交换机即可。

img

在rabbitMQ管理界面中结果

未过期:

img

过期后:

img

流程
img

消息过期的死信队列测试

RabbitMQ运维-持久化机制和内存磁盘的监控

01、RibbitMQ持久化

持久化就把信息写入到磁盘的过程。

02、RabbitMQ持久化消息

img
把消息默认放在内存中是为了加快传输和消费的速度,存入磁盘是保证消息数据的持久化。

03、RabbitMQ非持久化消息

非持久消息:是指当内存不够用的时候,会把消息和数据转移到磁盘,但是重启以后非持久化队列消息就丢失。

04、RabbitMQ持久化分类

RabbitMQ的持久化队列分为:
1:队列持久化
2:消息持久化
3:交换机持久化
不论是持久化的消息还是非持久化的消息都可以写入到磁盘中,只不过非持久的是等内存不足的情况下才会被写入到磁盘中。

05、RabbitMQ队列持久化的代码实现

队列的持久化是定义队列时的durable参数来实现的,Durable为true时,队列才会持久化。

// 参数1:名字  
// 参数2:是否持久化,
// 参数3:独du占的queue, 
// 参数4:不使用时是否自动删除,// 参数5:其他参数channel.queueDeclare(queueName,true,false,false,null);

其中参数2:设置为true,就代表的是持久化的含义。即durable=true。持久化的队列在web控制台中有一个D 的标记

img

测试步骤

1:可以建立一个临时队列

img

2:然后重启rabbit-server服务,会发现持久化队列依然在,而非持久队列会丢失。

systecmctl restart rabbitmq-server

或者docker restart myrabbit

06、RabbitMQ消息持久化

消息持久化是通过消息的属性deliveryMode来设置是否持久化,在发送消息时通过basicPublish的参数传入。

// 参数1:交换机的名字
// 参数2:队列或者路由key
// 参数3:是否进行消息持久化
// 参数4:发送消息的内容channel.basicPublish(exchangeName, routingKey1,             MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());

07、RabbitMQ交换机持久化

和队列一样,交换机也需要在定义的时候设置持久化的标识,否则在rabbit-server服务重启以后将丢失。

// 参数1:交换机的名字// 参数2:交换机的类型,topic/direct/fanout/headers// 参数3:是否持久化channel.exchangeDeclare(exchangeName,exchangeType,true);

RabbitMQ运维-内存磁盘的监控

01、RabbitMQ的内存警告

当内存使用超过配置的阈值或者磁盘空间剩余空间对于配置的阈值时,RabbitMQ会暂时阻塞客户端的连接,并且停止接收从客户端发来的消息,以此避免服务器的崩溃,客户端与服务端的心态检测机制也会失效。
如下图:

img
当出现blocking或blocked话说明到达了阈值和以及高负荷运行了。

02、RabbitMQ的内存控制

参考帮助文档:https://www.rabbitmq.com/configure.html
当出现警告的时候,可以通过配置去修改和调整

02-1、命令的方式

rabbitmqctl set_vm_memory_high_watermark <fraction>

rabbitmqctl set_vm_memory_high_watermark absolute 50MB

fraction/value 为内存阈值。默认情况是:0.4/2GB,代表的含义是:当RabbitMQ的内存超过40%时,就会产生警告并且阻塞所有生产者的连接。通过此命令修改阈值在Broker重启以后将会失效,通过修改配置文件方式设置的阈值则不会随着重启而消失,但修改了配置文件一样要重启broker才会生效。

分析:

rabbitmqctl set_vm_memory_high_watermark absolute 50MB

img

img

02-2、配置文件方式 rabbitmq.conf

当前配置文件:/etc/rabbitmq/rabbitmq.conf

#默认
#vm_memory_high_watermark.relative = 0.4
# 使用relative相对值进行设置fraction,建议取值在04~0.7之间,不建议超过0.7.vm_memory_high_watermark.relative = 0.6
# 使用absolute的绝对值的方式,但是是KB,MB,GB对应的命令如下
vm_memory_high_watermark.absolute = 2GB

03、RabbitMQ的内存换页

在某个Broker节点及内存阻塞生产者之前,它会尝试将队列中的消息换页到磁盘以释放内存空间,持久化和非持久化的消息都会写入磁盘中,其中持久化的消息本身就在磁盘中有一个副本,所以在转移的过程中持久化的消息会先从内存中清除掉。

默认情况下,内存到达的阈值是50%时就会换页处理。
也就是说,在默认情况下该内存的阈值是0.4的情况下,当内存超过0.4*0.5=0.2时,会进行换页动作。

比如有1000MB内存,当内存的使用率达到了400MB,已经达到了极限,但是因为配置的换页内存0.5,这个时候会在达到极限400mb之前,会把内存中的200MB进行转移到磁盘中。从而达到稳健的运行。

可以通过设置 vm_memory_high_watermark_paging_ratio 来进行调整

vm_memory_high_watermark.relative = 0.4

vm_memory_high_watermark_paging_ratio = 0.7(设置小于1的值)

为什么设置小于1,以为你如果你设置为1的阈值。内存都已经达到了极限了。你在去换页意义不是很大了。

04、RabbitMQ的磁盘预警

当磁盘的剩余空间低于确定的阈值时,RabbitMQ同样会阻塞生产者,这样可以避免因非持久化的消息持续换页而耗尽磁盘空间导致服务器崩溃。

默认情况下:磁盘预警为50MB的时候会进行预警。表示当前磁盘空间第50MB的时候会阻塞生产者并且停止内存消息换页到磁盘的过程。
这个阈值可以减小,但是不能完全的消除因磁盘耗尽而导致崩溃的可能性。比如在两次磁盘空间的检查空隙内,第一次检查是:60MB ,第二检查可能就是1MB,就会出现警告。

通过命令方式修改如下:

rabbitmqctl set_disk_free_limit  <disk_limit> 
rabbitmqctl set_disk_free_limit memory_limit  <fraction> 
disk_limit:固定单位 KB MB GB
fraction :是相对阈值,建议范围在:1.0~2.0之间。(相对于内存)

通过配置文件配置如下:

disk_free_limit.relative = 3.0
disk_free_limit.absolute = 50mb
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值