You are viewing a plain text version of this content. The canonical link for it is here.
Posted to httpclient-users@hc.apache.org by Nir Dweck <ni...@vasco-de.com> on 2012/12/16 12:03:08 UTC
Socket leak of Async HTTP server
Hi,
I am new to HTTP Components. I wrote a short server which is based on the
Asynchronous HTTP Server example. I am using httpcore-4.2.2 and
httpcore-nio-4.2.2. I wrote a short test program that loads my server. I
see that after ~500,000 requests I get a socket leak of ~600 sockets. I got
84 SocketTimeoutException during the test. After I got to a big number of
leak sockets the application stopped responding and I couldn't even connect
to it with remote debugger.
bellow is my test.
Regards,
Nir
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package httpsample;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.net.InetSocketAddress;
import java.net.URL;
import java.security.KeyStore;
import java.util.Calendar;
import java.util.logging.Level;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.nio.DefaultHttpServerIODispatch;
import org.apache.http.impl.nio.DefaultNHttpServerConnection;
import org.apache.http.impl.nio.DefaultNHttpServerConnectionFactory;
import org.apache.http.impl.nio.SSLNHttpServerConnectionFactory;
import org.apache.http.impl.nio.reactor.DefaultListeningIOReactor;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.nio.NHttpConnectionFactory;
import org.apache.http.nio.NHttpServerConnection;
import org.apache.http.nio.protocol.BasicAsyncRequestConsumer;
import org.apache.http.nio.protocol.BasicAsyncResponseProducer;
import org.apache.http.nio.protocol.HttpAsyncExchange;
import org.apache.http.nio.protocol.HttpAsyncRequestConsumer;
import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
import org.apache.http.nio.protocol.HttpAsyncResponseProducer;
import org.apache.http.nio.protocol.HttpAsyncService;
import org.apache.http.nio.reactor.IOEventDispatch;
import org.apache.http.nio.reactor.ListeningIOReactor;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.params.SyncBasicHttpParams;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.ImmutableHttpProcessor;
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;
import org.apache.log4j.xml.DOMConfigurator;
/**
* HTTP/1.1 file server based on the non-blocking I/O model and capable of
direct channel
* (zero copy) data transfer.
*/
public class Httpsample {
static private org.apache.log4j.Logger log =
org.apache.log4j.Logger.getLogger(Httpsample.class.getName());
static private final int DFLT_NUM_WORKERS = 200;
static private final int DFLT_PORT = 20003;
static public boolean STAND_ALONE = false;
public static void main(String[] args) throws Exception {
int numOfWorkers = DFLT_NUM_WORKERS;
int port = DFLT_PORT;
for ( int i = 0; i < args.length; i++) {
switch (i){
case 0:
port = Integer.parseInt(args[i]);
break;
case 1:
numOfWorkers = Integer.parseInt(args[i]);
break;
case 2:
STAND_ALONE = true;
break;
}
}
// start log4j system
Calendar now = Calendar.getInstance();
System.setProperty("log4j.year",
Integer.toString(now.get(Calendar.YEAR)));
System.setProperty("log4j.month",
Integer.toString(now.get(Calendar.MONTH) + 1));
System.setProperty("log4j.day",
Integer.toString(now.get(Calendar.DATE)));
System.setProperty("log4j.hours",
Integer.toString(now.get(Calendar.HOUR_OF_DAY)));
System.setProperty("log4j.minutes",
Integer.toString(now.get(Calendar.MINUTE)));
System.setProperty("log4j.seconds",
Integer.toString(now.get(Calendar.SECOND)));
DOMConfigurator.configure("log.xml");
// HTTP parameters for the server
HttpParams params = new SyncBasicHttpParams();
params
.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 20000)
.setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 *
1024)
.setParameter(CoreProtocolPNames.ORIGIN_SERVER, "VascoDE/1.1");
// Create HTTP protocol processing chain
HttpProcessor httpproc = new ImmutableHttpProcessor(new
HttpResponseInterceptor[] {
// Use standard server-side protocol interceptors
new ResponseDate(),
new ResponseServer(),
new ResponseContent(),
new ResponseConnControl()
});
// Create request handler registry
HttpAsyncRequestHandlerRegistry reqistry = new
HttpAsyncRequestHandlerRegistry();
// Register the default handler for all URIs
reqistry.register("*", new HttpFileHandler());
// Create server-side HTTP protocol handler
HttpAsyncService protocolHandler = new HttpAsyncService(
httpproc, new DefaultConnectionReuseStrategy(), reqistry,
params) {
@Override
public void connected(final NHttpServerConnection conn) {
System.out.println(conn + ": connection open");
super.connected(conn);
}
@Override
public void closed(final NHttpServerConnection conn) {
System.out.println(conn + ": connection closed");
super.closed(conn);
}
};
// Create HTTP connection factory
NHttpConnectionFactory<DefaultNHttpServerConnection> connFactory;
if (port == 8443) {
// Initialize SSL context
ClassLoader cl = Httpsample.class.getClassLoader();
URL url = cl.getResource("my.keystore");
if (url == null) {
System.out.println("Keystore not found");
System.exit(1);
}
KeyStore keystore = KeyStore.getInstance("jks");
keystore.load(url.openStream(), "secret".toCharArray());
KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
kmfactory.init(keystore, "secret".toCharArray());
KeyManager[] keymanagers = kmfactory.getKeyManagers();
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(keymanagers, null, null);
connFactory = new SSLNHttpServerConnectionFactory(sslcontext,
null, params);
} else {
connFactory = new DefaultNHttpServerConnectionFactory(params);
}
// Create server-side I/O event dispatch
IOEventDispatch ioEventDispatch = new
DefaultHttpServerIODispatch(protocolHandler, connFactory);
// Create server-side I/O reactor
IOReactorConfig conf = new IOReactorConfig();
conf.setIoThreadCount(numOfWorkers);
ListeningIOReactor ioReactor = new DefaultListeningIOReactor(conf);
try {
// Listen of the given port
ioReactor.listen(new InetSocketAddress(port));
// Ready to go!
ioReactor.execute(ioEventDispatch);
} catch (InterruptedIOException ex) {
System.err.println("Interrupted");
} catch (IOException e) {
System.err.println("I/O error: " + e.getMessage());
}
System.out.println("Shutdown");
}
static class HttpFileHandler implements
HttpAsyncRequestHandler<HttpRequest> {
public HttpFileHandler() {
super();
}
@Override
public HttpAsyncRequestConsumer<HttpRequest> processRequest(
final HttpRequest request,
final HttpContext context) {
// Buffer request content in memory for simplicity
return new BasicAsyncRequestConsumer();
}
class testResProducer extends BasicAsyncResponseProducer {
public testResProducer(HttpResponse response) {
super(response);
}
@Override
public synchronized HttpResponse generateResponse() {
log.debug("generating response - producer" + this);
//return super.generateResponse();
HttpResponse res = super.generateResponse();
log.debug("generated response - producer" + this);
return res;
}
@Override
public void failed(Exception ex) {
log.error( "failed to send response- producer" + this, ex);
super.failed(ex);
}
}
@Override
public void handle(
final HttpRequest request,
final HttpAsyncExchange httpexchange,
final HttpContext context) throws HttpException,
IOException {
HttpResponse response = httpexchange.getResponse();
try {
String method = request.getRequestLine().getMethod();
if ( method.equals("POST")) {
new
POSTHandler().processRequest((HttpEntityEnclosingRequest)request,
response);
} else {
new GETHandler().processRequest(request, response);
}
}catch (Exception ex) {
log.error("failed to submit response", ex);
response.setStatusCode(500);
}
HttpAsyncResponseProducer producer = new
testResProducer(response);
log.debug("submiting responce with producer" + producer);
httpexchange.submitResponse(producer);
}
}
}
Re: PoolingClientConnectionManager how to close a selected
connection
Posted by Oleg Kalnichevski <ol...@apache.org>.
On Tue, 2012-12-18 at 09:24 +0000, Alex wrote:
> Hi,
> I'm using PoolingClientConnectionManager to obtain a HttpClient and after execute a HttpPost where I set 1 to max for the pool.
>
> Looking at connection state with netstat I see the connection status in ESTABLISHED (and this is the right behavoir that I expect) for all my test.
> How is possible to force PoolingClientConnectionManager to close a specifice connection and recreate a new one ?
> In my code I tried to use releaseConnection() but the status not change in the netstatlist and if I use httpClient.getConnectionManager().shutdown() (used previously to kill the connection but with not Pooled connection ) the PoolingClientConnectionManager became not working
>
>
> Thank you very much
You can use a custom keep alive strategy and set the keep-alive period
for persistent connections to some finite value in milliseconds.
Persistent connections will not be re-used once that period expires. You
can also use #closeExpiredConnections() of the connection manager to
pro-actively evict expired connections from the pool.
Hope this helps
Oleg
---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org
PoolingClientConnectionManager how to close a selected connection
Posted by Alex <ga...@yahoo.com>.
Hi,
I'm using PoolingClientConnectionManager to obtain a HttpClient and after execute a HttpPost where I set 1 to max for the pool.
Looking at connection state with netstat I see the connection status in ESTABLISHED (and this is the right behavoir that I expect) for all my test.
How is possible to force PoolingClientConnectionManager to close a specifice connection and recreate a new one ?
In my code I tried to use releaseConnection() but the status not change in the netstatlist and if I use httpClient.getConnectionManager().shutdown() (used previously to kill the connection but with not Pooled connection ) the PoolingClientConnectionManager became not working
Thank you very much
Re: Socket leak of Async HTTP server
Posted by Nir Dweck <ni...@vasco-de.com>.
Oleg,
Thanks for the response.
The code doesn't compile because i didn't add my logic classes. In any case
I think I found the problem and it has nothing to do with the HTTPCore. My
application is a GW to a system and someone "forgot" that he run a new
process that accidentally sometimes stuck the system which affected my GW,
he just "remembered' it this morning. I have a stand alone test which
worked fine all the time, which was the reason I was so puzzled by the
problem and asked the forum if anyone has run into such a problem.
Regards,
Nir
On Sun, Dec 16, 2012 at 6:01 PM, Oleg Kalnichevski <ol...@apache.org> wrote:
> On Sun, 2012-12-16 at 13:03 +0200, Nir Dweck wrote:
> > Hi,
> > I am new to HTTP Components. I wrote a short server which is based on the
> > Asynchronous HTTP Server example. I am using httpcore-4.2.2 and
> > httpcore-nio-4.2.2. I wrote a short test program that loads my server. I
> > see that after ~500,000 requests I get a socket leak of ~600 sockets. I
> got
> > 84 SocketTimeoutException during the test. After I got to a big number of
> > leak sockets the application stopped responding and I couldn't even
> connect
> > to it with remote debugger.
> > bellow is my test.
> > Regards,
> > Nir
>
> Nir
>
> Your code does not compile so I cannot test it. I know that HttpCore
> (both blocking and non-blocking) can easily handle millions of requests.
> There is an (non-scientific) HTTP micro-benchmark used by the project to
> test HttpCore's performance [1]. Based on it 1'000'000 request do not
> seem to pose any sort of issue.
>
> Feel free to tweak the micro-benchmark and see how it performs for you
>
> Oleg
>
> [1]
> http://svn.apache.org/repos/asf/httpcomponents/benchmark/httpcore/trunk/
>
> ---------------------------------------------------------------
> HttpCore (blocking I/O); version: 4.2.3
> ---------------------------------------------------------------
>
> Server Software: HttpCore-Test/1.1
> Server Hostname: localhost
> Server Port: 8989
>
> Document Path: http://localhost:8989/rnd?c=2048
> Document Length: 2048 bytes
>
> Concurrency Level: 10
> Time taken for tests: 9.889423 seconds
> Complete requests: 1000000
> Failed requests: 0
> Write errors: 0
> Kept alive: 1000000
> Total transferred: 2048000000 bytes
> Requests per second: 101,118.13 [#/sec] (mean)
> Time per request: 0.099 [ms] (mean)
> Time per request: 0.010 [ms] (mean, across all concurrent
> requests)
> Transfer rate: 207,089.94 [Kbytes/sec] received
> -1 kb/s sent
> 207,089.94 kb/s total
> ---------------------------------------------------------------
> ---------------------------------------------------------------
> HttpCore (NIO); version: 4.2.3
> ---------------------------------------------------------------
>
> Server Software: HttpCore-NIO-Test/1.1
> Server Hostname: localhost
> Server Port: 8989
>
> Document Path: http://localhost:8989/rnd?c=2048
> Document Length: 2048 bytes
>
> Concurrency Level: 10
> Time taken for tests: 20.235072 seconds
> Complete requests: 1000000
> Failed requests: 0
> Write errors: 0
> Kept alive: 1000000
> Total transferred: 2048000000 bytes
> Requests per second: 49,419.15 [#/sec] (mean)
> Time per request: 0.202 [ms] (mean)
> Time per request: 0.020 [ms] (mean, across all concurrent
> requests)
> Transfer rate: 101,210.41 [Kbytes/sec] received
> -1 kb/s sent
> 101,210.41 kb/s total
> ---------------------------------------------------------------
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
>
>
Re: Socket leak of Async HTTP server
Posted by Oleg Kalnichevski <ol...@apache.org>.
On Sun, 2012-12-16 at 13:03 +0200, Nir Dweck wrote:
> Hi,
> I am new to HTTP Components. I wrote a short server which is based on the
> Asynchronous HTTP Server example. I am using httpcore-4.2.2 and
> httpcore-nio-4.2.2. I wrote a short test program that loads my server. I
> see that after ~500,000 requests I get a socket leak of ~600 sockets. I got
> 84 SocketTimeoutException during the test. After I got to a big number of
> leak sockets the application stopped responding and I couldn't even connect
> to it with remote debugger.
> bellow is my test.
> Regards,
> Nir
Nir
Your code does not compile so I cannot test it. I know that HttpCore
(both blocking and non-blocking) can easily handle millions of requests.
There is an (non-scientific) HTTP micro-benchmark used by the project to
test HttpCore's performance [1]. Based on it 1'000'000 request do not
seem to pose any sort of issue.
Feel free to tweak the micro-benchmark and see how it performs for you
Oleg
[1]
http://svn.apache.org/repos/asf/httpcomponents/benchmark/httpcore/trunk/
---------------------------------------------------------------
HttpCore (blocking I/O); version: 4.2.3
---------------------------------------------------------------
Server Software: HttpCore-Test/1.1
Server Hostname: localhost
Server Port: 8989
Document Path: http://localhost:8989/rnd?c=2048
Document Length: 2048 bytes
Concurrency Level: 10
Time taken for tests: 9.889423 seconds
Complete requests: 1000000
Failed requests: 0
Write errors: 0
Kept alive: 1000000
Total transferred: 2048000000 bytes
Requests per second: 101,118.13 [#/sec] (mean)
Time per request: 0.099 [ms] (mean)
Time per request: 0.010 [ms] (mean, across all concurrent requests)
Transfer rate: 207,089.94 [Kbytes/sec] received
-1 kb/s sent
207,089.94 kb/s total
---------------------------------------------------------------
---------------------------------------------------------------
HttpCore (NIO); version: 4.2.3
---------------------------------------------------------------
Server Software: HttpCore-NIO-Test/1.1
Server Hostname: localhost
Server Port: 8989
Document Path: http://localhost:8989/rnd?c=2048
Document Length: 2048 bytes
Concurrency Level: 10
Time taken for tests: 20.235072 seconds
Complete requests: 1000000
Failed requests: 0
Write errors: 0
Kept alive: 1000000
Total transferred: 2048000000 bytes
Requests per second: 49,419.15 [#/sec] (mean)
Time per request: 0.202 [ms] (mean)
Time per request: 0.020 [ms] (mean, across all concurrent requests)
Transfer rate: 101,210.41 [Kbytes/sec] received
-1 kb/s sent
101,210.41 kb/s total
---------------------------------------------------------------
---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org