java.io.IOException: Unreasonable length = 1486176问题解决
环境:JDK版本:1.7.0_80zookeeper版本:3.4.8问题:2018-11-1318:33:23.598 [localhost-startStop-1-SendThread(mt-zookeeper-vip.100.idc:2181)] WARNorg.apache.zookeeper.ClientCnxSession closed, press ENTER to s...
环境:
JDK版本:1.7.0_80
Tomcat版本:8.0
zookeeper版本:3.4.8
问题:
2018-11-13 18:33:23.598 [localhost-startStop-1-SendThread(mt-zookeeper-vip.100.idc:2181)] WARN org.apache.zookeeper.ClientCnxSession closed, press ENTER to start, l to last session or q to exit.c./x.x.x.x:2181, unexpected error, closing socket connection and attempting reconnect
java.io.IOException: Unreasonable length = 1256440
at org.apache.jute.BinaryInputArchive.checkLength(BinaryInputArchive.java:127)
at org.apache.jute.BinaryInputArchive.readBuffer(BinaryInputArchive.java:92)
at org.apache.zookeeper.proto.GetDataResponse.deserialize(GetDataResponse.java:54)
at org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:839)
at org.apache.zookeeper.ClientCnxnSocketNIO.doIO(ClientCnxnSocketNIO.java:94)
at org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:366)
at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1141)
从上面报错信息来看,我们在BinaryInputArchive.java类中127行找到相应代码,并贴出相关代码如下:
static public final String UNREASONBLE_LENGTH= "Unreasonable length = ";
static public final int maxBuffer = Integer.getInteger("jute.maxbuffer", 0xfffff);
public byte[] readBuffer(String tag) throws IOException {
int len = readInt(tag);
if (len == -1) return null;
checkLength(len);
byte[] arr = new byte[len];
in.readFully(arr);
return arr;
}
// Since this is a rough sanity check, add some padding to maxBuffer to
// make up for extra fields, etc. (otherwise e.g. clients may be able to
// write buffers larger than we can read from disk!)
private void checkLength(int len) throws IOException {
if (len < 0 || len > maxBuffer + 1024) {
throw new IOException(UNREASONBLE_LENGTH + len); //这里是代码第127行
}
}
推测结论:
zookeeper服务器端默认读取数据节点大小为1.01M,当zookeeper客户端读取的节点大小超过该值时就会抛出异常信息:java.io.IOException: Unreasonable length = 1256440
注:一般情况下zookeeper服务端数据节点大小也是1M,此处由于之前碰到过节点超过1M时无法写入的问题,所以在zookeeper服务端提前设置了大小为3M。但是zookeeper客户端这边读取大小没有设置大小,所以才会出现客户端读取超大节点时抛出异常信息问题。
解决方案:
通过zookeeper源码可以看出,zookeeper会优先读取系统变量:jute.maxbuffer,当系统中没有设置该变量时,才会使用默认值大小来读取数据节点。所以,我们需要在系统变量中设置jute.maxbuffer变量值。具体设置方法如下:
在Tomcat bin目录中的catalina.sh文件中,添加JAVA_OPTS变量即:JAVA_OPTS="-Djute.maxbuffer=3145728",这里设置大小为3M
注:此处只是临时解决方案,目的是着重介绍整个解决过程(毕竟zookeeper数据信息过长,已经超出了zookeeper的使用场景。后期会考虑其他更优方案来代替)。
更多推荐
所有评论(0)