0

1

2

3

4

5

6

7

8

9

0

1

{{ noReadMessageTotal }}

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

尚硅谷Java技术之深圳高频面试题:第六章 消息队列相关

晴天 晴天 | 361 | 558天前

尚硅谷Java技术之深圳高频面试题

版本:V1.0

尚硅谷Java技术中心

第六章 消息队列相关

1. RabbitMQ在项目中的应用

这个根据项目具体情况进行阐述即可

2. 如何保证RabbitMQ消息的可靠性传输

消息可靠性一般来说由3方面来保证:

1) 生产者

RabbitMQ提供transaction事务和confirm模式来确保生产者不丢消息;

Transaction事务机制就是说:发送消息前,开启事务(channel.txSelect()),然后发送消息,如果发送过程中出现什么异常,事务就会回滚
(channel.txRollback()),如果发送成功则提交事务(channel.txCommit()),然而,这种方式有个缺点:吞吐量下降。

confirm模式用的居多:一旦channel进入confirm模式,所有在该信道上发布的消息都将会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列之后;

rabbitMQ就会发送一个ACK给生产者(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了;

如果rabbitMQ没能处理该消息,则会发送一个Nack消息给你,可以进行重试操作。

2) 消息队列本身

可以进行消息持久化, 即使rabbitMQ挂了,重启后也能恢复数据

如果要进行消息持久化,那么需要对以下3种实体均配置持久化

a) Exchange

声明exchange时设置持久化(durable = true)并且不自动删除(autoDelete =
false)

b) Queue

声明queue时设置持久化(durable = true)并且不自动删除(autoDelete =
false)

c) message

发送消息时通过设置deliveryMode=2持久化消息

3) 消费者

消费者丢数据一般是因为采用了自动确认消息模式,消费者在收到消息之后,处理消息之前,会自动回复RabbitMQ已收到消息;如果这时处理消息失败,就会丢失该消息;改为手动确认消息即可!手动确认模式下消费失败时,不将其重新放入队列(确认重试也不会成功的情形),打印错误信息后,通知相关人员,人工介入处理。

3. 如何保证消息队列里消息的生成和消费的顺序性

场景:比如支付操作,支付成功之后,会发送修改订单状态和扣减库存的消息,如果这两个消息同时发送,就不能保证完全按照顺序消费,有可能是先减库存了,后更改订单状态。

解决方案:同步执行,当一个消息执行完之后,再发布下一个消息。

4. 如何避免消息队列消息重复消费(如何保证消息的幂等性)

- 幂等性:一个请求,不管重复来多少次,结果是不会改变的。

-
RabbitMQ、RocketMQ、Kafka等任何队列不保证消息不重复,如果业务需要消息不重复消费,则需要消费端处理业务消息要保持幂等性

- 方式一:Redis的setNX() , 做消息id去重 java版本目前不支持设置过期时间

//Redis中操作,判断是否已经操作过 TODO

boolean flag = jedis.setNX(key);

if(flag){

//消费

}else{

//忽略,重复消费

}

- 方式二:redis的 Incr 原子操作:key自增,大于0
返回值大于0则说明消费过,(key可以是消息的md5取值,
或者如果消息id设计合理直接用id做key)

int num = jedis.incr(key);

if(num == 1){

//消费

}else{

//忽略,重复消费

}

- 方式三:数据库去重表

设计一个去重表,某个字段使用Message的key做唯一索引,因为存在唯一索引,所以重复消费会失败

CREATE TABLE `message_record` ( `id` int(11) unsigned NOT NULL
AUTO_INCREMENT, `key` varchar(128) DEFAULT NULL, `create_time`
datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `key`
(`key`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

5. 分布式事务在项目中的应用

对于C端的应用,一般来说比较追求效率,如果在不需要强一致性的场景下可以用MQ来实现分布式事务,保证数据的最终一致性。说白了就是怎么保证消息的可靠性传输,保证消息最终能被成功消费,进行数据状态的改变,最终达到数据一致性的目的。

相关文章:
第一章 Java基础
第二章 MySQL相关
第三章 框架相关
第四章 Redis相关
第五章 JVM相关
第六章 消息队列相关
第七章 项目相关

文章标签: MQ

真诚点赞 诚不我欺~

{{ praiseUserVoList.length }}人点赞

item.nickname

尚硅谷Java技术之深圳高频面试题:第六章 消息队列相关

{{ isPraise ? '已点赞' : '点赞'}}
{{ isCollect ? '已收藏' : '收藏'}}
评论
gOod mornIng
没有更多啦~ 加载中...

关于作者

晴天
晴天

人因梦想而伟大!