负载下Apache Camel Route性能下降

时间:2019-01-25 15:55:22

标签: soap apache-camel cxf

我正在使用Apache Camel根据请求消息中的特定属性路由SOAP请求。邮件与正则表达式匹配,如果找到匹配项,则请求将被路由到“ calldestination1”,否则将被路由到“ calldestination2”。

我正在使用以下配置:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:camel="http://camel.apache.org/schema/spring"
    xmlns:cxf="http://camel.apache.org/schema/cxf"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
    http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd">

<!-- ... -->

<cxf:cxfEndpoint id="testEndpointTest"
    address="http://localhost:8080/testEndpoint"
    endpointName="s:testEndpoint_Port"
    serviceName="s:testEndpoint"
    wsdlURL="wsdl/testEndpoint.wsdl"
    xmlns:s="http://teste.com/testEndpoint"/>

<!-- ... -->

<camelContext xmlns="http://camel.apache.org/schema/spring">

    <endpoint id="calldestination1" uri="http://localhost:8080/destination1?bridgeEndpoint=true&amp;throwExceptionOnFailure=false"/>
    <endpoint id="calldestination2" uri="http://localhost:8080/destination2?bridgeEndpoint=true&amp;throwExceptionOnFailure=false"/>

    <route streamCache="true">
        <!--CXF consumer using MESSAGE format--> 
        <from uri="cxf:bean:testEndpointTest?dataFormat=MESSAGE"/>

        <choice>
            <when>
                <simple>${bodyAs(java.lang.String)} regex ${properties:router.regex}</simple>
                <to uri="calldestination1"/>
            </when>
            <otherwise>
                <to uri="calldestination2"/>
            </otherwise>
        </choice>

    </route>

</camelContext>

运行“ calldestination2”的目标服务器处于负载状态时,请求可能需要大约1150毫秒进行响应。 Apache Camel似乎不能很好地解决这个问题。

为了复制此行为,我将SoapUI与SOAP MockService一起使用,并带有延迟(OnRequest脚本)和jmeter。 首先,我没有延迟地对SoapUI MockService进行了测试,然后延迟了1100ms。
然后,我将Apache Camel配置为将请求路由到SoapUI服务并重复测试。

JMeter-> SoapUI-延迟0毫秒
每秒约1200个请求;平均25ms请求; 0%错误

JMeter-> SoapUI-1100ms延迟
每秒约100个请求;平均要求1128毫秒; 0%错误

JMeter-> Apache Camel-> SoapUI-0ms延迟
每秒约420个请求;平均285毫秒要求; 0%错误

JMeter-> Apache Camel-> SoapUI-1100ms延迟
每秒约8个请求;平均要求14800毫秒;超时错误率达97.23%

Apache Camel中的超时设置为30秒。

为什么在最后一种情况下Apache Camel的性能这么低,我该如何改善呢?

修改1
我在GitHub上创建了一个存储库,其中包含Apache Camel项目,SoapUI模拟服务和jmeter测试,以便于测试。

https://github.com/jraimundo/apache-camel-route-tester

1 个答案:

答案 0 :(得分:2)

基本问题

此类问题始终是资源问题。只要所有组件都有足够的资源并能快速回答,就可以了。一旦其中之一遇到资源限制,它就会变慢。

在JMeter-SoapUI场景中, SoapUI的有意延迟由JMeter处理。由于SoapUI花费了超过一秒钟的时间来响应,因此JMeter请求暂时保持打开状态。如果用于请求的JMeter线程池已用尽(所有线程都在等待SoapUI的答复),则无法进一步扩展。根据您的度量,线程池大小可能为100。

然后将骆驼放在中间。这样,您引入了新的线程池。必须有一个接收请求(CXF),并且可能有一个发送请求(Camel HTTP)。现在, SoapUI延迟也必须由这些池处理。情况相同,但现在Camel组件的线程池已成为限制。

我们假设Camel HTTP请求的线程池默认为10。 JMeter开始发送请求。如果 JMeter发送新请求的速度快于SoapUI的响应速度,则向SoapUI发送HTTP请求的10个线程将非常繁忙(正在等待SoapUI)。

JMeter的新请求到达,但是直到直到其中一个线程再次空闲为止,才可能有新的对SoapUI的HTTP请求。在这种情况下,大约有8个并行请求(根据您的测量)似乎是合理的。

因此,很显然,如果您想在这种情况下每秒处理100个请求,则需要调整所有涉及的线程池以进行处理。而且,您还必须微调不同的超时(CXF,Camel HTTP)。

您的代码

我在您的代码中注意到的一点是,您将Camel HTTP component用于目标端点。该组件使用Apache HTTP client 3.x

如果要使用最新的Apache HTTP client,则必须使用Camel HTTP4 component(4,因为它使用Apache HTTP客户端4.x)。我不知道它是否有很大的不同,但是多年来,旧版本被宣布为“寿命终止”。

另一件事是超时。您写道,您将骆驼超时设置为30秒。但这可能不是CXF或Apache HTTP客户端的超时。 HTTP客户端有多个超时:建立连接可能花费太长时间,并且接收响应可能花费太长时间。