Connection reset by peer

问题记录,最近遇到Connection reset by peer 这个错误,错误日志记录如下:

13-09-11 11:57:04 [ERROR] com.duitang.dboss.remote.nio.DbossServerHandler  - dboss hander exceptionCaught,RemoteAddress=/192.168.172.8:54763
java.io.IOException: Connection reset by peer
	at sun.nio.ch.FileDispatcher.read0(Native Method)
	at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:21)
	at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:198)
	at sun.nio.ch.IOUtil.read(IOUtil.java:171)
	at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:243)
	at org.jboss.netty.buffer.HeapChannelBuffer.setBytes(HeapChannelBuffer.java:156)
	at org.jboss.netty.buffer.AbstractChannelBuffer.writeBytes(AbstractChannelBuffer.java:425)
	at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:305)
	at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:275)
	at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:196)
	at org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)

 原因:

服务器读取数据的时候,客户端主动关闭了socket。

解决办法:

主要需要定位是客户端为何主动关闭。最终通过debug发现原因在于GenericObjectPool的addObjectToPool():

private void addObjectToPool(Object obj, boolean decrementNumActive) throws Exception {
        boolean success = true;
        if(_testOnReturn && !(_factory.validateObject(obj))) {
            success = false;
        } else {
            _factory.passivateObject(obj);
        }

        boolean shouldDestroy = !success;

        // Add instance to pool if there is room and it has passed validation
        // (if testOnreturn is set)
        synchronized (this) {
            if (isClosed()) {
                shouldDestroy = true;
            } else {
                if((_maxIdle >= 0) && (_pool.size() >= _maxIdle)) {
                    shouldDestroy = true;
                } else if(success) {
                    // borrowObject always takes the first element from the queue,
                    // so for LIFO, push on top, FIFO add to end
                    if (_lifo) {
                        _pool.addFirst(new ObjectTimestampPair(obj));
                    } else {
                        _pool.addLast(new ObjectTimestampPair(obj));
                    }
                    if (decrementNumActive) {
                        _numActive--;
                    }
                    allocate();
                }
            }
        }

        // Destroy the instance if necessary
        if(shouldDestroy) {
            try {
                _factory.destroyObject(obj);
            } catch(Exception e) {
                // ignored
            }
            // Decrement active count *after* destroy if applicable
            if (decrementNumActive) {
                synchronized(this) {
                    _numActive--;
                    allocate();
                }
            }
        }

    }

 第17行:

if((_maxIdle >= 0) && (_pool.size() >= _maxIdle)) {  
    shouldDestroy = true;

默认 maxIdle 是8,如果NumIdle即pool.size()大于8就需要销毁对象。

通过修改maxIdle即可搞定此问题。

针对apache pool写了一个总结: PoolableObjectFactory几个方法的总结 编辑

 

 

猜你喜欢

转载自san-yun.iteye.com/blog/1940708