消息隊列面試題


1、什么是消息隊列?
消息隊列,是分布式系統中重要的組件。

  • 主要解決應用耦合,異步消息,流量削鋒等問題。
  • 可實現高性能,高可用,可伸縮和最終一致性架構,是大型分布式系統不可缺少的中間件。

目前主流的消息隊列有:

  • Kafka
  • RabbitMQ
  • RocketMQ ,老版本是 MetaQ 。
  • ActiveMQ ,目前用的人越來越少了。

另外,消息隊列容易和 Java 中的本地 MessageQueue 搞混,所以消息隊列更多被稱為消息中間件、分布式消息隊列等等。

 

二、消息隊列由哪些角色組成?
如下圖所示:

 

 

 

  •  生產者(Producer):負責產生消息。
  •  消費者(Consumer):負責消費消息
  •  消息代理(Message Broker):負責存儲消息和轉發消息兩件事情。其中,轉發消息分為推送和拉取兩種方式。

           1. 拉取(Pull),是指 Consumer 主動從 Message Broker 獲取消息
   2. 推送(Push),是指 Message Broker 主動將 Consumer 感興趣的消息推送給 Consumer 。

 

三、消息隊列有哪些使用場景?

一般來說,有下面使用場景:

  • 應用解耦
  • 異步處理
  • 流量削峰
  • 消息通訊
  • 日志處理

其中,應用解耦、異步處理是比較核心的

 

四、Kafka的面試題

1.Apache Kafka 是什么?

Kafka 是基於發布與訂閱消息系統。它最初由 LinkedIn 公司開發,之后成為 Apache 項目的一部分。Kafka 是一個分布式的,可分區的,冗余備份的持久性的日志服務。它主要用於處理活躍的流式數據。

在大數據系統中,常常會碰到一個問題,整個大數據是由各個子系統組成,數據需要在各個子系統中高性能、低延遲的不停流轉。傳統的企業消息系統並不是非常適合大規模的數據處理。為了同時搞定在線應用

(消息)和離線應用(數據文件、日志),Kafka 就出現了。Kafka 可以起到兩個作用:

  ①   降低系統組網復雜度。

  ②   降低編程復雜度,各個子系統不在是相互協商接口,各個子系統類似插口插在插座上,Kafka 承擔高速數據總線的作用。

 

2.Kafka中的ISR、AR又代表什么?ISR的伸縮又指什么?

ISR:In-Sync Replicas 副本同步隊列

AR:Assigned Replicas 所有副本

ISR是由leader維護,follower從leader同步數據有一些延遲(包括延遲時間replica.lag.time.max.ms和延遲條數replica.lag.max.messages兩個維度, 當前最新的版本0.10.x中只支持

replica.lag.time.max.ms這個維度),任意一個超過閾值都會把follower剔除出ISR, 存入OSR(Outof-Sync Replicas)列表,新加入的follower也會先存放在OSR中。AR=ISR+OSR。

 

3.kafka中的broker 是干什么的?

broker 是消息的代理,Producers往Brokers里面的指定Topic中寫消息,Consumers從Brokers里面拉取指定Topic的消息,然后進行業務處理,broker在中間起到一個代理保存消息的中轉站。

 

4.kafka中的 zookeeper 起到什么作用,可以不用zookeeper么?
它最初由 LinkedIn 公司開發,之后成為 Apache 項目的一部分。Kafka 是一個分布式的,可分區的,冗余備份的持久性的日志服務。它主要用於處理活躍的流式數據。

在大數據系統中,常常會碰到一個問題,整個大數據是由各個子系統組成,數據需要在各個子系統中高性能、低延遲的不停流轉。傳統的企業消息系統並不是非常適合大規模的數據處理。為了同時搞定在線應用

 (消息)和離線應用(數據文件、日志),Kafka 就出現了。Kafka 可以起到兩個作用:


5.kafka follower如何與leader同步數據?

Kafka的復制機制既不是完全的同步復制,也不是單純的異步復制。完全同步復制要求All Alive Follower都復制完,這條消息才會被認為commit,這種復制方式極大的影響了吞吐率。而異步復制方

式下,Follower異步的從Leader復制數據,數據只要被Leader寫入log就被認為已經commit,這種情況下,如果leader掛掉,會丟失數據,kafka使用ISR的方式很好的均衡了確保數據不丟失以及吞

吐率。Follower可以批量的從Leader復制數據,而且Leader充分利用磁盤順序讀以及send file(zero copy)機制,這樣極大的提高復制性能,內部批量寫磁盤,大幅減少了Follower與Leader的消息量差。

 

 

6.什么情況下一個 broker 會從 isr中踢出去?
leader會維護一個與其基本保持同步的Replica列表,該列表稱為ISR(in-sync Replica),每個Partition都會有一個ISR,而且是由leader動態維護 ,如果一個follower比一個leader落后太多,或者超過

一定時間未發起數據復制請求,則leader將其重ISR中移除 。


7.kafka 為什么那么快?

Cache Filesystem Cache PageCache緩存


順序寫 由於現代的操作系統提供了預讀和寫技術,磁盤的順序寫大多數情況下比隨機寫內存還要快。

Zero-copy 零拷技術減少拷貝次數

Batching of Messages 批量量處理。合並小的請求,然后以流的方式進行交互,直頂網絡上限。

Pull 拉模式 使用拉模式進行消息的獲取消費,與消費端處理能力相符。

8.kafka producer如何優化打入速度?
增加線程

提高 batch.size

增加更多 producer 實例

增加 partition 數

設置 acks=-1 時,如果延遲增大:可以增大 num.replica.fetchers(follower 同步數據的線程數)來調解;

跨數據中心的傳輸:增加 socket 緩沖區設置以及 OS tcp 緩沖區設置。

9.kafka producer 打數據,ack  為 0, 1, -1 的時候代表啥, 設置 -1 的時候,什么情況下,leader 會認為一條消息 commit了

1(默認)  數據發送到Kafka后,經過leader成功接收消息的的確認,就算是發送成功了。在這種情況下,如果leader宕機了,則會丟失數據。


0 生產者將數據發送出去就不管了,不去等待任何返回。這種情況下數據傳輸效率最高,但是數據可靠性確是最低的。


-1 producer需要等待ISR中的所有follower都確認接收到數據后才算一次發送完成,可靠性最高。當ISR中所有Replica都向Leader發送ACK時,leader才commit,這時候producer才能認為一個請求中的消息都commit了。

 

10.Kafka中是怎么體現消息順序性的?

kafka每個partition中的消息在寫入時都是有序的,消費時,每個partition只能被每一個group中的一個消費者消費,保證了消費時也是有序的。
整個topic不保證有序。如果為了保證topic整個有序,那么將partition調整為1.

 

五、RabbitMQ面試題

 

 

1、什么是RabbitMQ?為什么使用RabbitMQ?

 

RabbitMQ是一款開源的,Erlang編寫的,基於AMQP協議的,消息中間件;

 

可以用它來:解耦、異步、削峰。

 

 

 

2、RabbitMQ有什么優缺點?

 

優點:解耦、異步、削峰;

 

缺點:降低了系統的穩定性:本來系統運行好好的,現在你非要加入個消息隊列進去,那消息隊列掛了,你的系統不是呵呵了。因此,系統可用性會降低;

 

增加了系統的復雜性:加入了消息隊列,要多考慮很多方面的問題,比如:一致性問題、如何保證消息不被重復消費、如何保證消息可靠性傳輸等。因此,需要考慮的東西更多,復雜性增大。

 

 

 

3、如何保證RabbitMQ的高可用?

 

沒有哪個項目會只用一搭建一台RabbitMQ服務器提供服務,風險太大;

 

 

 

4、如何保證RabbitMQ不被重復消費?

 

先說為什么會重復消費:正常情況下,消費者在消費消息的時候,消費完畢后,會發送一個確認消息給消息隊列,消息隊列就知道該消息被消費了,就會將該消息從消息隊列中刪除;

 

但是因為網絡傳輸等等故障,確認信息沒有傳送到消息隊列,導致消息隊列不知道自己已經消費過該消息了,再次將消息分發給其他的消費者。

 

針對以上問題,一個解決思路是:保證消息的唯一性,就算是多次傳輸,不要讓消息的多次消費帶來影響;保證消息等冪性;

 

比如:在寫入消息隊列的數據做唯一標示,消費消息時,根據唯一標識判斷是否消費過;

 

 

 

5、如何保證RabbitMQ消息的可靠傳輸

 

消息不可靠的情況可能是消息丟失,劫持等原因;

 

丟失又分為:生產者丟失消息、消息列表丟失消息、消費者丟失消息;

 

 

生產者丟失消息:從生產者弄丟數據這個角度來看,RabbitMQ提供transaction和confirm模式來確保生產者不丟消息;

 

transaction機制就是說:發送消息前,開啟事務(channel.txSelect()),然后發送消息,如果發送過程中出現什么異常,事務就會回滾(channel.txRollback()),如果發送成功則提交事務(channel.txCommit())。然而,這種方式有個缺點:吞吐量下降;

 

confirm模式用的居多:一旦channel進入confirm模式,所有在該信道上發布的消息都將會被指派一個唯一的ID(從1開始),一旦消息被投遞到所有匹配的隊列之后;

 

rabbitMQ就會發送一個ACK給生產者(包含消息的唯一ID),這就使得生產者知道消息已經正確到達目的隊列了;

 

如果rabbitMQ沒能處理該消息,則會發送一個Nack消息給你,你可以進行重試操作。

 

 

 

消息隊列丟數據:消息持久化。

 

處理消息隊列丟數據的情況,一般是開啟持久化磁盤的配置。

 

這個持久化配置可以和confirm機制配合使用,你可以在消息持久化磁盤后,再給生產者發送一個Ack信號。

 

這樣,如果消息持久化磁盤之前,rabbitMQ陣亡了,那么生產者收不到Ack信號,生產者會自動重發。

 

那么如何持久化呢?

 

這里順便說一下吧,其實也很容易,就下面兩步

 

  1. 將queue的持久化標識durable設置為true,則代表是一個持久的隊列
  2. 發送消息的時候將deliveryMode=2

 

這樣設置以后,即使rabbitMQ掛了,重啟后也能恢復數據

 

 

 

消費者丟失消息:消費者丟數據一般是因為采用了自動確認消息模式,改為手動確認消息即可!

 

消費者在收到消息之后,處理消息之前,會自動回復RabbitMQ已收到消息;

 

如果這時處理消息失敗,就會丟失該消息;

 

解決方案:處理消息成功后,手動回復確認消息。

 

 

 

6、如何保證RabbitMQ消息的順序性?

 

單線程消費保證消息的順序性;對消息進行編號,消費者處理消息是根據編號處理消息;

六、ActiveMQ

1.什么是activemq?

activeMQ是一種開源的,實現了JMS1.1規范的,面向消息(MOM)的中間件,為應用程序提供高效的、可擴展的、穩定的和安全的企業級消息通信。
 
2.activemq的作用以及原理?
Activemq 的作用就是系統之間進行通信。 當然可以使用其他方式進行系統間通信, 如果使用 Activemq 的話可以對系統之間的調用進行解耦, 實現系統間的異步通信。 原理就是生產者生產消息, 把消息發送給activemq。 Activemq 接收到消息, 然后查看有多少個消費者, 然后把消息轉發給消費者, 此過程中生產者無需參與。 消費者接收到消息后做相應的處理和生產者沒有任何關系
 
3.activemq的幾種通信方式?
 
3.1publish(發布)-subscribe(訂閱)(發布-訂閱方式)
發布/訂閱方式用於多接收客戶端的方式.作為發布訂閱的方式,可能存在多個接收客戶端,並且接收端客戶端與發送客戶端存在時間上的依賴。一個接收端只能接收他創建以后發送客戶端發送的信息。作為subscriber ,在接收消息時有兩種方法,destination的receive方法,和實現message listener 接口的onMessage 方法

3.2 p2p(point-to-point)(點對點)

p2p的過程則理解起來比較簡單。它好比是兩個人打電話,這兩個人是獨享這一條通信鏈路的。一方發送消息,另外一方接收,就這么簡單。在實際應用中因為有多個用戶對使用p2p的鏈路。

相互通信的雙方是通過一個類似於隊列的方式來進行交流。和前面pub-sub的區別在於一個topic有一個發送者和多個接收者,而在p2p里一個queue只有一個發送者和一個接收者。
  1. publish(發布)-subscribe(訂閱)方式的處理
發布訂閱模式的通信方式, 默認情況下只通知一次, 如果接收不到此消息就沒有了。 這種場景只適用於對消息送達率要求不高的情況。 如果要求消息必須送達不可以丟失的話, 需要配置持久訂閱。 每個訂閱端定義一個 id,   < property name="clientId" 在訂閱是向  activemq 注冊。 發布消息 <property name="subscriptionDurable" value="true"/>和接收消息時需要配置發送模式為持久化template.setDeliveryMode(DeliveryMode.PERSISTENT);。 此時如果客戶端接收不到消息, 消息會持久化到服務端(就是硬盤上), 直到客戶端正常接收后為止。
  1. 4.2p - p(點對點)方式的處理
點對點模式的話, 如果消息發送不成功此消息默認會保存到  activemq 服務端直到有消費者將其消費, 所以此時消息是不會丟失的。
 
 4. 如何解決消息重復問題
 
所謂消息重復,就是消費者接收到了重復的消息,一般來說我們對於這個問題的處理要把握下面幾點,
①.消息不丟失(上面已經處理了)
②.消息不重復執行
一般來說我們可以在業務段加一張表,用來存放消息是否執行成功,每次業務事物commit之后,告知服務端,已經處理過該消息,
這樣即使你消息重發了,也不會導致重復處理
大致流程如下:
        業務端的表記錄已經處理消息的id,每次一個消息進來之前先判斷該消息是否執行過,如果執行過就放棄,如果沒有執行就開始執行消息,消息執行完成之后存入這個消息的id

 



 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM