rabbitmq 基础知识

221 阅读6分钟

基于 tcp 协议,建立真实的 tcp 连接内的虚拟连接,每条 tcp 连接上的信道没有限制

mq缺点:

1、系统可用性降低了:本来A调用B好好的,突然加入个消息队列,mq挂了,系统不能运行了

2、系统复杂度提高:一致性问题、如何保证消息不被重复消费、如何保证消息可靠性传输等

3、一致性问题:异步处理,AB都执行成功了,但是C失败了,导致数据不一致

优势:

1、erlang语言天生支持高并发

2、中小型公司,用这个正好

主要解决的问题:消峰,解耦,异步

高级特性:

1.可靠性投递:成功发出,mq节点成功接收,发送端收到mq节点(broker)确认应答,完善的消息进行补偿机制

2.幂等性:乐观锁,一个消息同一时间只能被一个消费者消费

3.confirm确认消息:broker发送一个消息给生产者,保证消息成功发送到broker

4.return消息机制:ReturnListener 处理一些不可路由的消息,就是消息找不到队列(queue),routing key有问题

5.消费端自定义监听:自定义消费者

6.消费端限流:qos功能,不能自动签收

7.消费端的ack与重回队列:一般不开启重回队列

8.TTL:Time To Live,生存时间的意思(过期时间,消息队列的消息过期之后就会自动清除)

9.死信队列:Deal-Letter-Exchange

影响性能的因素:

1、持久化IO 、磁盘IO操作
解决办法:批量处理 + 缓冲区

2、消费者消费能力太低,造成消息堆积
解决办法:消费者集群,批量拉取

各种mq的对比

activeMqrabbitMqrocketMqkafka
开发语言javaerlangjavascala
单机吞吐量万级万级10万级10万级
实效性msusmsms
可用性非常高非常高
功能特性很成熟,各种协议支持的较好并发能力很强,性能及其好,延时很低功能比较完备,扩展性佳为大数据准备的

a. kafka  编程语言:java/scala

b. RabbitMq  编程语言:erlang

c. RocketMq  编程语言:java  (大一点的公司)  它的前身:Notify

d. ActiveMq  编程语言:java (小公司)

命令

// 启动:
1、rabbitmq-server start 
2、rabbitmq-server start  
3、/sbin/service rabbitmq-server start  
   
// 停止:
rabbitmq-server stop  

// 查看的状态:
1、rabbitmqctl status  
2、rabbitmqctl status | grep rabbit 

结构

image.png

解释:

1、borker:中介,相当于一个 mq 程序

2、exchange:交换机,绑定的列表,它和队列是多对多的关系
  它的属性:
    name:姓名
    type:类型 --- > direct,topic,fanout
    internal:当前exchange是否用户rabbitmq内部使用,一般都是false
    arguments:扩展参数,用户amqp协议自制定化使用
    auto delete:自动删除,交换机最后一个消息消费后,交换机自动删除
    durability:是否需要持久化,true
  
3、channel:信道,虚拟链接

4、queue:独立的进程,存放消息(有数据库,erlang语言)
   push:推送模式
   pull:拉取模式

交换机

1、基本类型:一个提供者,一个队列,一个消费者
2、工作模型:一个提供者,一个队列,多个消费者

发布/订阅模式(多个队列):
3、fanout exchange:没有routingkey,队列和交换机直接绑定(消息转发速度最快)

4、direct exchange:队列和交换机的routingkey完全匹配,才能进行消息的转发

5、topic exchange:可以进行模糊匹配
  #:可以匹配一个或多个单词
  *:只可以匹配一个单词

6、headers exchange:用消息头进行路由,不怎么常用

AMQP

什么是 AMQP 协议?

Advaced Message Queue,高级消息队列协议(应用层协议),不受产品、开发语言等条件的限制

AMQP 和JMS 的区别?

1、jms 定义统一的接口,对消息操作进行统一;amqp规定了统一数据交互的格式

2、jms 是针对java语言;amqp是协议,任何语言都可以实现

3、jms 规定了两种消息模型;amqp的消息模式更加丰富

设计模式

1、观察者模式

观察者模式里面,changed()方法所在的实例对象,就是被观察者(Subject,或者叫Observable)

它只需维护一套观察者(Observer)的集合,这些Observer实现相同的接口,Subject只需要知道,通知Observer时,需要调用哪个统一方法就好了

2、发布订阅模式

发布者只需告诉Broker,我要发的消息,topic是AAA;

订阅者只需告诉Broker,我要订阅topic是AAA的消息;

于是,当Broker收到发布者发过来消息,并且topic是AAA时,就会把消息推送给订阅了topic是AAA的订阅者。当然也有可能是订阅者自己过来拉取,看具体实现。

也就是说,发布订阅模式里,发布者和订阅者,不是松耦合,而是完全解耦的。

image.png


死信队列

什么是死信队列?没有被及时消费的队列

没有被及时消费的原因:

1、消息被拒绝

2、TTL 消息超时未被消费

3、达到队列的最大程度

消息变成死信后,会被重新投递(publish)到另一个交换机上(Exchange),
这个交换机往往被称为DLX(dead-letter-exchange)“死信交换机”,然后交换机根据绑定规则转发到对应的队列上,
监听该队列就可以被重新消费。

生产者-->发送消息-->交换机-->队列-->变成死信队列-->DLX交换机-->队列-->监听-->消费者 

拓展:

发送者发送消息的时候,如果队列长度满了,默认的策略是,丢弃最早进入队列消息的策略

但是我们可以对此进行修改(设置 overflow 为 reject - publish),此时将最新到的消息直接丢弃。

如果开启了 confirm 模式,mq 会通过 basic.nack 的方式对发送者进行消息拒绝

相关配置博客

集群模式

1、单机模式(standalone)

2、普通集群模式

运作过程:
1、创建的 queue,只会放在一个 RabbitMQ 实例上,但是每个实例都同步 queue 的元数据
  (元数据可以认为是 queue 的一些配置信息,通过元数据,可以找到 queue 所在实例)
  
2、你消费的时候,实际上如果连接到了另外一个实例,那么那个实例会从 queue 所在实例上拉取数据过来

image.png

会出现的问题:

1、mq 集群内部会有大量数据传输

2、一个节点宕机,如果消息和队列没有持久化,数据就丢了

3、镜像集群模式

特点:这个模式下,不论是你创建的 queue 还是 发送的消息,都会在集群内部进行同步,保证了消息的一致性

缺点:
1、消息同步给带宽带来的压力很大
2、这样就不是分布式了,因为每台 mq 机器都有集群中的所有数据,所以扩展性很差

image.png

扩展:什么是 node ,cluster,broker?

node:集群中的一个 mq 节点

cluster (翻译:集群):在broker的基础之上,增加了node之间共享元数据的约束

broker:指一个或多个 erlang node 的逻辑分组

关系图:

image.png