ActiveMQ 文件传输

来源:互联网 发布:软件研发中心管理制度 编辑:程序博客网 时间:2024/05/16 00:43

官方文档:http://activemq.apache.org/message-features.html

文档中引用其他网页内容!


方案

使用场景

优点

缺点

消息发送

小文件传输(文件转换为byte[],然后安装正常消息传送)

小文件简单方便

传输大文件效率低下

JMS Stream(弃用)

大文件传输(4.2版本前的用户)

以流的形式传输,解决大文件传输的问题

官方文档已经弃用该方案。推荐BlobMessage

自定义文件中转

大文件传输

不需要使用broker来传输文件,节省资源,效率高

需要独立FTP或者File服务器,且要处理复杂的io等方面的问题。

BlobMessage(推荐)

大文件传输

ActiveMQ封装复杂过程,提供方便的接口调用,内置Jetty提供httpServer,方便简单效率高

支持filehttpftp三种方式,内置httpserver,如果使用file方式需要自行搭建。

消息发送有如下几种方法:

1.作为消息发送,先读取所有的文件成byte[],然后使用ByteMessage,把文件数据发送到broker,像正常的message一样处理。只适合小文件发送。

2.JMS Stream

e.g.ActiveMQConnection connection = ...;Destination destination = new ActiveMQQueue("FOO.BAR");OutputStream out = connection.createOutputStream(destination);// write the file to outout.close();Or to consume a large messageActiveMQConnection connection = ...;Destination destination = new ActiveMQQueue("FOO.BAR");InputStream in = connection.createInputStream(destination)// read the stream...in.close();

发送端拿到文件后,首先分片,默认64K文件数据为一个byte message,然后依次把所有的message发送到brokerbroker转发给接收端,最后发送一个空消息作为结束符。

connection上提供了两个创建OutputStream的方法,一个是createOutputStream创建的是持久化的消息集合,这 些数据会写到磁盘或是数据库(对大文件来说慢消费也是一件可怕的事儿);一个是createNonPersistOutputStream创建的是非持久 化消息集合,不会写到磁盘上,如果没有及时消费掉就惨了。

文件片段的byte messageTTL设置为0,就是不会超时进入DLQ

适合小文件传输,特别是小于片(64k)大小的文件传输。

3. ActiveMQ把上面繁复的文件处理工作进行了封装,屏蔽掉文件中转的整个处理过程,使得我们可以使用类似jms规范的API来简单操作文件传输。

发送端:

3.1

启动ActiveMQ时,也启动jetty(activemq.xml中有import jetty.xml),此时jetty中运行了一个ActiveMQ自带的http文件服务器

3.2       

tcp://localhost:61616?jms.blobTransferPolicy.defaultUploadUrl=http://localhost:8161/fileserver/创建connection,然后创建sessionproducer

3.3 

使用如下代码发送文件:

BlobMessageblobMessage = session.createBlobMessage(file); blobMessage.setStringProperty("FILE.NAME",file.getName()); blobMessage.setLongProperty("FILE.SIZE",file.length()); producer.send(blobMessage); 

接收端:

InputStream inputStream = blobMessage.getInputStream();

然后直接读取文件数据即可。文件名和文件大小可以从message的属性中拿到。

3.4过程讲解:

发送端:producer.send的时候,把文件通过http协议的PUT方法发到jetty中的fileserver(默认128Khttpchunk分片传输)。然后把httpurl写入消息中。再把消息发送到broker

接收端:接收到消息以后,发现是BlobMessage,拿到url,直接使用GET方法获取文件数据。处理完毕后,使用DELETE方法从fileserver删除文件。

3.5 BlobMessage支持3种文件中转方式:

FILE

要求clientbroker在同一个机器或者使用同一个共享存储。发送文件的时候,把文件从本地写入到指定路径。接收文件的时候,把文件从此路径读出来。

HTTP

使用httpfileserverPUT/GET/DELETE方法。ActiveMQ自带了简单的实现。就是前面场景中使用的方式。

FTP

使用一个独立的ftpserver作为文件中转方式。发送文件的时候,把文件发送到ftp服务器。接收文件的时候,从ftp把文件读取下来。

3.6 ActiveMQ 对大文件进行传输的时候,有四种方式:

1. BlobUploader:该方法采用内置的Jetty,有个HttpServer服务器

2. FTPBlobDownloadStratrgy:该方法需要自行搭建FTP服务器。

3. FileSystemBlobStrategy:该方法需要搭建文件服务器。

4. DefaultBlobDownloadStrategy:该方法采用缺省方式。

3.7 内部原理

发送端:producer.send的时候,把文件通过http协议的PUT方法发到jetty中的fileserver(默认128Khttpchunk分片传输)。然后把httpurl写入消息中。再把消息发送到broker

接收端:接收到消息以后,发现是BlobMessage,拿到url,直接使用GET方法获取文件数据。处理完毕后,使用DELETE方法从fileserver删除文件。

文件发送:

import java.io.File;import javax.jms.Connection;import javax.jms.ConnectionFactory;import javax.jms.DeliveryMode;import javax.jms.Destination;import javax.jms.JMSException;import javax.jms.MessageProducer;import javax.jms.Session;import javax.swing.JFileChooser;import org.apache.activemq.ActiveMQConnectionFactory;import org.apache.activemq.ActiveMQSession;import org.apache.activemq.BlobMessage;public class FileSender {public static void main(String[] args) {File file = getFile();// 获取 ConnectionFactory// Activemq内置Http服务器(Jetty内置)ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://10.11.116.21:61616?jms.blobTransferPolicy.defaultUploadUrl=http://10.11.116.21:8161/fileserver/");MessageProducer producer = null;ActiveMQSession session = null;Connection connection = null;try {// 创建 Connectionconnection = connectionFactory.createConnection();connection.start();// 创建 Sessionsession = (ActiveMQSession) connection.createSession(false,Session.AUTO_ACKNOWLEDGE);// 创建 DestinationDestination destination = session.createQueue("File.Transport");// 创建 Producerproducer = session.createProducer(destination);producer.setDeliveryMode(DeliveryMode.PERSISTENT);// 设置为持久性// 设置持久性的话,文件也可以先缓存下来,接收端离线再连接也可以收到文件// 构造 BlobMessage,用来传输文件BlobMessage blobMessage = session.createBlobMessage(file);// 通过set方法对对象属性进行赋值blobMessage.setStringProperty("FILE.NAME", file.getName());blobMessage.setLongProperty("FILE.SIZE", file.length());System.out.println("开始发送文件:" + file.getName() + ",文件大小:"+ file.length() + " 字节");// 7. 发送文件producer.send(blobMessage);System.out.println("完成文件发送:" + file.getName());} catch (Exception e) {e.printStackTrace();} finally {try {producer.close();} catch (JMSException e) {e.printStackTrace();}try {session.close();} catch (JMSException e) {e.printStackTrace();}try {connection.close();} catch (JMSException e) {e.printStackTrace();}}}private static File getFile() {// 选择要上传的文件JFileChooser fileChooser = new JFileChooser();fileChooser.setDialogTitle("请选择要传送的文件");if (fileChooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION) {return null;}File file = fileChooser.getSelectedFile();return file;}}

文件接收:

import java.io.File;import javax.jms.Connection;import javax.jms.ConnectionFactory;import javax.jms.DeliveryMode;import javax.jms.Destination;import javax.jms.JMSException;import javax.jms.MessageProducer;import javax.jms.Session;import javax.swing.JFileChooser;import org.apache.activemq.ActiveMQConnectionFactory;import org.apache.activemq.ActiveMQSession;import org.apache.activemq.BlobMessage;public class FileSender {public static void main(String[] args) {File file = getFile();// 获取 ConnectionFactory// Activemq内置Http服务器(Jetty内置)ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://10.11.116.21:61616?jms.blobTransferPolicy.defaultUploadUrl=http://10.11.116.21:8161/fileserver/");MessageProducer producer = null;ActiveMQSession session = null;Connection connection = null;try {// 创建 Connectionconnection = connectionFactory.createConnection();connection.start();// 创建 Sessionsession = (ActiveMQSession) connection.createSession(false,Session.AUTO_ACKNOWLEDGE);// 创建 DestinationDestination destination = session.createQueue("File.Transport");// 创建 Producerproducer = session.createProducer(destination);producer.setDeliveryMode(DeliveryMode.PERSISTENT);// 设置为持久性// 设置持久性的话,文件也可以先缓存下来,接收端离线再连接也可以收到文件// 构造 BlobMessage,用来传输文件BlobMessage blobMessage = session.createBlobMessage(file);// 通过set方法对对象属性进行赋值blobMessage.setStringProperty("FILE.NAME", file.getName());blobMessage.setLongProperty("FILE.SIZE", file.length());System.out.println("开始发送文件:" + file.getName() + ",文件大小:"+ file.length() + " 字节");// 7. 发送文件producer.send(blobMessage);System.out.println("完成文件发送:" + file.getName());} catch (Exception e) {e.printStackTrace();} finally {try {producer.close();} catch (JMSException e) {e.printStackTrace();}try {session.close();} catch (JMSException e) {e.printStackTrace();}try {connection.close();} catch (JMSException e) {e.printStackTrace();}}}private static File getFile() {// 选择要上传的文件JFileChooser fileChooser = new JFileChooser();fileChooser.setDialogTitle("请选择要传送的文件");if (fileChooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION) {return null;}File file = fileChooser.getSelectedFile();return file;}}


0 0
原创粉丝点击