cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alessio Soldano <asold...@redhat.com>
Subject JAX-WS client performances
Date Tue, 27 Jan 2015 17:14:51 GMT
Hi,
my attention has been recently brought to a scenario in which an Apache 
CXF client invokes an endpoint operation in a loop and the number of 
invocations performed in a given amount of time (say, 2 minutes) is used 
as benchmark for measuring WS stack performances. It's actually a very 
simplistic scenario, with a plain JAX-WS single thread client sending 
and receiving small RPC/Lit SOAP messages [1]. The reason why I've been 
asked to have a look is that with default settings the Apache CXF JAX-WS 
impl seems to perform *shamefully* bad compared to the Metro (JAX-WS RI) 
implementation. I've been blaming the user log configuration, etc but 
when I eventually tried on my own I could actually reproduce the bad 
results. I've been profiling a bit and found few hot spot area where CXF 
could possibly be optimized, but the big issue really seems to be at the 
HTTPCounduit / HTTPURLConnection level.
I found that almost all the invocations end up into 
sun.net.www.http.HttpClient.New(..) calling available() method [2] as 
part of the process for re-using cached connections [3]; that goes to 
the wire to try reading and takes a lot of time.
When the RI does the equivalent operation, the available() method is not 
called [4], resulting in much better performances.
By looking at the JDK code, it looks to me that the problem boils down 
to sun.net.www.protocol.http.HttpURLConnection#streaming() [5] returning 
different values, as a consequence of the fixedContentLenght attribute 
being set to a value different from -1 when running on CXF only. As a 
matter of fact, that is set when 
HTTPConduit.WrappedOutputStream#thresholdNotReached() is called, 
whenever a message is completely written to the outpustream buffer 
before the chunking threshold is reached (at least AFAIU). I've searched 
through the JAX-WS RI and could not find any place where 
setFixedLengthStreamingMode is called on the connection instead.
So, I've performed two quick and dirty tries: the first time I forced 
allowChunking = false on the client policy, the second time I commented 
out the code in HTTPConduit.WrappedOutputStream#thresholdNotReached(). 
In both cases I managed to get performances comparable to what I can get 
with the JAX-WS RI.
Now, few questions:
- are we really required to call setFixedLengthStreamingMode as we 
currently do? what's the drawback of not calling it?
- should we actually do something for getting decent performances by 
default in this scenario? (not sure expecting the user to disable 
chunking is that an option...)
As a side note, the relevant part of the JDK HttpClient code changed 
between JDK6 and JDK7, so things have not always been as explained above...

Cheers
Alessio


[1] http://www.fpaste.org/176166/14223765/
[2] http://pasteboard.co/FR5QVrP.png
[3] 
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/net/www/http/HttpClient.java#276
[4] http://pasteboard.co/FR8okYM.png
[5] 
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/net/www/protocol/http/HttpURLConnection.java#HttpURLConnection.streaming%28%29

-- 
Alessio Soldano
Web Service Lead, JBoss


Mime
View raw message