【问题标题】:Upload a blob file with Java to an AmazonMQ queue (ActiveMQ)使用 Java 将 blob 文件上传到 AmazonMQ 队列 (ActiveMQ)
【发布时间】:2020-03-18 19:49:37
【问题描述】:

我必须使用 Amazon MQ。 Amazon MQ 基于 ActiveMQ。我找到了一些代码,它应该在队列中放置一条 blob 消息(PDF 大小 230kB)。但是如果我运行程序,它会在下面的错误堆栈中出错。

这是我的代码:

private final static String WIRE_LEVEL_ENDPOINT = "ssl://<examplednsname>-1.amazonaws.com:61617";
private final static String ACTIVE_MQ_USERNAME = "test123";
private final static String ACTIVE_MQ_PASSWORD = "test123";

public static void sendFileViaQueue(String uri, String queueName) throws JMSException {
    File file = new File("test.pdf");
    ConnectionFactory connectionFactory = null;
    Connection connection = null;
    Session session = null;
    BlobMessage blobMsg = null;
    MessageProducer producer = null;
    try {
        connectionFactory = new ActiveMQConnectionFactory(ACTIVE_MQ_USERNAME, ACTIVE_MQ_PASSWORD, WIRE_LEVEL_ENDPOINT);
        connection = connectionFactory.createConnection();
        connection.start();
        session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
        producer = session.createProducer(session.createQueue(queueName));
        blobMsg = ((ActiveMQSession) session).createBlobMessage(file);
        blobMsg.setStringProperty("FILE.NAME", file.getName());
        blobMsg.setLongProperty("FILE.SIZE", file.length());
        producer.send(blobMsg);
        session.commit();
    } finally {
        closeQuietly(producer);
        closeQuietly(session);
        closeQuietly(connection);
    }
}

它似乎想要上传一些东西到 8080,但我没有在本地配置任何东西。它只应该将 PDF 上传到队列中。

有没有人想办法解决这个问题? 只需将 blob 上传到队列就不会那么复杂。

这是我得到的堆栈跟踪:

javax.jms.JMSException: PUT failed to: http://localhost:8080/uploads/ID:bpSligro-PC-50920-1584558692848-1:1:1:1:1
    at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:72)
    at org.apache.activemq.command.ActiveMQBlobMessage.onSend(ActiveMQBlobMessage.java:177)
    at org.apache.activemq.ActiveMQSession.send(ActiveMQSession.java:1952)
    at org.apache.activemq.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:288)
    at org.apache.activemq.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:223)
    at org.apache.activemq.ActiveMQMessageProducerSupport.send(ActiveMQMessageProducerSupport.java:241)
    at nl.bpittens.mq.AmazonMQExample.sendFileViaQueue(AmazonMQExample.java:81)
    at nl.bpittens.mq.AmazonMQExample.main(AmazonMQExample.java:52)
Caused by: java.io.IOException: PUT failed to: http://localhost:8080/uploads/ID:bpSligro-PC-50920-1584558692848-1:1:1:1:1
    at org.apache.activemq.blob.DefaultBlobUploadStrategy.uploadStream(DefaultBlobUploadStrategy.java:67)
    at org.apache.activemq.blob.DefaultBlobUploadStrategy.uploadFile(DefaultBlobUploadStrategy.java:44)
    at org.apache.activemq.blob.BlobUploader.upload(BlobUploader.java:53)
    at org.apache.activemq.command.ActiveMQBlobMessage.onSend(ActiveMQBlobMessage.java:174)
    ... 6 more
Caused by: java.net.ConnectException: Connection refused: connect
    at java.net.DualStackPlainSocketImpl.connect0(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at java.net.Socket.connect(Socket.java:538)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:180)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
    at sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
    at sun.net.www.http.HttpClient.New(HttpClient.java:339)
    at sun.net.www.http.HttpClient.New(HttpClient.java:357)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1220)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:984)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1334)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1309)
    at org.apache.activemq.blob.DefaultBlobUploadStrategy.uploadStream(DefaultBlobUploadStrategy.java:60)
    ... 9 more

发送一个普通的 JMS TextMessage 没有问题。

【问题讨论】:

    标签: java jms activemq amazon-mq


    【解决方案1】:

    the documentation 中所述,一条“blob”消息:

    允许在一些带外传输机制中发送大量 BLOB(二进制大对象)。可能的带外机制可能是 HTTP、FTP 或 SCP 或其他一些点对点协议。

    请注意,必须“以某种带外传输机制”发送实际的二进制数据。换句话说,blob 实际上并没有进入队列。 Blob 被上传到其他地方,进入队列的消息只是指向那个位置。

    您需要使用客户端 URL 上的 jms.blobTransferPolicy.uploadUrl 参数配置传输策略。默认传输策略的默认上传 URL 是 http://localhost:8080/uploads/,这是您的客户端试图用来上传二进制数据的 URL。

    如果您想将任意大的消息直接发送到队列而不是使用一些带外机制,请考虑移至支持that functionalityActiveMQ Artemis

    如果您在使用 Amazon MQ 时遇到问题,那么除了某种手动解决方案之外,我认为您没有任何其他解决方案,您可以将文件分成更小的块,您可以将这些块放入单独的消息中,然后重新组合这些稍后在消费应用程序中的块。

    【讨论】:

    • 我想如果我想上传这样的文件,那么这是一个错误的解决方案。似乎没有人使用它,因为互联网上没有信息。如果您使用排队,那么您这样做是为了获得可靠的消息传递解决方案。使用上传服务器是不可靠的。所以我的问题是,如果我想将大文件上传到 Amazon MQ,那么最好的解决方案是什么?例如 PDF 文件。
    • 最好的解决方案是适合您并满足您要求的解决方案。
    • 嗨,谢谢大家的cmets。如果要求发送大于 100 MB 的大型 XML 文件并且我们想要发送图像和 pdf,我认为 Amazon MQ 不适合我们。我对这个结论是否正确?我还读到,在 Amazon MQ 和 ActiveMQ 中,队列上消息的最大消息大小为 32 MB。
    • 如果您的要求包括发送文件的能力 > 100MB 并且您不想使用 blob 消息的带外传输机制,那么我认为 Amazon MQ 不适合.正如我之前提到的,ActiveMQ Artemis 非常适合,因为它支持任意大的消息。
    • 谢谢贾斯汀,但如果我的信息是正确的,那么 Amazon MQ 没有实现 Artemis ?
    猜你喜欢
    • 2014-02-06
    • 2018-12-23
    • 2020-04-12
    • 2022-12-17
    • 2017-03-14
    • 2017-07-10
    • 1970-01-01
    • 2019-08-08
    相关资源
    最近更新 更多