0

我有一个服务器集群(可能彼此远程),它们都Tomcat使用 Apache 通过 HTTP 运行和通信HttpClient。这些服务器中有大量是数据存储,其中一个服务器是前端 Web 服务器,充当客户端和存储之间的中介。用户应该能够将文件上传到网络服务器,并且网络服务器会将该文件传递给给定数量的商店。

所以,问题是:是否可以将客户端上传的文件部分作为一个文件InputStream并同时写入多个POST对商店的请求?如果我只是简单地写入本地文件,那么显而易见的解决方案就是将块读取InputStreambyte数组缓冲区中,然后依次从缓冲区写入每个输出,但我不知道如何说服 HttpClient像这样“分享”一个流。

是的,我可以简单地将整个数据读InputStream入网络服务器上的一个对象,然后按顺序将其写入每个存储,但由于我可能会接受非常大的文件,我必须将数据写入磁盘,然后再将其读回每个存储服务器,磁盘操作的数量可能会很快变得令人望而却步。这是我希望避免的实现。

4

2 回答 2

0

创建自己的输出流。将尽可能多的 HTTP POST 客户端附加到此流。如果您在输出流中收到日期,请将其发送到每个连接的 POST 客户端。

于 2013-08-12T14:44:16.790 回答
0

如果商店没有网络带宽来跟上,它如何“共享”流?

您可以拆分传入的文件并将其传递到存储而不将其写入磁盘,但如果只有一个存储无法跟上,您必须将该文件数据保存在内存中,直到它可以接受为止。如果它是一个大文件或许多用户,它可能会占用你所有的内存。

从技术上讲,我的意思是您可以创建 5 个线程,它们将尽可能快地将数据发送到存储区,并将文件数据保存在共享的 FIFO 结构中。当最后一个线程访问了一部分并发送了该部分时,可以从数据结构中删除该数据,但之前不能。如果速度很慢,数据结构可能会变得巨大。

数据必须在某个地方,如果不是内存也不是硬盘驱动器,那么在哪里?

因此,将传入的数据保留在内存中,直到(如果?)内存不足(永远不会?),然后将其刷新到硬盘驱动器。通过将数据发送到商店然后删除,继续尝试用数据清空数据结构。

你可以很容易地编写一个 ExecutorService 来处理数据的重新传输和清理数据结构,但这并不能神奇地解决问题。:)

我没有提供源代码,因为你似乎不想要这个解决方案。如果您接受不能神奇地传递数据而不必在硬盘驱动器上缓冲数据(或者更糟糕的解决方案是限制用户上传到 MinimumBandwidth(store1 , 商店 2, 商店 3, 商店 4, 商店 5))。

编辑/更改:

即使我这么说,我也不确定你是否真的想要一个 ExecutorService。我会创建自己的自定义线程来实际处理这个问题。我会从并发包创建一个集合,可能是一个保存字节数组(不是字节,字节数组)的 LinkedBlockingQueue。然后我会从 Thread->Integer 创建一个映射,它保存每个线程进程在传递数据时的当前索引。当所有进度数字都高于 10 时(意味着所有线程都发送了前 10 个块),然后我删除前 10 个字节数组,并从所有线程的进度中减去 10 以重置它。

于 2013-08-12T14:51:08.273 回答