ActiveMQ傳輸檔案的幾種方式原理與優劣

來源:互聯網
上載者:User

本文討論ActiveMQ傳輸檔案的幾種方法的原理及其利弊,作為訊息發送、直接傳輸檔案、使用ftp或http中轉。最後介紹擴充ActiveMQ實現自訂檔案傳輸方式,討論如何?高效的檔案傳輸。by kimmking

作為訊息發送

按照JMS規範,為了保證可靠性,所有的訊息都應該是發送到broker,然後交由broker來投遞的。也即是說其實JMS是不建議或不支援傳輸檔案的。

對於比較小的檔案,簡單的處理方式是先讀取所有的檔案成byte[],然後使用ByteMessage,把檔案資料發送到broker,像正常的message一樣處理。對於大檔案,例如1GB以上的檔案,這麼搞直接把client或是broker給oom掉了。

這種方式僅僅適用於小檔案的傳輸。特別是如果broker端使用資料庫作為儲存,message序列化以後存放於blob欄位,檔案傳輸頻繁或是稍微有點大,寫入效率極低。

直接傳輸檔案

為瞭解決傳輸大檔案的問題,ActiveMQ在jms規範之外引入了jms streams的概念。PTP模式下,連到同一個destination的兩端,可以通過broker中轉來傳輸大檔案。

發送端使用connection.createOutputStream開啟一個輸出資料流,往流裡寫檔案。

OutputStream out =connection.createOutputStream(destination);

接收端則簡單的使用connection.createInputStream拿到一個輸入資料流,從中讀取檔案資料即可。

InputStream in = connection.createInputStream(destination)

詳見:http://activemq.apache.org/jms-streams.html

使用非常簡單。ActiveMQ在中間做了什麼事情呢?

其實過程蠻曲折的,發送端拿到檔案後,首先分區,預設64K檔案資料為一個byte message,然後依次把所有的message發送到broker,broker轉寄給接收端,最後發送一個空訊息作為結束符。

connection上提供了兩個建立OutputStream的方法,一個是createOutputStream建立的是持久化的訊息集合,這些資料會寫到磁碟或是資料庫(對大檔案來說慢消費也是一件可怕的事兒);一個是createNonPersistOutputStream建立的是非持久化訊息集合,不會寫到磁碟上,如果沒有及時消費掉就慘了。

檔案片段的byte message的TTL設定為0,就是不會逾時進入DLQ。

優勢:簡單直接,處理非常小(不大於64K)的檔案非常方便。

劣勢:對大檔案,簡直就是噩夢。

檔案中轉方式

使用訊息的方式來傳遞大檔案,明顯不是一個有效率的辦法。檔案應該就是按檔案的方式去處理。

自己處理中轉

如果自己處理檔案的話,一個簡單方式是使用共用或ftp、dfs等方式,先把檔案發送到一個大家都可以拿到的地方,然後發送message,payload或properties中包含檔案的路徑資訊。這樣,consumer拿到檔案路徑後去指定的地方,按照給定的方式去擷取檔案資料即可。

優勢:這種方式可以用來處理大資料,並且不需要client或broker在記憶體中持有檔案資料本身,非常的節省資源。而且檔案是通過額外的方式處理,跟ActiveMQ本身無關,所以符合jms協議、處理的效率也相對比較高。

劣勢:需要自己處理很多檔案相關的操作。

BlobMessage對檔案中轉的封裝

幸運的是,ActiveMQ把上面繁複的檔案處理工作進行了封裝,屏蔽掉檔案中轉的整個處理過程,使得我們可以使用類似jms規範的API來簡單操作檔案傳輸。

舉個例子來說,典型的使用步驟:

發送端:

1.        啟動ActiveMQ時,也啟動jetty(即activemq.xml中有import jetty.xml),此時jetty中運行了一個ActiveMQ內建的http檔案伺服器

2.        使用tcp://localhost:61616?jms.blobTransferPolicy.defaultUploadUrl=http://localhost:8161/fileserver/建立connection,然後建立session和producer

3.        使用如下代碼傳送檔案:

BlobMessageblobMessage = session.createBlobMessage(file); 

blobMessage.setStringProperty("FILE.NAME",file.getName()); 

blobMessage.setLongProperty("FILE.SIZE",file.length()); 

producer.send(blobMessage); 

接收端比較簡單,正常的使用jms接收到訊息:

InputStream inputStream = blobMessage.getInputStream();

然後直接讀取檔案資料即可。檔案名稱和檔案大小可以從message的屬性中拿到。

 

這個過程中ActiveMQ做了什麼呢?

發送端:producer.send的時候,把檔案通過http協議的PUT方法發到jetty中的fileserver(預設128K走http的chunk分區傳輸)。然後把http的url寫入訊息中。再把訊息發送到broker。

接收端:接收到訊息以後,發現是BlobMessage,拿到url,直接使用GET方法擷取檔案資料。處理完畢後,使用DELETE方法從fileserver刪除檔案。

BlobMessage支援3種檔案中轉方式:

FILE

         要求client和broker在同一個機器或者使用同一個共用儲存。傳送檔案的時候,把檔案從本地寫入到指定路徑。接收檔案的時候,把檔案從此路徑讀出來。

HTTP

         使用http的fileserver,PUT/GET/DELETE方法。ActiveMQ內建了簡單的實現。就是前面情境中使用的方式。

FTP

         使用一個獨立的ftpserver作為檔案中轉方式。傳送檔案的時候,把檔案發送到ftp伺服器。接收檔案的時候,從ftp把檔案讀取下來。

 

詳見:http://activemq.apache.org/blob-messages.html

 

優勢:訊息處理與檔案處理傳輸分開,極大的提高了檔案傳輸的效率。而且可以使用類似jms協議的方式來處理檔案發送。

劣勢:FILE方式不太實用。HTTP和FTP方式都需要額外的fileserver。

 

自訂檔案傳輸方式

ActiveMQ實現BlobMessage的三種檔案中轉方式時,使用了Façade和Strategy模式。ActiveMQBlobMessage需要在發送訊息時使用blobUploader上傳檔案、接收訊息時使用blobDownloader下載檔案。每種中轉方式的這兩個操作分別使用BlobUploadStrategy和BlobDownloadStrategy封裝。

所以,我們也可以根據ActiveMQBlobMessage檔案傳送的原理,實現自己的定製方式:

1、  給ActiveMQBlobMessage添加自己的blobDownloader和blobUploader來實現檔案的處理。

2、  擴充這個檔案中轉機制,實現BlobUploadStrategy和BlobDownloadStrategy。

 

一個更高效且不需要額外fileserver的實現思路是:broker上再開啟一個tcp的監聽連接埠,用來接收和轉寄檔案,當發送和接收端都在時,broker僅僅作為一個傳輸代理。接收端不在時,broker把資料存為本地臨時檔案,處理完畢後刪除掉。之所以使用一個新的連接埠來傳輸檔案資料而不是已有的transport,是為了避免jms streams這種命令和資料混合的模式。可以參考ftp協議,作為一種高效的檔案傳輸通訊協定,它有一個很大的特點就是命令的處理,和資料轉送的處理使用不同的連接埠和串連。而ActiveMQ使用的openwire協議其實就是一個個的操作命令。檔案分區、封裝、序列化,到另一頭再反向這個過程,無疑是效率很低下的。

大家有什麼想法都可以跟我交流:kimmking@163.com

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.