我正在尝试实现一个仅用于流的内存高效的http反向代理。 Jetty使用者将输入流放入交换机中,我可以将其与http生成器挂钩以转发请求。没问题。
然而,我所知道的所有http生成器(Jetty,http4,netty-http)都将响应流读入堆内存,并以某种形式将其内容放入交换中,而不是流的句柄。他们似乎都没有提供让他们这样做的选择。
我发现这个thread描述了同样的问题,并提出了一个解决方案。但是看看Camel 2.13.1中的http4 HttpProducer的代码,它看起来并不像拟议的更改毕竟进入了Camel代码库。
有没有办法用Camel实现仅流方法?因此,在内存占用量最小的情况下,我可以采取以下措施:
<route id="reverse_proxy" streamCache="false">
<from ref="jetty.http.server"/>
<bean ref="streamHolder" method="enableCaching"/>
<bean ref="streamHolder" method="parsePayloadHeaderInfoAndDoStuff"/>
<bean ref="streamHolder" method="resetStream"/>
<to ref="http.client"/> <!-- Register completion synchronization hook to close stream. -->
<bean ref="streamHolder" method="enableCaching"/>
<bean ref="streamHolder" method="parsePayloadResponseHeaderAndDoStuff"/>
<bean ref="streamHolder" method="resetStream"/>
</route>
编辑 - 有关输入流在内存中的最终位置的其他信息:
http4 :一切都发生在org.apache.camel.component.http4.HttpProducer :: process() - &gt; populateResponse(..) - &gt; extractResponseBody(..) - &gt; doExtractResponseBodyAsStream()
;这里将原始流复制到CachedOutputStream
的实例中。
Jetty :org.eclipse.jetty.client.AsyncHttpConnection :: handle() - &gt; org.eclipse.jetty.http.HttpParser::parseNext()
将填充org.eclipse.jetty.client.ContentExchange
中的CachedExchange
字节数组HttpExchange
。
netty-http :构建一个管道,将HttpResponse内容组合为复合ChannelBuffer。包装的通道缓冲区构成完整的响应流。
我已经调试了所有三个客户端,并没有偶然发现一个没有采用的分支,这会让我将原始输入流作为交换体。
这可以通过如下简单的路线重现:
<camelContext id="pep-poc">
<endpoint id="jetty.http.server" uri="jetty:http://{{http.host.server}}:{{http.port.server}}/my/frontend?disableStreamCache=true"/>
<endpoint id="http.client" uri="jetty:http://{{http.host.client}}:{{http.port.client}}/large_response.html?bridgeEndpoint=true&throwExceptionOnFailure=false&disableStreamCache=true"/>
<route id="reverse_proxy" startupOrder="10" streamCache="false">
<from ref="jetty.http.server"/>
<to ref="http.client"/>
</route>
</camelContext>
我有一个Apache2将{750}文件作为large_response.html
返回。
编辑2
确实,这是所有可用HTTP生产者的问题。请参阅Camel mailing list上的此帖子以及相应的JIRA ticket。
答案 0 :(得分:0)
除非您按需访问消息体,否则它们不会将流读入内存,并告诉Camel将其作为String类型等读入内存。
请参阅此烹饪书示例如何执行基于流的代理