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