1、查看服務器網絡狀態TIME_WAIT的數量。
#netstat -antp|grep -i time_wait|wc -l查看TIME_WAIT數量,如果數量過多,并且Resin前端還有Nginx或者Apache,那么請把socket-timeout、keepalive-max和把keepalive-timeout調小
????? <socket-timeout>30s</socket-timeout>
????? <keepalive-max>512</keepalive-max>
????? <keepalive-timeout>60s</keepalive-timeout>
2、查看JVM中對象占用內存情況
jmap 能查看jvm內存中,對象占用內存的情況,還提供非常方便的命令將jvm的內存信息導出的文件。
#jmap -dump:format=b,file=heap.bin <pid>?
命令jhat 能夠解析 java內存堆的文件,生成相關信息,并啟動webServer提供查詢。 也就說,我們可以通過瀏覽器來看這些內存信息。jhat還提供了一個類sql的查詢語言---OQL來給我們使用。
#jhat -J-Xmx512m heap.bin????
就可以將我們剛剛使用jmap導出的內存信息交給jhat解析了。默認的情況下,它會監聽7000端口。我在本機的地址就是,http://localhost:7000/。
訪問http://localhost:7000/histo/,大致可以看到一下的畫面,這里列出對象,對象實例數量、總占用內存大小。點擊進去之后可以看到“誰引用了這個對象,這個對象又引用了哪個”這些信息。不過因為展示的信息非常多,并沒有想象中那樣清晰可見。
3、dump獲取java stack和native stack信息
消息隊列會突然堵塞,查看消費者日志,發現處理延時明顯延長,而此時網絡無丟包。最后多方排查,是java消費者運行出現死鎖。
這種問題可以通過jstack來dump獲取java stack和native stack信息查明問題。
#jstatck <pid>
重要的是TOMCAT這種容器竟然有這樣的BUG,不能正確讀取UTF-8格式的文件,你總不能強求用戶編輯JSP文件時一定要存為什么格式吧?
費話少說,下載tomcat5的src,進入jakarta-tomcat-jasper\jasper2\src\share\org\apache\jasper\compiler,找到JspUtil.java,找到
public static InputStream getInputStream(String fname, JarFile jarFile,
JspCompilationContext ctxt,
ErrorDispatcher err)
throws JasperException, IOException {
InputStream in = null;
if (jarFile != null) {
String jarEntryName = fname.substring(1, fname.length());
ZipEntry jarEntry = jarFile.getEntry(jarEntryName);
if (jarEntry == null) {
err.jspError("jsp.error.file.not.found", fname);
}
in = jarFile.getInputStream(jarEntry);
} else {
in = ctxt.getResourceAsStream(fname);
}
if (in == null) {
err.jspError("jsp.error.file.not.found", fname);
}
return in;
}
在return in前加上判斷,改成:
public static InputStream getInputStream(String fname, JarFile jarFile,
JspCompilationContext ctxt,
ErrorDispatcher err)
throws JasperException, IOException {
InputStream in = null;
if (jarFile != null) {
String jarEntryName = fname.substring(1, fname.length());
ZipEntry jarEntry = jarFile.getEntry(jarEntryName);
if (jarEntry == null) {
err.jspError("jsp.error.file.not.found", fname);
}
in = jarFile.getInputStream(jarEntry);
} else {
in = ctxt.getResourceAsStream(fname);
}
if (in == null) {
err.jspError("jsp.error.file.not.found", fname);
}
PushbackInputStream testin = new PushbackInputStream(in);
int ch = testin.read();
if (ch != 0xef) {
testin.unread(ch);
}
else if ((ch = testin.read()) != 0xbb) {
testin.unread(ch);
testin.unread(0xef);
}
else if ((ch = testin.read()) != 0xbf) {
throw new IOException("錯誤的UTF-8格式文件");
}
else{
//fStream.setEncoding("UTF-8");
testin.read();
}
return testin;
}
編譯,重新打包,替換原來的包,運行TOMCAT,OK!
整個問題解決除了遠程登錄他的服務器傳送文件的時間,總共只有4-5分鐘.其實只要問題定位準確,就不難解決了.我一再強調的是經熟悉底層,你如果知道內
存中每個byte從哪兒來要到哪兒去,就可以非常容易地解決問題.在此之前我連TOMCAT5下載都沒有下過,更別說試用了.但只要你對JDK有深入的了
解,就可以準確地定位問題的所在.
希望本文能給不是高手的朋友一點幫助和啟發,對于高手的朋友你可以棄之一笑.
As I got the email:
Just writing to inform you theis patch for 1.3 works with the 1.3 shipped with borland JBuilder 4 (not sure which excat version it is)
the only problems I had where that the code was a bit messed up, following are the changes made to it to make it work.
public void SetTimeout(int i)
throws SocketException
{
this.timeout = i; // Should be i not -1 <------------ERROR
serverSocket.setSoTimeout(i) ;
}
public boolean parseHTTP(MessageHeader header, ProgressEntry entry)
throws java.io.IOException
{
if( this.timeout != -1 ) {
try {
serverSocket.setSoTimeout(timeout) ; // should be timeout not i <---------------ERROR
} catch( SocketException e ) {
throw new java.io.IOException("unable to set socket timeout!") ;
}
}
return super.parseHTTP(header, entry) ;
}
Sam
Under JDK 1.3, which is HTTP 1.1 compatible, the InterruptedIOException gets caught by the socket I/O routines and ignored. input is read in "chunks". I debugged the existing code under 1.3, the Timeout is getting set properly etc., but the exception gets caught in the underlying I/O routines, which have a single retry if any IOExceptions are thrown. Thanks a lot Sun....
Patch code for JDK 1.3 from Matt Ho (unverified)
----[ snip ]----
import sun.net.www.MessageHeader ;
import sun.net.ProgressEntry ;
.
.
.
private int timeout = -1 ;
public void SetTimeout(int i)
throws SocketException
{
this.timeout = -1 ;
serverSocket.setSoTimeout(i) ;
}
public boolean parseHTTP(MessageHeader header, ProgressEntry entry)
throws java.io.IOException
{
if( this.timeout != -1 ) {
try {
serverSocket.setSoTimeout(i) ;
} catch( SocketException e ) {
throw new java.io.IOException("unable to set socket timeout!") ;
}
}
return super.parseHTTP(header, entry) ;
}
----[ snip ]----
The BSD socket API supports a timeout option (the option is SO_TIMEOUT), which is also supported in java.net.socket. Unfortunately, java.net.URLConnection does not expose the underlying socket. So if you have a URL connection that attempts to connect to a dead URL (i.e., the URL is well formed and exists but the site is down), the socket will eventually timeout using the operating system's default timeout (420 seconds on Win NT). The timeout is a very long time, e.g., for spiders or URL checking.
The following files illustrate a technique to introduce a socket timeout to URL connection, based upon the actual java source code itself (see the open source community licensing at JavaSoft).
Java's implementation of networking is protocol independent, as well as object oriented. Therefore the implementation is not as straightfoward as one might imagine.
URLConnection relies upon several internal classes using a client/server model as well as a "factory" design pattern. The client's base class is sun.net.www.http.HttpClient. This class is extended for the purpose of exposing the socket.
The default factory is URLStreamHandlerFactory, which indirectly "handles" the creation of an HTTP client by instantiating a class that is specific to the HTTP protocol: sun.net.www.protocol.http.Handler. The handler actually creates the client.
In practice, the factory is only necessary to mimic java's implementation, but only the Handler is really needed.
We derive 4 classes so as to preserve the symmetry with the java source code:
HttpURLConnectionTimeout extends sun.net.www.protocol.http.HttpURLConnectionOn with the source code.
// whatever package you want
import sun.net.www.http.HttpClient;
import java.net.*;
import java.io.*;
public class HttpClientTimeout extends HttpClient
{
public HttpClientTimeout(URL url, String proxy, int proxyPort) throws IOException
{
super(url, proxy, proxyPort);
}
public HttpClientTimeout(URL url) throws IOException
{
super(url, null, -1);
}
public void SetTimeout(int i) throws SocketException {
serverSocket.setSoTimeout(i);
}
/* This class has no public constructor for HTTP. This method is used to
* get an HttpClient to the specifed URL. If there's currently an
* active HttpClient to that server/port, you'll get that one.
*
* no longer syncrhonized -- it slows things down too much
* synchronize at a higher level
*/
public static HttpClientTimeout GetNew(URL url)
throws IOException {
/* see if one's already around */
HttpClientTimeout ret = (HttpClientTimeout) kac.get(url);
if (ret == null) {
ret = new HttpClientTimeout (url); // CTOR called openServer()
} else {
ret.url = url;
}
// don't know if we're keeping alive until we parse the headers
// for now, keepingAlive is false
return ret;
}
public void Close() throws IOException
{
serverSocket.close();
}
public Socket GetSocket()
{
return serverSocket;
}
}
import java.net.*;
public class HttpTimeoutFactory implements URLStreamHandlerFactory
{
int fiTimeoutVal;
public HttpTimeoutFactory(int iT) { fiTimeoutVal = iT; }
public URLStreamHandler createURLStreamHandler(String str)
{
return new HttpTimeoutHandler(fiTimeoutVal);
}
}
import java.net.*;
import java.io.IOException;
public class HttpTimeoutHandler extends sun.net.www.protocol.http.Handler
{
int fiTimeoutVal;
HttpURLConnectionTimeout fHUCT;
public HttpTimeoutHandler(int iT) { fiTimeoutVal = iT; }
protected java.net.URLConnection openConnection(URL u) throws IOException {
return fHUCT = new HttpURLConnectionTimeout(u, this, fiTimeoutVal);
}
String GetProxy() { return proxy; } // breaking encapsulation
int GetProxyPort() { return proxyPort; } // breaking encapsulation
public void Close() throws Exception
{
fHUCT.Close();
}
public Socket GetSocket()
{
return fHUCT.GetSocket();
}
}
import java.net.*;
import java.io.*;
import sun.net.www.http.HttpClient;
public class HttpURLConnectionTimeout extends sun.net.www.protocol.http.HttpURLConnection
{
int fiTimeoutVal;
HttpTimeoutHandler fHandler;
HttpClientTimeout fClient;
public HttpURLConnectionTimeout(URL u, HttpTimeoutHandler handler, int iTimeout) throws IOException
{
super(u, handler);
fiTimeoutVal = iTimeout;
}
public HttpURLConnectionTimeout(URL u, String host, int port) throws IOException
{
super(u, host, port);
}
public void connect() throws IOException {
if (connected) {
return;
}
try {
if ("http".equals(url.getProtocol()) /* && !failedOnce <- PRIVATE */ ) {
// for safety's sake, as reported by KLGroup
synchronized (url)
{
http = HttpClientTimeout.GetNew(url);
}
fClient = (HttpClientTimeout)http;
((HttpClientTimeout)http).SetTimeout(fiTimeoutVal);
} else {
// make sure to construct new connection if first
// attempt failed
http = new HttpClientTimeout(url, fHandler.GetProxy(), fHandler.GetProxyPort());
}
ps = (PrintStream)http.getOutputStream();
} catch (IOException e) {
throw e; }
// this was missing from the original version
connected = true;
}
/**
* Create a new HttpClient object, bypassing the cache of
* HTTP client objects/connections.
*
* @param url the URL being accessed
*/
protected HttpClient getNewClient (URL url)
throws IOException {
HttpClientTimeout client = new HttpClientTimeout (url, (String)null, -1);
try {
client.SetTimeout(fiTimeoutVal);
} catch (Exception e)
{ System.out.println("Unable to set timeout value"); }
return (HttpClient)client;
}
/**
* opens a stream allowing redirects only to the same host.
*/
public static InputStream openConnectionCheckRedirects(URLConnection c)
throws IOException
{
boolean redir;
int redirects = 0;
InputStream in = null;
do {
if (c instanceof HttpURLConnectionTimeout) {
((HttpURLConnectionTimeout) c).setInstanceFollowRedirects(false);
}
// We want to open the input stream before
// getting headers, because getHeaderField()
// et al swallow IOExceptions.
in = c.getInputStream();
redir = false;
if (c instanceof HttpURLConnectionTimeout) {
HttpURLConnectionTimeout http = (HttpURLConnectionTimeout) c;
int stat = http.getResponseCode();
if (stat >= 300 && stat <= 305 &&
stat != HttpURLConnection.HTTP_NOT_MODIFIED) {
URL base = http.getURL();
String loc = http.getHeaderField("Location");
URL target = null;
if (loc != null) {
target = new URL(base, loc);
}
http.disconnect();
if (target == null
|| !base.getProtocol().equals(target.getProtocol())
|| base.getPort() != target.getPort()
|| !HostsEquals(base, target)
|| redirects >= 5)
{
throw new SecurityException("illegal URL redirect");
}
redir = true;
c = target.openConnection();
redirects++;
}
}
} while (redir);
return in;
}
// Same as java.net.URL.hostsEqual
static boolean HostsEquals(URL u1, URL u2)
{
final String h1 = u1.getHost();
final String h2 = u2.getHost();
if (h1 == null) {
return h2 == null;
} else if (h2 == null) {
return false;
} else if (h1.equalsIgnoreCase(h2)) {
return true;
}
// Have to resolve addresses before comparing, otherwise
// names like tachyon and tachyon.eng would compare different
final boolean result[] = {false};
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
try {
InetAddress a1 = InetAddress.getByName(h1);
InetAddress a2 = InetAddress.getByName(h2);
result[0] = a1.equals(a2);
} catch(UnknownHostException e) {
} catch(SecurityException e) {
}
return null;
}
});
return result[0];
}
void Close() throws Exception
{
fClient.Close();
}
Socket GetSocket()
{
return fClient.GetSocket();
}
}
import java.net.*;
public class MainTest
{
public static void main(String args[])
{
int i = 0;
try {
URL theURL = new URL((URL)null, "http://www.snowball.com", new HttpTimeoutHandler(150)); // timeout value in milliseconds
// the next step is optional
theURL.setURLStreamHandlerFactory(new HttpTimeoutFactory(150));
URLConnection theURLconn = theURL.openConnection();
theURLconn.connect();
i = theURLconn.getContentLength();
}
catch (InterruptedIOException e)
{
System.out.println("timeout on socket");
}
System.out.println("Done, Length:" + i);
}
}
try
{
HttpTimeoutHandler xHTH = new HttpTimeoutHandler(10); // timeout value in milliseconds
URL theURL = new URL((URL)null, "http://www.javasoft.com", xHTH);
HttpURLConnection theUC = theURL.openConnection();
.
.
.
}
catch (InterruptedIOException e)
{
// socket timed out
}
Some remarks: this code is thread safe.
More to come
來源:http://www.logicamente.com/sockets.html
???? http://www.edevs.com/java-programming/15068/
Thanks Felipe!
If I understand information at http://www.logicamente.com/sockets.html correctly there are 2 problems with timeout when using HttpURLConnection in JDK 1.3:
1. HttpURLConnection does not allow changing the default timeout that is in order of few minutes.
2. If actual HTTP stream is chunked then HttpURLConnection ignores even the default timeout and tries to read what it perceives as a continued stream resulting in indefinite read wait.
The patch shown at the above URL, consisting of subclassing of 4 system classes (1 from java.net... and 3 from sun.net.www...), is aimed to resolve problem 1 above but does not help in problem 2.
My main problem is to have timeout when reading chunked stream (system default timeout will be ok to beginning with) and therefore the question is if this bug has been corrected in later versions of JDK? Thanks.
-----
I have seen much chat about this "problem", that is setSoTimeout not available or not working properly.
how about you write your own Timer (resettable) or 1.4 has Timer class
you just reset it anytime you detect network activity and close the Socket if the Timer finishes its cycle?
Date: 23 Jan 2004 09:14:16 -0800
After spending nearly 3 days on this problem to come up with a
solution I think it is only right to post the solution.
I found that you can't set the soTimeout on an HttpURLConnection
as
the sockets are encapsulated within the HttpURLConnection
implementation.
I found Mike Reiche solution in which he uses a handler to set a
timeout value. This nearly worked. Looking at the code in the rt.jar I
found that the initial timeout was working, but the call
parseHTTP(...) in HttpClient was then attempting a second connection
which had a time out value of 0(infinite).
I modified the code to override the doConnect() in the
NetworkClient
and managed to get a timeout occurring. To be exact two timeouts
occur.
It works on
java version "1.4.0_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_03-b04)
Java HotSpot(TM) Client VM (build 1.4.0_03-b04, mixed mode)
and
java version "1.2.2"
Classic VM (build JDK-1.2.2_013, native threads, symcjit)
Anyway here is the code, excuse the formatting.
/* HttpTimeoutURLConnection.java */
import java.net.*;
import java.io.*;
import sun.net.www.http.HttpClient;
// Need to override any function in HttpURLConnection that create
a
new HttpClient
// and create a HttpTimeoutClient instead. Those functions are
// connect(), getNewClient(), getProxiedClient()
public class HttpTimeoutURLConnection extends
sun.net.www.protocol.http.HttpURLConnection
{
????public HttpTimeoutURLConnection(URL u, HttpTimeoutHandler
handler,
int iSoTimeout)
????????throws IOException
????{
????????super(u, handler);
????????HttpTimeoutClient.setSoTimeout(iSoTimeout);
????}
????public void connect() throws IOException
????{
????????if (connected)
????????{
????????????return;
????????}
????????try
????????{
????????????if ("http".equals(url.getProtocol())) // &&
!failedOnce <-
PRIVATE
????????????{
????????????????// for safety's sake, as reported by KLGroup
????????????????synchronized (url)
????????????????{
????????????????????http = HttpTimeoutClient.getNew(url);
????????????????}
????????????}
????????????else
????????????{
????????????????if (handler instanceof HttpTimeoutHandler)
????????????????{
????????????????????http = new HttpTimeoutClient(super.url,
((HttpTimeoutHandler)handler).getProxy(),
((HttpTimeoutHandler)handler).getProxyPort());
????????????????}
????????????????else
????????????????{
????????????????????throw new IOException("HttpTimeoutHandler
expected");
????????????????}
????????????}
????????????ps = (PrintStream)http.getOutputStream();
????????}
????????catch (IOException e)
????????{
????????????throw e;
????????}
????????connected = true;
????}
????protected HttpClient getNewClient(URL url)
????????throws IOException
????{
????????HttpTimeoutClient httpTimeoutClient = new HttpTimeoutClient
(url, (String)null, -1);
????????return httpTimeoutClient;
????}
????protected HttpClient getProxiedClient(URL url, String
s, int i)
????????throws IOException
????{
????????HttpTimeoutClient httpTimeoutClient = new HttpTimeoutClient
(url, s, i);
????????return httpTimeoutClient;
????}
}
/* HttpTimeoutHandler.java */
import java.net.*;
import java.io.IOException;
public class HttpTimeoutHandler extends
sun.net.www.protocol.http.Handler
{
????private int iSoTimeout=0;
????public HttpTimeoutHandler(int iSoTimeout)
????{
????????// Divide the time out by two because two connection attempts
are made
????????// in HttpClient.parseHTTP()
????????if (iSoTimeout%2!=0)
????????{
????????????iSoTimeout++;
????????}
????????this.iSoTimeout = (iSoTimeout/2);
????}
????protected java.net.URLConnection openConnection(URL u) throws
IOException
????{
????????return new HttpTimeoutURLConnection(u, this, iSoTimeout);
????}
????protected String getProxy()
????{
????????return proxy;
????}
????protected int getProxyPort()
????{
????????return proxyPort;
????}
}
/* HttpTimeoutFactory.java */
import java.net.*;
public class HttpTimeoutFactory implements
URLStreamHandlerFactory
{
????private int iSoTimeout=0;
????public HttpTimeoutFactory(int iSoTimeout)
????{
????????this.iSoTimeout = iSoTimeout;
????}
????public URLStreamHandler createURLStreamHandler(String str)
????{
????????return new HttpTimeoutHandler(iSoTimeout);
????}
}
/* HttpTimeoutClient.java */
import sun.net.www.http.HttpClient;
import java.net.*;
import sun.net.*;
import sun.net.www.*;
import java.io.*;
public class HttpTimeoutClient extends HttpClient
{
????private static int iSoTimeout=0;
????public HttpTimeoutClient(URL url, String proxy, int
proxyPort)
throws IOException
????{
????????super(url, proxy, proxyPort);
????}
????public HttpTimeoutClient(URL url) throws IOException
????{
????????super(url, null, -1);
????}
????public static HttpTimeoutClient getNew(URL url)
????????throws IOException
????{
????????HttpTimeoutClient httpTimeoutClient = (HttpTimeoutClient)
kac.get(url);
????????if (httpTimeoutClient == null)
????????{
????????????httpTimeoutClient = new HttpTimeoutClient (url); // CTOR
called openServer()
????????}
????????else
????????{
????????????httpTimeoutClient.url = url;
????????}
????????return httpTimeoutClient;
????}
????public static void setSoTimeout(int iNewSoTimeout)
????{
????????iSoTimeout=iNewSoTimeout;
????}
????public static int getSoTimeout()
????{
????????return iSoTimeout;
????}
????// Override doConnect in NetworkClient
????protected Socket doConnect(String s, int i)
????????throws IOException, UnknownHostException, SocketException
????{
????????Socket socket=super.doConnect(s,i);
????????// This is the important bit
????????socket.setSoTimeout(iSoTimeout);
????????return socket;
????}
}
/* Example use */
import java.util.*;
import java.io.*;
import java.net.*;
public class SystemProperty
{
????public static void main(String[] args)
????{
????????String sSoapUrl="
????????System.out.println("Connecting to [" + sSoapUrl + "]");
????????URLConnection urlConnection = null;
????????URL url=null;
????????try
????????{
????????????url = new URL((URL)null, sSoapUrl, new
HttpTimeoutHandler(10000));
????????????urlConnection = url.openConnection();
????????????// Optional
????????????url.setURLStreamHandlerFactory(new
HttpTimeoutFactory(10000));
????????????System.out.println("Url class
["+urlConnection.getClass().getName()+"]");
????????}
????????catch (MalformedURLException mue)
????????{
????????????System.out.println(">>MalformedURLException<<");
????????????mue.printStackTrace();
????????}
????????catch (IOException ioe)
????????{
????????????System.out.println(">>IOException<<");
????????????ioe.printStackTrace();
????????}
????????HttpURLConnection httpConnection =
(HttpURLConnection)urlConnection;
????????System.out.println("Connected to [" + sSoapUrl + "]");
????????byte[] messageBytes=new byte[10000];
????????for (int i=0; i<10000; i++)
????????{
????????????messageBytes[i]=80;
????????}
????????try
????????{
????????????httpConnection.setRequestProperty("Connection", "Close");
????????????httpConnection.setRequestProperty("Content-Length",
String.valueOf(messageBytes.length));
????????????httpConnection.setRequestProperty("Content-Type",
"text/xml; charset=utf-8");
????????????httpConnection.setRequestMethod("POST");
????????????httpConnection.setDoOutput(true);
????????????httpConnection.setDoInput(true);
????????}
????????catch (ProtocolException pe)
????????{
????????????System.out.println(">>ProtocolException<<");
????????????pe.printStackTrace();
????????}
????????OutputStream outputStream=null;
????????try
????????{
????????????System.out.println("Getting output stream");
????????????outputStream =httpConnection.getOutputStream();
????????????System.out.println("Got output stream");
????????????outputStream.write(messageBytes);
????????}
????????catch (IOException ioe)
????????{
????????????System.out.println(">>IOException<<");
????????????ioe.printStackTrace();
????????}
????????try
????????{
????????????System.out.println("Getting input stream");
????????????InputStream is=httpConnection.getInputStream();
????????????System.out.println("Got input stream");
????????????byte[] buf = new byte[1000];
????????????int i;
????????????while((i = is.read(buf)) > 0)
????????????{
????????????????System.out.println(""+new String(buf));
????????????}
????????????is.close();
????????}
????????catch (Exception ie)
????????{
????????????ie.printStackTrace();
????????}
????}
}
查了下TOMCAT的文檔,解釋如下:
Wrap an IOException identifying it as being caused by an abort of a request by a remote client.
在BAIDU和GOOGLE上找了下原因,大概歸結為:
ClientAbortException: java.net.SocketException: Connection reset by peer: socket write error的原因是由于處理http連接時,正在輸出內容時,用戶關閉了IE,會出現一個"ClientAbortException",屬于I/O處理中出現的一個異常,應用服務器應該會捕捉。
Connection reset by peer的原因:
經常出現的Connection reset by peer: 原因可能是多方面的,不過更常見的原因是:
①:服務器的并發連接數超過了其承載量,服務器會將其中一些連接Down掉;
②:客戶關掉了瀏覽器,而服務器還在給客戶端發送數據;
③:瀏覽器端按了Stop
很多人都說是客戶端造成的,沒有辦法控制,是個比較郁悶的問題。
但是,我擔心的是:雖然前臺沒有任何出錯的跡象,但是后臺會記錄這個異常,日志也會瘋狂爆滿,時間長了,肯定會DOWN掉的,還沒找到好的解決辦法
resin有一個參數ignore-client-disconnect
tomcat似乎沒有
經常出現的Connection reset by peer: 原因可能是多方面的,不過更常見的原因是:①:服務器的并發連接數超過了其承載量,服務器會將其中一些連接Down掉;②:客戶關掉了瀏覽器,而服務器還 在給客戶端發送數據;③:瀏覽器端按了Stop
[10054] Connection reset by peer
Connection reset by peer is a
tough one because it can be caused by so many things. In all cases, the
server determines that the socket is no longer good and closes it from
its side.
Read Error
Scenario: Mary couldn't make out what Joe
was saying anymore, so she hung up rather than lose his messages
(data).
A read error occurs when a server cannot successfully read
from a user's client. Servers gather information from the client by
text, setup, and other items.When the server receives an error when
reading from a client, it then disconnects the user, resulting in a read
error quit message.
Write Error
Scenario: Mary was trying to
talk to Joe but didn't think she was getting through, so she hung
rather than lose his messages (data).
A write error occurs when a
server cannot successfully write to a user's client. When the server
receives information, it usually responds with information of its own.
When the server receives an error when writing to a client, it then
disconnects the user, resulting in a write error quit message similar to
the read error format.
Ping Timeout Error
Scenario: Mary,
having been raised in a household with too many kids and always craving
attention, keeps asking to make sure that Joe is still on the line and
listening. If he doesn't reply fast enough to suit her, she hangs up.
Servers automatically ping users at a preset time. The reason for this
is to ensure the client is still connected to the server. When you see
"PING? PONG!" results in your status window, it means the server has
pinged your client, and it has responded back with a pong to ensure the
server that you are still connected. When this does not happen and you
disconnect without the server's knowledge, the server will automatically
disconnect the user when it does not receive a response, resulting in a
ping timeout. Ping timeouts occur to EVERYONE.
Broken pipe Error
Scenario: Mary had picked up a sticky note with a message she needed to
relay to Joe, but somehow between her hand and her mouth, the message
got misplaced. Mary was trying to talk to Joe but didn't think she was
getting through, so she hung up rather than lose his messages (data).
A broken pipe error occurs when the server knows it has a message but
can't seem to use its internal data link to get the data out to the
socket.
Miscellaneous
Scenario: Lots of other reasons;
perhaps the operator broke in and gave Mary a message that made her
doubt the validity of the call so she hung up