消息队列中间件

你觉得看书没用的时候看书真的是没用的,等有一天你觉得看书是有用的看书就真的是有用的


消息队列常见的比较少
大概是
kafka
rabbitmq
redis
rocketmq
activemq


消息队列有什么优点?
1、解耦
2、异步。减少系统响应时间,提高吞吐量
3、削峰。当上下游系统处理能力存在差距的时候,利用消息队列进行限流控制。在下游有能力处理的时候,再进行分发
4、数据可靠性。中间件可以进行持久化存储,不过需要看具体情况

消息队列有什么缺点?
1、增加复杂度。需要消息队列维护成本
2、暂时的不一致性。异步消息方式可以确保最终的一致性,导致的暂时不一致性问题
3、增加了消息队列可用性问题


rabbitmq

RabbitMQ是一个用Erlang语言实现了AMQP(Advanced Message Queuing Protocol)高级消息队列协议的消息队列服务

在这里插入图片描述

exchange交换器主要分为一下三种:

direct:如果路由键完全匹配,消息就被投递到相应的队列
fanout:如果交换器收到消息,将会广播到所有绑定的队列上
topic:可以使来自不同源头的消息能够到达同一个队列。 使用topic交换器时,可以使用通配符,比如:“*” 匹配特定位置的任意文本, “.” 把路由键分为了几部分,“#” 匹配所有规则等。特别注意:发往topic交换器的消息不能随意的设置选择键(routing_key),必须是由"."隔开的一系列的标识符组成。
header:headers exchange主要通过发送的request message中的header进行匹配,其中匹配规则(x-match)又分为all和any,all代表必须所有的键值对匹配,any代表只要有一个键值对匹配即可。headers exchange的默认匹配规则(x-match)是any。头交换机的路由值基于消息的header数据。

消息基于什么传输?
由于TCP连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶颈。RabbitMQ使用信道的方式来传输数据。信道是建立在真实的TCP连接内的虚拟连接,且每条TCP连接上的信道数量没有限制。

消息怎么路由?
从概念上来说,消息路由必须有三部分:交换器、路由、绑定。生产者把消息发布到交换器上;绑定决定了消息如何从路由器路由到特定的队列;消息最终到达队列,并被消费者接收。

如何确保消息不丢失?
消息持久化的前提是:将交换器/队列的durable属性设置为true,表示交换器/队列是持久交换器/队列,在服务器崩溃或重启之后不需要重新创建交换器/队列(交换器/队列会自动创建)。

通信方式?
RabbitMQ是 消息投递服务,在应用程序和服务器之间扮演路由器的角色,而应用程序或服务器可以发送和接收包裹。其通信方式是一种 “发后即忘(fire-and-forget)” 的单向方式。

怎么实现延迟队列?
利用rabbitmq的死信队列,放入正常队列一段时间后过期进入延迟死信队列,然后消费死信队列(不过有问题,rabbitmq有插件可以实现)


内存节点和磁盘节点的作用?
集群中的节点只有两种类型:内存节点/磁盘节点,单节点系统只运行磁盘类型的节点。在集群中,可选择配置部分节点为内存节点。

内存节点将所有的队列,交换器,绑定关系,用户,权限,和vhost的元数据信息保存在内存中,内存节点的消息也是可以持久化的
磁盘节点将这些信息保存在磁盘中,但是内存节点的性能更高,为了保证集群的高可用性,必须保证集群中有两个以上的磁盘节点,来保证当有一个磁盘节点崩溃了,集群还能对外提供访问服务。在上面的操作中,可以通过如下的方式,设置新加入的节点为内存节点还是磁盘节点。
在这里插入图片描述

集群有几种模式?
rabbitmq有三种模式:单机模式,普通集群模式,镜像集群模式

1、普通集群模式(为增加吞吐量)
意思就是在多台机器上启动多个rabbitmq实例,每个机器启动一个。
但是你创建的queue,只会放在一个rabbtimq实例上,但是每个实例都同步queue的元数据(存放真正实例位置)。消费的时候,实际上如果连接到了另外一个实例,那么那个实例会从queue所在实例上拉取数据过来。
2、镜像集群模式(为实现高可用)
这种模式,才是所谓的rabbitmq的高可用模式,跟普通集群模式不一样的是,你创建的queue,无论元数据还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。
3、rabbitmq适合中小型企业,如果数据量太大可以尝试 建立多个rabbitmq镜像集群,再用中间件负载,做到高可用

坏处在于
第一,性能开销有点大,消息同步所有机器,导致网络带宽压力和消耗很重!
第二,扩展性不好,如果某个queue负载很重,加机器,新增的机器也包含了这个queue的所有数据,并没有办法线性扩展你的queue

rabbitmq持久化分为三个部分:,交换器的持久化、队列的持久化和消息的持久化


rabbitmq重试机制?
利用ack机制,调用channel.basicReject,request设置为true

死信队列?
1、消息被否定确认,使用 channel.basicNack 或 channel.basicReject ,并且此时requeue 属性被设置为false。
2、消息在队列的存活时间超过设置的TTL时间。
3、消息队列的消息数量已经超过最大队列长度。
那么该消息将成为“死信”。
“死信”消息会被RabbitMQ进行特殊处理,如果配置了死信队列信息,那么该消息将会被丢进死信队列中,如果没有配置,则该消息将会被丢弃。


消费模式 推或者拉?
实现RabbitMQ的消费者有两种模式,推模式(Push)和拉模式(Pull)。
RabbitMQ的Channel提供了 basicGet 方法用于拉取消息。


关于rabbitmq的消费速度
可以从rabbitmq 后台监控上看如果消费速度小于生产速度,需要调优或者添加消费者
Concurrency与Prefetch配置
concurrency设置的是对每个listener在初始化的时候设置的并发消费的个数prefetch是每次从一次性从broker里面取的待消费的消息的个数,上面的配置在监控后台看到的效果

如果想实现严格按照顺序的消费,可以对一个queue只设置一个消费者,只配置消费并发数为1

rabbitmq确保消息生产者发送到mq不会丢失?
1、使用事务(性能差)
可以选择用rabbitmq提供的事务功能,在生产者发送数据之前开启rabbitmq事务(channel.txSelect),然后发送消息,如果消息没有成功被rabbitmq接收到,那么生产者会收到异常报错,此时就可以回滚事务(channel.txRollback),然后重试发送消息;如果收到了消息,那么可以提交事务(channel.txCommit)。但是问题是,开始rabbitmq事务机制,基本上吞吐量会下来,因为太耗性能。
事务只能保证生产者发出的消息成功被MQ服务器收到(不保证进入queue)
2、发送回执确认(推荐)
可以开启confirm模式,在生产者那里设置开启confirm模式之后,你每次写的消息都会分配一个唯一的id,然后如果写入了rabbitmq中,rabbitmq会给你回传一个ack消息,告诉你说这个消息ok了。如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息接收失败,你可以重试。而且你可以结合这个机制自己在内存里维护每个消息id的状态,如果超过一定时间还没接收到这个消息的回调,那么你可以重发。
  事务机制和cnofirm机制最大的不同在于,事务机制是同步的,你提交一个事务之后会阻塞在那儿,但是confirm机制是异步的,你发送个消息之后就可以发送下一个消息,然后那个消息rabbitmq接收了之后会异步回调你一个接口通知你这个消息接收到了。
所以一般在生产者这块避免数据丢失,都是用confirm机制的。

rabbitmq如何避免消息重复投递或重复消费?
消息进入MQ,MQ内部会生成inner-msg-id,作为去重和唯一的根据,避免消息重复入队
消息消费时,如果是分布式系统,需要在上游生成bizId(同一业务全局唯一,如订单ID)作为去重的根据,避免重复消费

rabbitmq如何确保消息不丢失?
1.消息持久化
2.ACK确认机制
3.设置集群镜像模式
4.消息补偿机制(消费者生产者各生成一个表,定时扫描差异)

rabbitmq如果发消息没有找到queue会怎么样?
生产者发送消息到exchange后,发送的路由和queue没有绑定,消息会存在丢失情况

rabbitmq如何优化以及避免性能恶化?
1、要避免流控机制触发,服务端默认配置是当内存使用达到40%,磁盘空闲空间小于50M,即启动内存报警,磁盘报警;报警后服务端触发流控(flowcontrol)机制,RabbitMQ服务端接收发布来的消息会变慢,使得进入队列的消息减少
2、消息大小不要超过4MB,当包大小达到4.5MB时,服务器的性能出现明显的异常,传输率尤其是每秒订阅消息的数量,出现波动,不稳定;同时有一部分订阅者的TCP连接出现断开的现象。可能是客户端底层或者RabbitMQ服务端在进行拆包,组包的时候,出现了明显的压力,而导致异常的发生,超过4MB的消息,最好先进行分包
3、RabbitMQ的内存占的很大,一般在产生的原因是长期的生产者发送速率大于消费者消费速率导致. 触发了RabbitMQ 的流控;
4、在direct模式下明显消息发布的性能比其他模式强很多,并且消息发送到相同队列比发送到不同队列性能稍好
5、磁盘也可能形成瓶颈
磁盘也可能形成瓶颈,如果单台机器队列很多,确认只在必要时才使用duration(持久化),避免把磁盘跑满;
6、队列的消息大量累积后,发送和消费速度都会受到影响,导致服务进一步恶化,采用的方法是,额外的脚本监控每个队列的消息数,超过限额会执行purge操作,简单粗暴但是有效的保证了服务稳定;


Kafka

kafka由scale实现,可运行在JVM中,并且和其他MQ不一样的是kafka只有topic方式的,topic有分区(partition),并且分区是冗余存储的,kafka是为分布式存在的,而rabbitmq和activemq的场景更多的是用于企业级的消息系统,kafka如果一个分区挂了,通过选主可以马上切换到另外一台服务器使用,相比rabbitmq,若想实现这一功能就需要配置一些镜像队列,操作上可能比较麻烦一点。kafka只支持拉模式(Pull)。


有几个概念👇
Broker↓
Kafka集群包含一个或多个服务器,这种服务器被称为broker [5]
Topic↓
每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)
Partition↓
Partition是物理上的概念,每个Topic包含一个或多个Partition.
Producer↓
负责发布消息到Kafka broker
Consumer↓
消息消费者,向Kafka broker读取消息的客户端。
Consumer Group↓
每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。
kafka中的消息在


分区中的存储,是采用偏移量的机制,所以在同一个分区中,消息消费的顺序是可以得到保证的


rabbitmq和activemq 和kafka 不一样的地方 消息删除时间不太一样,
kafka中消息的删除策略有两种↓
第一种是时间策略,比如我放在kafka的消息存放了多长时间,相当于过期时间,过了这个时间,自动删除
第二种是容量,超过了一定的量,会把最早的消息进行删除


对于rabbitmq和activemq 的消息只要消费之后,就立即会删除,没有重复消费的功能,所以kafka是支持重复消费的,这是kafka的优点,有的业务场景是需要重复消费的,比如 可以支持多个应用程序消费同一个topic中的消息


kafka是支持多个应用程序(consumerGroup )消费同一个主题中的消息,Kafka 只是说消息在消费的时候Kafka不知道你来自于哪个应用程序他只关心你订阅哪个主题,怎么做消费者区分,消费者需要指定自己属于哪个consumerGroup ,每个消费者都可以读取多个分区,但是一个分区在同一个consumerGroup 中指挥被同一个消费者消费。
在consumerGroup 中想消费哪个消费哪个分区,在不同的consumerGroup中两个消费者是可以消费同一个消息的,在consumerGroup消费分区的时候互相是互斥的

kafka支持多个应用程序消费同一个分区中的topic消息,多个应用程序他们的topic他们的consumergroup要指明清楚不能冲突

在这里插入图片描述

kafka支持MQTT(物联网场景的消息协议)

kafka创建一个topic是个很重的操作,他是分布式的,中间还要经过ZK
kafka仅仅可以作为MQTT的输入,如果让kafka去给硬件发消息,并不擅长

kafka提供了流式计算,可以做一些数据的初步清理, 大数据领域实时计算 ,日志采集,也是Kafka是业内标准的方案,这个Kafka社区活跃度也比较高

kafka安装和使用比较简单,如果有集群需要 首选Kafka ,海量数据,以及数据倾斜的场景里,什么是数据倾斜,比如某一个topic数据量特别大,在这种 对于Kafka有partition 数据倾斜会被自动解决。rabbitmq 不太好解决,虽然rabbitmq有集群复制但是需要指定为镜像队列,activemq适用于简单一些的,或者说他是个jar可以内嵌到项目里面可以用命令行启动,有这方面需求可以用activemq,大环境来说,分布式现在是主流


kafka的缺点?
1、由于是批量发送,数据并非真正的实时; 仅支持统一分区内消息有序,无法实现全局消息有序;
2、有小概率可能消息重复消费;
3、依赖zookeeper进行元数据管理,等等。

kafka的优点:
1、支持跨数据中心的消息复制;
2、单机吞吐量:十万级,最大的优点,就是吞吐量高;
3、topic数量都吞吐量的影响:topic从几十个到几百个的时候,吞吐量会大幅度下降。所以在同等机器下,kafka尽量保证topic数量不要过多。如果要支撑大规模topic,需要增加更多的机器资源;
4、时效性:ms级;
5、可用性:非常高,kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用;
6、消息可靠性:经过参数优化配置,消息可以做到0丢失;
7、功能支持:功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用。

为什么Kafka性能很好,体现在哪里?
1、磁盘顺序读写
2、零拷贝
3、分区
4、批量发送
5、数据压缩

请说明Kafka相对传统技术有什么优势?
1、快速:单一的Kafka代理可以处理成千上万的客户端,每秒处理数兆字节的读写操作。
2、可伸缩:在一组机器上对数据进行分区
3、和简化,以支持更大的数据
4、持久:消息是持久性的,并在集群中进
5、行复制,以防止数据丢失。
6、设计:它提供了容错保证和持久性

Kafka 与传统消息系统之间有三个关键区别?
1、Kafka 持久化日志,这些日志可以被重复读取和无限期保留
2、Kafka 是一个分布式系统:它以集群的方式运行,可以灵活伸缩,在内部通过复制数据提升容错能力和高可用性
3、Kafka 支持实时的流式处理

partition的数据如何保存到硬盘?
topic中的多个partition以文件夹的形式保存到broker,每个分区序号从0递增, 且消息有序 Partition文件下有多个segment(xxx.index,xxx.log) segment 文件里的 大小和配置文件大小一致可以根据要求修改 默认为1g 如果大小大于1g时,会滚动一个新的segment并且以上一个segment最后一条消息的偏移量命名

kafka的ack机制有几种?
request.required.acks有三个值 0 1 -1
0:生产者不会等待broker的ack,这个延迟最低但是存储的保证最弱当server挂掉的时候就会丢数据
1:服务端会等待ack值 leader副本确认接收到消息后发送ack但是如果leader挂掉后他不确保是否复制完成新leader也会导致数据丢失
-1:同样在1的基础上 服务端会等所有的follower的副本受到数据后才会受到leader发出的ack,这样数据不会丢失

kafka的写入是leader还是follower?
写入只能从leader写入,可以通过follower读取

Kafka的高可靠性的保障来源于其健壮的副本(replication)策略。
可以设置replicas的个数

kafka支持3种消息投递语义
At most once:最多一次,消息可能会丢失,但不会重复
At least once:最少一次,消息不会丢失,可能会重复
Exactly once:只且一次,消息不丢失不重复,只且消费一次(0.11中实现,仅限于下游也是kafka)

在业务中,常常都是使用At least once的模型,如果需要可重入的话,往往是业务自己实现。

At least once
先获取数据,再进行业务处理,业务处理成功后commit offset。
1、生产者生产消息异常,消息是否成功写入不确定,重做,可能写入重复的消息
2、消费者处理消息,业务处理成功后,更新offset失败,消费者重启的话,会重复消费

At most once
先获取数据,再commit offset,最后进行业务处理。
1、生产者生产消息异常,不管,生产下一个消息,消息就丢了
2、消费者处理消息,先更新offset,再做业务处理,做业务处理失败,消费者重启,消息就丢了

Exactly once
思路是这样的,首先要保证消息不丢,再去保证不重复。所以盯着At least once的原因来搞。 首先想出来的:

生产者重做导致重复写入消息----生产保证幂等性
消费者重复消费—消灭重复消费,或者业务接口保证幂等性重复消费也没问题

Zookeeper 在 Kafka 中的作用?
1、Broker注册
每个Broker就会将自己的IP地址和端口信息记录到该节点中去。其中,Broker创建的节点类型是临时节点,一旦Broker宕机,则对应的临时节点也会被自动删除。
2、Topic注册
在Kafka中,同一个Topic的消息会被分成多个分区并将其分布在多个Broker上,这些分区信息及与Broker的对应关系也都是由Zookeeper在维护
3、生产者负载均衡
由于同一个Topic消息会被分区并将其分布在多个Broker上,因此,生产者需要将消息合理地发送到这些分布式的Broker上,那么如何实现生产者的负载均衡,Kafka支持传统的四层负载均衡,也支持Zookeeper方式实现负载均衡
4、消费者负载均衡
与生产者类似,Kafka中的消费者同样需要进行负载均衡来实现多个消费者合理地从对应的Broker服务器上接收消息,每个消费者分组包含若干消费者,每条消息都只会发送给分组中的一个消费者,不同的消费者分组消费自己特定的Topic下面的消息,互不干扰。
5、分区 与 消费者 的关系
消费组 (Consumer Group):
consumer group 下有多个 Consumer(消费者)。
在Kafka中,规定了每个消息分区 只能被同组的一个消费者进行消费,因此,需要在 Zookeeper 上记录 消息分区 与 Consumer 之间的关系
6、消息 消费进度Offset 记录
7、消费者注册
对 消费者分组 中的 消费者 的变化注册监听。
对Broker服务器变化注册监听。
进行消费者负载均衡。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
高并发消息队列中间件是一种用于处理大量并发消息传递的软件系统。它提供了可靠的消息传递机制,以确保消息的可靠性和一致性。以下是两个常见的高并发消息队列中间件的介绍: 1. Kafka: Kafka是一个分布式流处理平台,也是一个高吞吐量的分布式发布订阅消息系统。它具有以下特点: - 支持高并发:Kafka能够处理大量的并发消息传递,可以同时处理大量的生产者和消费者。 - 高可靠性:Kafka使用分布式存储和复制机制,确保消息的可靠性和持久性。 - 高扩展性:Kafka可以通过添加更多的代理节点来扩展处理能力,以适应不断增长的消息负载。 - 高性能:Kafka使用磁盘存储消息,可以提供非常高的吞吐量和低延迟。 2. DDMQ(滴滴消息队列): DDMQ是滴滴出行开源的高并发消息队列中间件,它提供了低延迟、高并发、高可用、高可靠的消息服务。DDMQ具有以下特点: - 多种消息类型:DDMQ支持实时消息、延迟消息和事务消息等多种消息类型,以满足不同业务需求。 - 高可靠性:DDMQ使用分布式存储和复制机制,确保消息的可靠性和持久性。 - 高扩展性:DDMQ可以通过添加更多的代理节点来扩展处理能力,以适应不断增长的消息负载。 - 高性能:DDMQ使用高效的消息传递协议和优化的存储引擎,提供了低延迟和高吞吐量的消息传递能力。 这些高并发消息队列中间件可以帮助企业构建可靠、高效的消息传递系统,适用于各种高并发场景,如实时数据处理、日志收集、分布式事务等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值