Camel反向代理 - 没有响应流缓存

时间:2014-07-21 08:59:14

标签: apache-camel

我正在尝试实现一个仅用于流的内存高效的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&amp;throwExceptionOnFailure=false&amp;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

1 个答案:

答案 0 :(得分:0)

除非您按需访问消息体,否则它们不会将流读入内存,并告诉Camel将其作为String类型等读入内存。

请参阅此烹饪书示例如何执行基于流的代理