user1719443
user1719443

Reputation:

Spring WS and MultiThreadedHttpConnectionManager

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

Answers (1)

Tomasz Nurkiewicz
Tomasz Nurkiewicz

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 the CommonsHttpMessageSender, 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

Related Questions