views:

624

answers:

1

I am looking to optimize a process that runs continually and makes frequent calls (> 1 per second on average) to an external API via a simple REST style HTTP post. One thing I've noticed is that currently, the HttpUrlConnection is created and closed for every API call, as per the following structure (non essential code and error handling removed for readability).

//every API call
try {
  URL url = new URL("..remote_site..");
  conn = (HttpURLConnection) url.openConnection();
  setupConnectionOptions(conn); //sets things like timeoout and usecaches false
  outputWriter = new OutputStreamWriter(new BufferedOutputStream(conn.getOutputStream()));
  //send request
} finally {
  conn.disconnect();
  outputWriter.close();
}

I don't have extensive experience dealing with the http protocol directly, but based on common sense / knowledge of sockets in general it seems that it would be much more efficient to only create the connection once and re-use it, and only reinitialize it on a problem, to avoid the connection negotiation each time, like this:

//on startup, or error
private void initializeConnection()
{
  URL url = new URL("..remote_site..");
  conn = (HttpURLConnection) url.openConnection();
  setupConnectionOptions(conn); //sets things like timeoout and usecaches false
}

//per request
try {
  outputWriter = new OutputStreamWriter(new BufferedOutputStream(conn.getOutputStream()));
  //send request
} catch (IOException) {
  try conn.disconnect();
  initializeConnection();
} finally {
  outputWriter.close();
}

//on graceful exit
conn.disconnect();

My questions are:

  • is this a reasonable optimization in general (will the speed increase be noticeable)?

Assuming yes:

  • should I reuse the output stream as well the connection?
  • is it reasonable to only reinitialize connection on error, or should I do it after a certain number of requests / time?
+2  A: 

Basically, yes, and it saves a lot of time --- setting up a socket takes significant effort, even worse with SSL. That's why "keepalive" was implemented back in the Old Days. That's a litle bit counter to the REST philosophy, but it's a performance optimization.

The one thing about it is that sockets are a limited resource; in a really heavy-use environment, you could end up with no sockets left for new connections. this is a Bad Thing.

Charlie Martin