Hi,
I developed a camel cxf component that is configured to failover to
alternate addresses in case of connections /availability failures.
The camel component is a simple timer that sends every second a request to
a webservice.
The camel route is the following :
public void configure() throws Exception {
from("timer:timerRetrieveAvailableJobs?fixedRate=trueꗪ=1000")
.setBody(constant(getRequestMessage())
.setHeader(CxfConstants.OPERATION_NAME,
constant("getAvailableJobs"))
.to("cxf:bean:cxfJobsWsEndpoint?synchronous=true隈₊砅禫溭榹=true");
private String getRequestMessage(){
//Build the right request
...
The camel-context.xml configures the clustering failover as below :
...
<cxf:cxfEndpoint id="cxfJobsWsEndpoint"
serviceClass="net.jobs.ws.myPTServiceClass" address="
http://localhost/myservice/JobWS">
<cxf:features>
<clustering:failover>
<clustering:strategy>
<bean
class="org.apache.cxf.clustering.SequentialStrategy">
<property name="alternateAddresses">
<util:list>
<value>http://server1/JobWS</value>
<value>http://server2/JobWS</value>
</util:list>
</property>
</bean>
</clustering:strategy>
</clustering:failover>
</cxf:features>
<cxf:properties>
<entry key="dataFormat" value="MESSAGE" />
</cxf:properties>
</cxf:cxfEndpoint>
...
After a few hours, a dump of JVM memory shows that some objects of CXF
(org.apage.cxf.xxxx) are created and remain in the memory. They are not
accessible by the GC. Their number continues to grow and causes a memory
leak after a long term :
command : jmap -histo:live 25698 | grep cxf
8: 90660 9428640
[Lorg.apache.cxf.phase.PhaseInterceptorChain$InterceptorHolder;
20: 135989 3263736
org.apache.cxf.phase.PhaseInterceptorChain$InterceptorHolder
22: 45328 2900992 org.apache.cxf.message.MessageImpl
24: 45330 2175840
org.apache.cxf.phase.PhaseInterceptorChain
25: 22664 1994432 org.apache.cxf.message.ExchangeImpl
33: 45328 1087872
org.apache.cxf.phase.PhaseInterceptorChain$PhaseInterceptorIterator
36: 22664 906560
org.apache.cxf.clustering.FailoverTargetSelector$InvocationContext
40: 22664 725248
org.apache.cxf.helpers.LoadingByteArrayOutputStream$1
41: 45328 725248 org.apache.cxf.binding.soap.SoapMessage
46: 22664 543936
org.apache.cxf.message.MessageContentsList
51: 22664 362624
org.apache.cxf.helpers.LoadingByteArrayOutputStream
52: 22664 362624
org.apache.cxf.clustering.FailoverTargetSelector$InvocationKey
I tried the same test without failover configuration and I was surprised :
the component continues to work without memory problem. The objects above
are collected and removed by the GC.
It seems that the classes that implement the clustering failover retain
created objects and prevent their removal.
The test has been done on the following configurations :
* apache-servicemix-3.4.0, cxf 2.4.4, camel 2.8.3
* apache-servicemix-3.5.0-fuse-00-00, cxf 2.2.11, camel 2.5
Any help will be appreciated.
Thanks
Regards
Adnan
I developed a camel cxf component that is configured to failover to
alternate addresses in case of connections /availability failures.
The camel component is a simple timer that sends every second a request to
a webservice.
The camel route is the following :
public void configure() throws Exception {
from("timer:timerRetrieveAvailableJobs?fixedRate=trueꗪ=1000")
.setBody(constant(getRequestMessage())
.setHeader(CxfConstants.OPERATION_NAME,
constant("getAvailableJobs"))
.to("cxf:bean:cxfJobsWsEndpoint?synchronous=true隈₊砅禫溭榹=true");
private String getRequestMessage(){
//Build the right request
...
The camel-context.xml configures the clustering failover as below :
...
<cxf:cxfEndpoint id="cxfJobsWsEndpoint"
serviceClass="net.jobs.ws.myPTServiceClass" address="
http://localhost/myservice/JobWS">
<cxf:features>
<clustering:failover>
<clustering:strategy>
<bean
class="org.apache.cxf.clustering.SequentialStrategy">
<property name="alternateAddresses">
<util:list>
<value>http://server1/JobWS</value>
<value>http://server2/JobWS</value>
</util:list>
</property>
</bean>
</clustering:strategy>
</clustering:failover>
</cxf:features>
<cxf:properties>
<entry key="dataFormat" value="MESSAGE" />
</cxf:properties>
</cxf:cxfEndpoint>
...
After a few hours, a dump of JVM memory shows that some objects of CXF
(org.apage.cxf.xxxx) are created and remain in the memory. They are not
accessible by the GC. Their number continues to grow and causes a memory
leak after a long term :
command : jmap -histo:live 25698 | grep cxf
8: 90660 9428640
[Lorg.apache.cxf.phase.PhaseInterceptorChain$InterceptorHolder;
20: 135989 3263736
org.apache.cxf.phase.PhaseInterceptorChain$InterceptorHolder
22: 45328 2900992 org.apache.cxf.message.MessageImpl
24: 45330 2175840
org.apache.cxf.phase.PhaseInterceptorChain
25: 22664 1994432 org.apache.cxf.message.ExchangeImpl
33: 45328 1087872
org.apache.cxf.phase.PhaseInterceptorChain$PhaseInterceptorIterator
36: 22664 906560
org.apache.cxf.clustering.FailoverTargetSelector$InvocationContext
40: 22664 725248
org.apache.cxf.helpers.LoadingByteArrayOutputStream$1
41: 45328 725248 org.apache.cxf.binding.soap.SoapMessage
46: 22664 543936
org.apache.cxf.message.MessageContentsList
51: 22664 362624
org.apache.cxf.helpers.LoadingByteArrayOutputStream
52: 22664 362624
org.apache.cxf.clustering.FailoverTargetSelector$InvocationKey
I tried the same test without failover configuration and I was surprised :
the component continues to work without memory problem. The objects above
are collected and removed by the GC.
It seems that the classes that implement the clustering failover retain
created objects and prevent their removal.
The test has been done on the following configurations :
* apache-servicemix-3.4.0, cxf 2.4.4, camel 2.8.3
* apache-servicemix-3.5.0-fuse-00-00, cxf 2.2.11, camel 2.5
Any help will be appreciated.
Thanks
Regards
Adnan