Reputation:
I have a web service on Spring WS 2.1.0. Web service runs on Tomcat 7 and implements an endpoint with one transactional method that read data from database and generate different reports. Tomcat 7 runs behind Apache Server via JServ protocol.
During stress test via Apache JMeter I came to conclusion that simultaneous requests are handled serially. At first I tried to tune database connection pool (commons-dbcp and later tomcat-jdbc) but result was the same. Endpoint method only reads data, so there are no read-after-write or write-after-read dependencies and transactions could by handled in parallel. Thus the problem is in HTTP connections handling.
After some searching (and googling, of course) I found out that Spring WS comes with the default connection manager(SimpleHttpConnectionManager) which is single threaded. The good practise is to replace SimpleHttpConnectionManager with MultiThreadedHttpConnectionManager. I found sample code that looks like this:
<bean id="httpClient" class="org.apache.commons.httpclient.HttpClient">
<constructor-arg>
<bean class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager>
<property name="maxConnectionsPerHost" value="20"/>
<property name="maxTotalConnections" value="100"/>
</bean>
</constructor-arg>
</bean>
But this example isn't rather clear to me because I don't understand how Spring uses HttpClient (refers to ID or autowiring it). So how can I use MultiThreadedHttpConnectionManager with Spring in my case? Where should I inject configured instance of this class?
Upvotes: 1
Views: 6225
Reputation: 340763
You are misunderstanding the usage of HttpClient
. It's only used in Spring WS client module to initiate HTTP connections, see 6.2.1.1.1. HTTP transports:
There are two implementations of the
WebServiceMessageSender
interface for sending messages via HTTP. [...] The alternative is theCommonsHttpMessageSender
, which uses the Jakarta Commons HttpClient.
HttpClient
is not needed at all when Spring WS is used on the server side. In that case it's the servlet container that provides HTTP (server) abstraction. Check out your Tomcat configuration, maybe the thread pool is too small and some requests are queued? HttpClient
has absolutely nothing to do here. I'm sorry, but you'll have to look for a problem somewhere else.
Just to keep the answer complete, when you use Spring WS to access SOAP services on other computer, the following settings of HttpClient
apply:
maxConnectionsPerHost
- how many concurrent connections HttpClient
is allowed to keep to the same host (see: Keep-Alive
header)? Most browsers limit the number of concurrent connections to the same host to 2/4/8. HttpClient
follows that behaviour, so in principle you cannot have more then 2/4/8 (whatever you set here) concurrent connections to the same host.
maxTotalConnections
- like above, but total to all hosts. If you are connecting to hundreds of different web services on different servers, this is the total number of open connections HttpClient
can keep
Upvotes: 5