From: Christopher Schultz Reply-To: Tomcat Users List Date: Thursday 11 June 2015 09:12 To: Tomcat Users List Subject: Re: TCP connections reuse
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Maxim, On 6/10/15 4:12 AM, Maxim Neshcheret wrote: I have java http client which sends periodically (every 30 sec; this code is run by heartbeat thread in the cycle) heartbeats *private* PostResponse post(String jSessionCookie, *final* String action, *final* String data, *final* *int* postTimeoutMs) *throws* IOException, SSYSException { *final* HttpURLConnection httpConn = openHttpUrlConnection(*true*, postTimeoutMs, jSessionCookie); What does openHttpUrlConnection do? This method simply gets new instance of HttpURLConnection protected HttpURLConnection openHttpUrlConnection(final boolean isPost, final int timeout, final String jSession) throws IOException { final HttpURLConnection httpConn; final String method; httpConn = (HttpURLConnection) url.openConnection(); if (isPost) { method = "POST"; httpConn.setReadTimeout(timeout); } else { method = "GET"; httpConn.setRequestProperty( "Connection", "Keep-Alive"); } httpConn.setDoOutput(true); httpConn.setRequestMethod(method); httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + DefaultProperty.httpEncoding); if (jSession != null) { httpConn.addRequestProperty("Cookie", jSession); log.trace("JSession for " + method + " '" + jSession + "'"); } return httpConn; } *final* OutputStream os = httpConn.getOutputStream(); *try* (*final* PrintWriter wr = *new* PrintWriter( DefaultProperty./isEnableSocketTraceGW/ ? *new* TracerOutputStream(os) : os )) { *final* String text = "action=" + action + "&data=" + URLEncoder./encode/(data, DefaultProperty./httpEncoding/); You should encode the "action" String, too. Yes, you are right. Thanks for notice wr.write(text); wr.flush(); *final* *int* respCode = httpConn.getResponseCode(); *if* (respCode != HttpURLConnection.*/HTTP_OK/*) { String info = "Incorrect response from server, responseCode:" + respCode + ", message:" + httpConn.getResponseMessage(); */log/*.error(info); *throw* *new* SSYSException(SSYSCoreEx.*/ERR_UNKNOWN_ERROR/*, info); } } *if* (jSessionCookie == *null*) { jSessionCookie = getJSessionCookie(httpConn); } *final* InputStream inputStream = httpConn.getInputStream(); *try* (*final* BufferedReader reader = *new* BufferedReader(*new* InputStreamReader( (DefaultProperty./isEnableSocketTraceGW/ ? *new* TracerInputStream(inputStream) : inputStream ) , DefaultProperty./httpEncoding/))) You probably want to use the *actual* encoding of the response. Yes, but on server side I have same property for response and both are initialized with UTF-8 value. So should not be a problem here { */log/*.trace("before readline(post)"); String replyText = reader.readLine(); */log/*.trace("after readline(post): [" + replyText + "]"); NReply nReply = PoolGson./fromJson/(replyText, NReply.*class*); *if* (nReply == *null*) { *final* String msg = "corrupted reply, action:" + action; */log/*.debug(msg); *throw* *new* IOException(msg); } *return* *new* PostResponse(replyText, nReply, jSessionCookie, nReply.id); } } On the server side there is Tomcat 8.0.21 + APR connector. Every time this heartbeat is sent I see in the Wireshark and EtherDetect that new TCP connection is opened (SYN-SYNACK packets) and after getting response from Tomcat connection is closed (FIN – FINACK packets). I was expecting that TCP connections will be reused but not closed. Are you sending a "Connection" header to the server? Is it problem in my client or it can be solved by Java and/or Tocmat configuration? That depends. IIRC, HttpURLConnection used to use KeepAlive *by default* but that turned out to be a surprise to a lot of people and caused resource issues. I'm not sure if Sun/Oracle changed their minds about that and changed the default to be "Connection: close". According to http://docs.oracle.com/javase/6/docs/technotes/guides/net/http-keepalive.html connections in HTTP 1.1 are persistent by default. But if it is incorrect behavior in Java then maybe there is some way or configuration in Tomcat to put Keep-alive parameter in the response header? I notice that you are *not* calling HttpURLConnection.disconnect(), which is probably the correct decision given what you'd like to do. I'd confirm that "Connection: keep-alive" is being used with your connection, just in case. I do call HttpURLConnection.disconnect() only when client is stopped. Keep-alive is used for sure. - -chris -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIcBAEBCAAGBQJVeO58AAoJEBzwKT+lPKRYWusP/0FnuVVOj8NCYvy84+ckpStZ saV8srYNmlZiL9YLaMTEAEifPRndCFjWbBIjbAVAS2pFB25gxvkGl4WJTrz6KdkU u89kVUtOjqwJ6aaNDuUmOuyv52wq5NyGWDcsmVX5WgaWCOxmRZK3TlVGWikjn0J+ W7Ta86nI3qtYeY9yq7S3BwR7wUmzHXDvWK9Z3eeh3v9W0PgmoUg8TMbBKH/3HhWs GRBUYeotXjXpNqygaY0LOllTWSSQO/YLReStK4jcKzlOyGNoZrNpigbTJBberjg8 EltuquoyWlRRlL8BMglLVSfpX0NVJrToDEsDURiHQl614Fj7ZgBlmZgSVSQIdd50 vDdAZSFlzyAqnnYCa6f7vX2BMcV6nHRwoFsSWOz7oRy4ImkVttHoR84ZKzgylF5m xmMKg8J/xcbBk+eZLOedYnOKElnIBtu66Lj8Rq+B1UT6T45pcN7ypbVYbzGTjWrM Pq2+m9Jz5Ch/dsnjraW5ewbD3/N40LIBs8s8tUd4on2e2eK8OFuPGNbDm8gnd2hq N0qOH33y+BjKt2XGneUesuB/0lrySBs6FcuBG+M5afyfkkgb+QV9UONRJwKSP0ad jI4zJPQTkHjXefJjf5KvpPSAQJoPIzO6oCtExt9ijd/cE9uhLMGbmrHaswj8TcUM NIxez4dHmc6cEgDIodAZ =baJj -----END PGP SIGNATURE----- --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
--------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org