java socket-多线程 压力测试

最大客户端套接字对象/链接数100

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…并发

----

最大链接数500

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

应用程序代码

github.com/diedai/java…

总结

以上的并发 虽然是并发 可是单个请求 时间很短 线程任务一下就执行完了 若是是长链接 高并发 这种状况是什么样?

相关文章
相关标签/搜索