目录
RabbitMQ
1、你们项目中哪里用到了RabbitMQ
2、为什么会选择使用RabbitMQ
3、使用RabbitMQ如何保证消息不丢失
4、消息的重复消费问题如何解决的
5、如何解决消息堆积在MQ的问题
6、RabbitMQ如何保证消费的顺序性
7、RabbitMQ的延迟队列有了解过嘛
8、RabbitMQ如何设置消息过期
9、什么是死信交换机
10、RabbitMQ的集群有哪些
ElasticSearch
1、什么是倒排索引
2、ES中的查询关键字有哪些
3、ES中字符串类型有几个
4、ES中query和filter的区别
5、如何保证ES和MySQL的数据一致性
RabbitMQ
1、你们项目中哪里用到了RabbitMQ
RabbitMQ是我们项目中服务通信的主要方式之一 , 我们项目中服务通信主要有二种方式实现 :
通过Feign实现服务的同步调用
通过MQ实现服务的异步通信
下面要结合自己的项目中功能来说两个地方
xxx
xxx
2、为什么会选择使用RabbitMQ
我们项目中之所以选择使用RabbitMQ,是因为它的功能比较丰富 , 支持各种消息收发模式, 支持延迟队列 , 惰性队列
而且天然支持集群, 保证服务的高可用, 同时性能非常不错 , 社区也比较活跃, 文档资料非常丰富
使用MQ有很多好处,简单跟您说几个:
吞吐量提升:无需等待订阅者处理完成,响应更快速
故障隔离:服务没有直接调用,不存在级联失败问题
调用间没有阻塞,不会造成无效的资源占用
耦合度极低,每个服务都可以灵活插拔,可替换
流量削峰:不管发布事件的流量波动多大,都由Broker接收,订阅者可以按照自己的速度去处理事件
当然使用使用MQ也有一些缺点
架构复杂了,业务没有明显的流程线,不好管理
需要依赖于Broker的可靠、安全、性能
总之,瑕不掩瑜,使用了RabbitMQ之后可以大大提供程序的效率
3、使用RabbitMQ如何保证消息不丢失
消息从生产者发送到消费者接收,会经历多个过程 , 其中的每一步都可能导致消息丢失
大体可以分为这样几种情况:
消息发送到交换机丢失
消息从交换机路由到队列丢失
消息保存到队列中丢失
消费者消费消息丢失
针对每一步,RabbitMQ分别给出了解决方案:
消息发送到交换机丢失:发布者确认机制
消息发送到交换机失败会向生产者返回失败原因,生产者通过回调接收发送结果,如果发送失败,重新发送,或者记录日志人工介入
消息从交换机路由到队列丢失:发布者回执机制
消息从交换机路由到队列失败会向生产者返回失败原因 ,生产者通过回调接收回调结果,如果发送失败,重新发送,或者记录日志人工介入
消息保存到队列中丢失:MQ持久化
RabbitMQ运行开启交换机持久化、队列持久化、消息持久化,以保证消息在传输过程中不会丢失
消费者消费消息丢失:消费者确认机制
消费者确认机制指的是只有消费者一方确认消息消费成功了,mq才删除消息,否则就会重新发送消息给消费者
通过RabbitMQ本身所提供的机制基本上已经可以保证消息不丢失, 但是因为一些特殊的原因还是会发送消息丢失问题 ,
例如 : 回调丢失 , 系统宕机, 磁盘损坏等 , 这种概率很小 , 但是如果想规避这些问题 , 进一步提高消息发送的成功率, 也可以通过程序自己进行控制
设计一个消息状态表 , 主要包含 : 消息id , 消息内容 , 交换机 , 消息路由key , 发送时间, 签收状态等字段 , 发送方业务执行完毕之后 , 向消息状态表保存一条消息记录, 消息状态为未签收 , 之后再向MQ发送消息 , 消费方接收消息消费完毕之后 , 向发送方发送一条签收消息 , 发送方接收到签收消息之后 , 修改消息状态表中的消息状态为已签收 ! 之后通过定时任务扫描消息状态表中这些未签收的消息 , 重新发送消息, 直到成功为止 , 对于已经完成消费的消息定时清理即可 !
4、消息的重复消费问题如何解决的
在使用RabbitMQ进行消息收发的时候,如果发送失败或者消费失败会自动进行重试,那么就有可能会导致消息的重复消费
解决方案:
每条消息设置一个唯一的标识id
幂等方案
token+redis
分布式锁
数据库锁(悲观锁、乐观锁)
5、如何解决消息堆积在MQ的问题
解决消息堆积有几种种思路:
提高消费者的消费能力,例如使用多线程消费
增加消费者数量,提高消费速度,可以使用ork队列模式,设置多个消费者消费消费同一个队列中的消息
扩大队列容积,提高堆积上限
使用RabbitMQ惰性队列,接收到消息后直接存入磁盘而非内存,消费者要消费消息时才会从磁盘中读取并加载到内存
6、RabbitMQ如何保证消费的顺序性
一个队列只设置一个消费者消费即可 , 多个消费者之间是无法保证消息消费顺序性的
7、RabbitMQ的延迟队列有了解过嘛
RabbitMQ的延迟队列有两种实现方案 :
使用消息过期TTL + 死信交换机
使用延迟交换机插件
8、RabbitMQ如何设置消息过期
RabbitMQ设置消息过期的方式有两种 :
在队列上设置过期时间,所有进到这个队列的消息就会具有统一的过期时间
为消息单独设置过期时间
注意 :
队列过期和消息过期同时存在 , 会以时间短的时间为准
RabbitMQ队列消息过期的机制是判断队列头部元素是否过期 , 如果队里头部消息没有到过期时间 , 中间消息到了过期时间, 这个消息也不会被自动剔除
9、什么是死信交换机
死信交换机和正常的交换机没有什么不同,当一个包含
死信
的队列使用dead-letter-exchange
属性,指定了一个交换机,这个交换机称为死信交换机也就是说只有队列中的死信才会流转到死信交换机,而当一个队列中的消息满足下列情况之一时,就会成为死信:
消费者使用basic.reject或 basic.nack声明消费失败,并且消息的requeue参数设置为false
消息是一个过期消息,超时无人消费
要投递的队列消息满了,无法投递
一般的死信交换机还会再跟着一个专门的队列,用来专门存储所有的死信,以方便后期的人工干预
10、RabbitMQ的集群有哪些
RabbitMQ天然支持集群模式,它的集群有两种模式:
普通集群:是一种分布式集群,将队列分散到集群的各个节点,从而提高整个集群的并发能力
这种集群会在集群的各个节点间共享部分数据,包括:交换机、队列元信息。不包含队列中的消息。
当访问集群某节点时,如果队列不在该节点,会从数据所在节点传递到当前节点并返回
如果队列所在节点宕机,队列中的消息就会丢失
镜像集群:是一种主从集群,普通集群的基础上,添加了主从备份功能,提高集群的数据可用性。
这种集群模式下,交换机、队列、队列中的消息会在各个mq的镜像节点之间同步备份
创建队列的节点被称为该队列的主节点,备份到的其它节点叫做该队列的镜像节点。
一个队列的主节点可能是另一个队列的镜像节点
所有操作都是主节点完成,然后同步给镜像节点
主宕机后,镜像节点会替代成新的主
ElasticSearch
1、什么是倒排索引
倒排索引是搜索引擎的核心,它是一种像数据结构一样的散列图,可将用户从单词导向文档或网页。主要目标是快速从数百万文件中查找数据
倒排索引主要体现在文档的保存和查询流程中
保存文档时,会先根据文档进行分词,然后使用分好的词条作为key进行排序,然后将文档的标识作为value进行存储
查询文档时,也会先对查询关键字进行分词,然后根据分好的词条直接定位相关文档,再做结果的合并
2、ES中的查询关键字有哪些
在ES中用于声明查询条件的关键字主要有:
match_all:查询所有
match、multi_match:全文检索
term:精准词条查询
range:范围查询
bool、must、must_not、should、filter:复合查询
还有一些跟地理位置、相关性算分相关的
3、ES中字符串类型有几个
ES有两个字符串类型,分别是:keyword 和 Text,他们两个的区别主要是在分词方面
keyword类型的字符串是不会分词的,直接根据字符串内容建立倒排索引
Text类型的字符串在保存到ES时会先分词,然后根据分词后的内容建立倒排索引
4、ES中query和filter的区别
query和filter都可以实现ES中的查询,区别是
query查询操作不仅仅会进行查询,还会计算分值,用于确定相关度
filter查询操作仅判断是否满足查询条件,不会计算任何分值,也不会关心返回的排序问题,同时,filter查询的结果可以被缓存,提高性能。
5、如何保证ES和MySQL的数据一致性
保证MySQL和ES数据一致性的方式有很多,下面列举几个:
同步双写:程序在向MySQL写入数据之后,立即将数据写入ES中。这种方法可以确保数据的实时同步,但可能会增加系统的复杂性和延迟。
异步消息:程序在在向MySQL写入数据之后,向MQ中投递消息,ES相关程序监听MQ,获取数据,写入ES
canel监听:使用canel监听MySQL的binlog,当发现写入操作后,立即读取内容,写入ES
logstatsh:使用logstatsh将MySQL中的数据实时传输给ES