我正在使用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&throwExceptionOnFailure=false"/>
<endpoint id="calldestination2" uri="http://localhost:8080/destination2?bridgeEndpoint=true&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测试,以便于测试。
答案 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客户端有多个超时:建立连接可能花费太长时间,并且接收响应可能花费太长时间。