Apache Tribes - 簡介

目錄

快速入門

Apache Tribes 是群組或點對點通訊架構,讓您可以輕鬆地將您的遠端物件連接起來,以便彼此通訊。

  • 匯入:org.apache.catalina.tribes.Channel
  • 匯入:org.apache.catalina.tribes.Member
  • 匯入:org.apache.catalina.tribes.MembershipListener
  • 匯入:org.apache.catalina.tribes.ChannelListener
  • 匯入:org.apache.catalina.tribes.group.GroupChannel
  • 建立一個實作:org.apache.catalina.tribes.ChannelListener 的類別
  • 建立一個實作:org.apache.catalina.tribes.MembershipListener 的類別
  • 簡單的類別,用來示範如何傳送訊息
    //create a channel
    Channel myChannel = new GroupChannel();
    
    //create my listeners
    ChannelListener msgListener = new MyMessageListener();
    MembershipListener mbrListener = new MyMemberListener();
    
    //attach the listeners to the channel
    myChannel.addMembershipListener(mbrListener);
    myChannel.addChannelListener(msgListener);
    
    //start the channel
    myChannel.start(Channel.DEFAULT);
    
    //create a message to be sent, message must implement java.io.Serializable
    //for performance reasons you probably want them to implement java.io.Externalizable
    Serializable myMsg = new MyMessage();
    
    //retrieve my current members
    Member[] group = myChannel.getMembers();
    
    //send the message
    myChannel.send(group,myMsg,Channel.SEND_OPTIONS_DEFAULT);

簡單吧?Tribes 的功能遠比我們展示的還要多,希望文件能為您提供更多說明。請記住,我們一直很歡迎建議、改進、錯誤修正,以及您認為有助於此專案的任何事項。

什麼是 Tribes

Tribes 是具備群組通訊能力的訊息傳遞架構。Tribes 讓您可以透過網路傳送和接收訊息,也可以動態發現網路中的其他節點。
這就是簡短的故事,真的就這麼簡單。Tribes 的實用性和獨特性將在以下章節中說明。

Tribes 模組於 2006 年初開始,而一小部分的程式碼基礎來自於群集模組,該模組自 2003 年或 2004 年以來一直存在。目前的群集實作有幾個小缺點,而且由於群組通訊的複雜性,因此產生許多解決方法。長話短說,兩個模組應該在很久以前就分開,現在是時候了。Tribes 從複製模組中消除了訊息傳遞的複雜性,並成為一個完全獨立且高度靈活的群組通訊模組。

在 Tomcat 中,舊的 modules/cluster 現已變成 modules/groupcom(Tribes) 和 modules/ha (複製)。這將允許開發繼續進行,並讓開發人員專注於他們實際正在處理的問題,而不是陷入他們不感興趣的模組細節中。了解通訊和複製都夠複雜,而當嘗試在同一個模組中開發它們時,嗯,你知道的,它會變成一個群集 :)

Tribes 允許保證訊息傳遞,並且可以透過許多方式自訂。為什麼這很重要?
嗯,身為開發人員,您想知道您所傳送的訊息是否已到達目的地。更重要的是,如果訊息未到達目的地,則 Tribes 上方的應用程式將會收到通知,告知訊息從未傳送,以及在那個節點上失敗。

為何需要另一個訊息傳遞架構

我是重複使用程式碼的忠實擁護者,如果其他人已經開發出某個東西,而且它對我和我試圖服務的社群可用,我絕不會想開發它。
當我進行研究以改善群集模組時,我經常遇到一些障礙
1. 框架不夠靈活
2. 框架的授權方式使得我和社群都無法使用它
3. 缺少我需要的幾個功能
4. 訊息傳遞有保證,但沒有回饋報告給我
5. 我的訊息傳遞語意必須在執行階段之前進行設定
清單持續增加...

因此,我提出了 Tribes,以解決這些問題和其他出現的問題。在設計 Tribes 時,我想要確保我不會失去現有架構已提供的任何彈性和傳遞語義。目標是建立一個架構,可以執行其他架構已執行的所有功能,但為應用程式開發人員提供更大的彈性。在下一節中,將為您提供 Tribes 提供或將提供的功能的高階概觀。

功能概觀

為了讓您了解功能設定,我將在此列出。某些功能尚未完成,如果是這樣,則會做相應標記。

可插入模組
Tribes 是使用介面建立的。任何屬於 Tribes 的模組或元件都可以交換,以自訂您自己的 Tribes 實作。

保證訊息傳遞
在 Tribes 的預設實作中,使用 TCP 或 UDP 進行訊息傳遞。TCP 已內建保證訊息傳遞和流量控制。我相信 Java TCP 的效能將優於 Java/UDP/流量控制/訊息保證的實作,因為邏輯發生在堆疊的更低層。已新增 UDP 訊息傳遞,以便在需要時透過 UDP 而非 TCP 傳送訊息。以下所述的相同保證情境仍然可以在 UDP 上使用,但是當 UDP 訊息遺失時,會視為失敗。
Tribes 支援非封鎖和封鎖 IO 作業。建議的設定是使用非封鎖,因為它在傳送和接收訊息時能促進更好的平行性。封鎖實作可供 NIO 仍有問題的平台使用。

不同的保證等級
傳送訊息時有三個不同的傳遞保證等級。

  1. 基於 IO 的傳送保證 - 最快,最不可靠
    這表示如果訊息已傳送到 socket 傳送緩衝區並已接受,Tribes 會將訊息傳輸視為成功。
    在封鎖 IO 上,這將是 socket.getOutputStream().write(msg)
    在非封鎖 IO 上,這將是 socketChannel.write(),然後緩衝區位元組緩衝區會清空,接著是 socketChannel.read() 以確保通道仍然開啟。已新增 read(),因為如果使用 NIO 時連線已「關閉」,write() 會成功。
  2. 基於 ACK - 建議使用,保證傳遞
    當訊息已在遠端節點收到時,會傳送 ACK 回傳給寄件者,表示訊息已成功收到。
  3. 基於 SYNC_ACK。- 保證傳遞,保證處理,最慢
    當訊息已在遠端節點收到時,節點將處理訊息,如果訊息已成功處理,會傳送 ACK 回傳給寄件者,表示訊息已成功收到並處理。如果訊息已收到,但處理失敗,會傳送 ACK_FAIL 回傳給寄件者。這是獨特的功能,為應用程式開發人員增加了驚人的價值。這裡的大部分架構會告訴您訊息已傳遞,而應用程式開發人員必須建立邏輯,判斷訊息是否實際上已由遠端節點上的應用程式正確處理。如果已設定,Tribes 會在收到 ACK_FAIL 時擲回例外狀況,並將該例外狀況與未處理訊息的成員關聯。

您當然可以撰寫更精密的保證層級,其中一些會在稍後的文件中提到。一個值得一提的層級是兩階段提交,其中遠端應用程式在所有節點收到訊息之前不會收到訊息。有點像全有或全無協定。

每個訊息傳遞屬性
或許是讓 Tribes 從眾多群組通訊架構中脫穎而出的功能。Tribes 讓您能夠傳送,以決定訊息傳輸在每個訊息基礎上應具備什麼傳遞語意。這表示您的訊息並非根據訊息架構啟動後保持固定的某些靜態設定傳遞。
為了讓您了解這個功能有多強大,我會試著用一個簡單的範例來說明。想像一下您需要傳送 10 則不同的訊息,您可以用以下方式傳送

Message_1 - asynchronous and fast, no guarantee required, fire and forget
Message_2 - all-or-nothing, either all receivers get it, or none.
Message_3 - encrypted and SYNC_ACK based
Message_4 - asynchronous, SYNC_ACK and call back when the message is processed on the remote nodes
Message_5 - totally ordered, this message should be received in the same order on all nodes that have been
            send totally ordered
Message_6 - asynchronous and totally ordered
Message_7 - RPC message, send a message, wait for all remote nodes to reply before returning
Message_8 - RPC message, wait for the first reply
Message_9 - RPC message, asynchronous, don't wait for a reply, collect them via a callback
Message_10- sent to a member that is not part of this group

如您現在所想像的,這些只是範例。您可以在每個訊息基礎上套用的不同語意數量幾乎是無限的。Tribes 讓您可以在訊息上設定多達 28 個不同的訊息,然後設定 Tribes,讓旗標在訊息上產生什麼動作。
想像一個共用交易快取,可能 >90% 是讀取,而髒讀取應完全無序,並盡可能快地傳遞。但另一方面,交易寫入必須是有序的,以免快取損毀。使用 Tribes 時,您可以傳送完全有序的寫入訊息,而讀取訊息您只需發射,即可達成最高吞吐量。
關於如何使用這個強大功能,可能還有更好的範例,因此請發揮您的想像力和經驗,想想這如何在您的應用程式中對您有幫助。

基於攔截器的訊息處理
Tribes 使用可自訂的攔截器堆疊來處理傳送和接收的訊息。
所以呢,所有架構都有這個功能!
是的,但在 Tribes 中,攔截器可以根據在執行階段傳送的每個訊息屬性對訊息做出反應。這表示,如果您新增一個加密訊息的加密攔截器,您可以決定這個攔截器是否會加密所有訊息,或僅加密由執行於 Tribes 上方的應用程式決定的特定訊息。
這就是 Tribes 能夠傳送一些完全順序的訊息,而其他訊息則像上述範例一樣採用發射後不管的方式。
可用的攔截器數量會持續增加,我們歡迎您提供任何貢獻。

無執行緒攔截器堆疊攔截器不需要任何獨立執行緒來執行其訊息處理。
傳送的訊息會暫時使用傳送它們的執行緒,直到傳輸完成。例外情況是 MessageDispatchInterceptor,它會將訊息排隊,並在獨立執行緒上傳送,以進行非同步訊息傳遞。接收的訊息由 receiver 組件中的執行緒池控制。
頻道物件可以透過攔截器堆疊傳送 heartbeat(),以允許逾時、清理和其他事件。
MessageDispatchInterceptor 是唯一預設設定的攔截器。

平行傳遞
Tribes 支援平行傳遞訊息。這表示 node_A 可以平行傳送三則訊息給 node_B。當傳送具有不同傳遞語意的訊息時,這個功能會很有用。否則,如果 Message_1 以完全順序傳送,Message_2 就必須等到該訊息完成。
透過 NIO,Tribes 也能在同一個執行緒上同時傳送訊息給多個接收者。

靜默成員傳訊
使用 Tribes,您可以傳送訊息給不在您群組中的成員。因此,預設情況下,您已經可以在廣域網路上傳送訊息,即使動態發現模組目前使用多播進行動態節點發現,而僅限於區域網路。當然,成員資格組件將在未來擴充,以支援廣域網路成員資格。但是,當您想要將成員隱藏在群組的其他成員面前,並僅與他們通訊時,這會非常有用

在哪裡可以取得 Tribes

Tribes 作為模組隨附在 Tomcat 中,並作為 Apache Tomcat 發行版的一部分發布。