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: [email protected]
For additional commands, e-mail: [email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]