ActiveMQ 文件传输

官方文档: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 out
out.close();

Or to consume a large message
ActiveMQConnection 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 {
			// 创建 Connection
			connection = connectionFactory.createConnection();
			connection.start();
			// 创建 Session
			session = (ActiveMQSession) connection.createSession(false,
					Session.AUTO_ACKNOWLEDGE);
			// 创建 Destination
			Destination destination = session.createQueue("File.Transport");
			// 创建 Producer
			producer = 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 {
			// 创建 Connection
			connection = connectionFactory.createConnection();
			connection.start();
			// 创建 Session
			session = (ActiveMQSession) connection.createSession(false,
					Session.AUTO_ACKNOWLEDGE);
			// 创建 Destination
			Destination destination = session.createQueue("File.Transport");
			// 创建 Producer
			producer = 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;
	}
}


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值