问题记录,最近遇到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几个方法的总结