更新时间:2022-09-13 17:43:31
Cobar在测试的时候看到日志里会报很多如下的错误:
java.nio.channels.AsynchronousCloseException
atjava.nio.channels.spi.AbstractInterruptibleChannel.end
at sun.nio.ch.SocketChannelImpl.read
atcom.alibaba.cobar.net.AbstractConnection.read
at com.alibaba.cobar.net.NIOReactor$R.read
at com.alibaba.cobar.net.NIOReactor$R.run
at java.lang.Thread.run(Thread.java:722)
看一眼代码很容易看出WARNING的原因:Cobar的IO模型是reactor式的,采用Java的NIO
首先是Reader线程
Object att = key.attachment();
if (att != null&& key.isValid()) {
int readyOps = key.readyOps();
if((readyOps & SelectionKey.OP_READ) != 0) {
read((NIOConnection) att);
} elseif((readyOps & SelectionKey.OP_WRITE) != 0) {
write((NIOConnection) att);
} else{
key.cancel();
}
} else {
key.cancel();
}
再看后端Channel的close:
private void mysqlClose() {
try {
if (out != null){
out.write(QuitPacket.QUIT);
out.flush();
}
} catch (IOException e) {
LOGGER.error(toString(), e);
} finally {
try {
socket.close();
} catch (Throwable e) {
LOGGER.error(toString(), e);
}
}
}
Reader线程在从Socket读取的时候不是同步的,因此后端Channel关闭的时候Reader可能正在读取,换句话说,Reader会有一定概率从一个已经关闭的socket读取数据,因此报出这个异常,不过并不会影响实际业务,因为这个数据并不会被处理到;并且在Reader加同步会严重影响到系统的吞吐量,因此这个WARNING是可以忽略的.