100個線程 100個客戶端套接字對象(鏈接的是同一個服務器ip/port) 同時 併發 報錯java
併發=多線程+安全git
//客戶端報錯github
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
at java.io.BufferedWriter.flush(BufferedWriter.java:254) //刷數據時 報錯
at serverMaxConnMultiThread.Task1.run(Task1.java:32)
at java.lang.Thread.run(Thread.java:745)
複製代碼
class SocketOutputStream extends FileOutputStream
{
private void socketWrite(byte b[], int off, int len) throws IOException {
if (len <= 0 || off < 0 || off + len > b.length) {
if (len == 0) {
return;
}
throw new ArrayIndexOutOfBoundsException();
}
Object traceContext = IoTrace.socketWriteBegin();
int bytesWritten = 0;
FileDescriptor fd = impl.acquireFD();
try {
socketWrite0(fd, b, off, len); //發生異常 不是第一次發生異常 而是高併發時發生
bytesWritten = len;
} catch (SocketException se) {
if (se instanceof sun.net.ConnectionResetException) {
impl.setConnectionResetPending();
se = new SocketException("Connection reset");
}
if (impl.isClosedOrPending()) {
throw new SocketException("Socket closed");
} else { //捕獲異常
throw se;
}
} finally {
impl.releaseFD();
IoTrace.socketWriteEnd(traceContext, impl.address, impl.port, bytesWritten);
}
}
複製代碼
1.客戶端套接字關閉 2.服務器仍然在往客戶端套接字寫數據 由於高併發的時候 有的線程有延遲 由於輪詢 因此有的線程慢一點 有的線程快一點web
These broke pipe exceptions happen when the client (browser) has closed the connection, but the server (your tag) continues to try to write to the stream.安全
This usually happens when someone clicks Back, Stop, etc. in the browser and it disconnects from the server before the request is finished. Sometimes, it can happen because, for example, the Content-Length header is incorrect (and the browser takes its value as true).bash
Usually, this is a non-event, and nothing to worry about. But if you are seeing them in your dev environment when you know you have not interrupted your browser, you might dig a bit more to find out why.服務器
WLS server will try to filter these exceptions from the web container out of the log, since it is due to client (browser) action and we can't do anything about it. But the server doesn't catch all of them.多線程
community.oracle.com/thread/8068…併發
Broken pipe 和 Connection reset 異常都有 1.前面100個會出現 Broken pipe 2.後面開始出現 Connection resetoracle
//報錯信息
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:196)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:154)
at java.io.BufferedReader.readLine(BufferedReader.java:317)
at java.io.BufferedReader.readLine(BufferedReader.java:382) //讀數據報錯
at serverMaxConnMultiThread.Task1.run(Task1.java:41)
at java.lang.Thread.run(Thread.java:745)
複製代碼
class SocketInputStream extends FileInputStream
{
int read(byte b[], int off, int length, int timeout) throws IOException {
int n = 0;
// EOF already encountered
if (eof) {
return -1;
}
// connection reset
if (impl.isConnectionReset()) {
throw new SocketException("Connection reset");
}
// bounds check
if (length <= 0 || off < 0 || off + length > b.length) {
if (length == 0) {
return 0;
}
throw new ArrayIndexOutOfBoundsException();
}
boolean gotReset = false;
Object traceContext = IoTrace.socketReadBegin();
// acquire file descriptor and do the read
FileDescriptor fd = impl.acquireFD();
try {
n = socketRead0(fd, b, off, length, timeout);
if (n > 0) {
return n;
}
} catch (ConnectionResetException rstExc) {
gotReset = true;
} finally {
impl.releaseFD();
IoTrace.socketReadEnd(traceContext, impl.address, impl.port,
timeout, n > 0 ? n : 0);
}
/*
* We receive a "connection reset" but there may be bytes still
* buffered on the socket
*/
if (gotReset) {
traceContext = IoTrace.socketReadBegin();
impl.setConnectionResetPending();
impl.acquireFD();
try {
n = socketRead0(fd, b, off, length, timeout);
if (n > 0) {
return n;
}
} catch (ConnectionResetException rstExc) {
} finally {
impl.releaseFD();
IoTrace.socketReadEnd(traceContext, impl.address, impl.port,
timeout, n > 0 ? n : 0);
}
}
/*
* If we get here we are at EOF, the socket has been closed,
* or the connection has been reset.
*/
if (impl.isClosedOrPending()) {
throw new SocketException("Socket closed");
}
if (impl.isConnectionResetPending()) {
impl.setConnectionReset();
}
if (impl.isConnectionReset()) { //若是重置 拋出異常
throw new SocketException("Connection reset"); //捕獲異常
}
eof = true;
return -1;
}
複製代碼
my.oschina.net/xionghui/bl… 從日誌中能夠看到是Socket套接字在read數據時拋出了該錯誤。
致使「Connection reset」的緣由是服務器端由於某種緣由關閉了Connection(客戶端高併發請求),而客戶端依然在讀寫數據(讀的時候報錯),此時服務器會返回復位標誌「RST」(服務器端返回給客戶端一個reset標誌),而後此時客戶端就會提示「java.net.SocketException: Connection reset」。
首先,這是客戶端套接字發生了重置,由於服務端套接字重置報錯其餘信息java.net.SocketException reset by peer。
This error happens on your side and NOT the other side. If the other side reset the connection, then the exception message should say:
java.net.SocketException reset by peer The cause is the connection inside HttpClient is stale. Check stale connection for SSL does not fix this error. Solution: dump your client and recreate.
stackoverflow.com/questions/5…
緣由確定是由於高併發的緣由 客戶端套接字對象請求太多 服務器處理不過來
file:///var/folders/m9/yshd99dx1g38gtyxvv3k201r0000gn/T/WizNote/4f6d438b-8137-4773-ba2f-8ff0c31889c5/index_files/a452d037-ce33-4766-a590-0f83a403b490.png
以上的併發 雖然是併發 可是單個請求 時間很短 線程任務一下就執行完了 若是是長鏈接 高併發 這種狀況是什麼樣?