面试题答案
一键面试RabbitMQ
- 实现方式:
- 队列持久化:声明队列时将
durable
属性设为true
,这样即使RabbitMQ服务器重启,队列依然存在。例如在Java中使用Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
方法,将durable
设为true
。 - 消息持久化:发送消息时将
deliveryMode
属性设为2,代表持久化消息。例如在Java中使用AMQP.BasicProperties.Builder deliveryMode(int deliveryMode)
方法,将deliveryMode
设为2。持久化消息会被写入磁盘,当服务器重启时不会丢失。
- 队列持久化:声明队列时将
- 优点:
- 实现相对简单,通过设置队列和消息的持久化属性即可。
- 对于可靠性要求较高的支付场景,能较好地保证消息不丢失。
- 缺点:
- 性能会有所下降,因为涉及磁盘I/O操作。持久化消息写入磁盘比非持久化消息在内存中处理要慢。
- 若持久化配置不当,比如只持久化消息而队列未持久化,依然可能丢失消息。
Kafka
- 实现方式:
- 副本机制:Kafka通过副本机制来实现消息持久化。每个分区可以有多个副本,其中一个为领导者副本,其他为追随者副本。生产者发送的消息首先写入领导者副本,追随者副本会从领导者副本同步数据。当领导者副本所在的节点发生故障时,会从追随者副本中选举出新的领导者副本,保证数据不丢失。例如,创建主题时可以指定副本因子
replication.factor
,如kafka-topics.sh --create --bootstrap -servers localhost:9092 --replication -factor 3 --partitions 1 --topic test_topic
,这里replication.factor
设为3,即有3个副本。 - 日志分段和刷盘策略:Kafka的日志以段(Segment)为单位进行管理,每个段由日志文件和索引文件组成。Kafka有不同的刷盘策略,如
fsync
的频率配置,通过log.flush.interval.messages
(指定消息数触发刷盘)和log.flush.interval.ms
(指定时间间隔触发刷盘)等参数控制。
- 副本机制:Kafka通过副本机制来实现消息持久化。每个分区可以有多个副本,其中一个为领导者副本,其他为追随者副本。生产者发送的消息首先写入领导者副本,追随者副本会从领导者副本同步数据。当领导者副本所在的节点发生故障时,会从追随者副本中选举出新的领导者副本,保证数据不丢失。例如,创建主题时可以指定副本因子
- 优点:
- 高吞吐量,在保证消息持久化的同时,能处理大量的消息,适合支付系统高并发的场景。
- 基于副本的容错机制,能在节点故障的情况下保证数据不丢失,可靠性较高。
- 缺点:
- 配置相对复杂,需要合理设置副本因子、刷盘策略等参数,否则可能影响性能和可靠性。
- 由于副本同步等机制,可能存在消息的短暂不一致性,不过一般能在短时间内达到最终一致性,这对于支付系统可能需要额外处理以保证强一致性。