Closed
Description
前提:
我们自定义了序列化方式,serialization.getContentTypeId() == 88
超出计算的最大值。
按照ExchangeCodec的逻辑,这个值最大允许32。
88在服务端经过计算,变成24,无法获取到序列化方式。
在2.6.0版本时,获取序列化方式,采用兼容处理
CodecSupport.java代码如下:
public static Serialization getSerialization(URL url) {
return ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(
url.getParameter(Constants.SERIALIZATION_KEY, Constants.DEFAULT_REMOTING_SERIALIZATION));
}
public static Serialization getSerialization(URL url, Byte id) {
Serialization result = getSerializationById(id);
if (result == null) {
result = getSerialization(url);
}
return result;
}
上述代码会从SPI接口,根据url获取的参数,进一步获取。
在2.6.2版本时,获取序列化方式更改,根据id获取不到则抛出异常
public static Serialization getSerialization(URL url, Byte id) throws IOException {
Serialization serialization = getSerializationById(id);
String serializationName = url.getParameter(Constants.SERIALIZATION_KEY, Constants.DEFAULT_REMOTING_SERIALIZATION);
// Check if "serialization id" passed from network matches the id on this side(only take effect for JDK serialization), for security purpose.
if (serialization == null
|| ((id == 3 || id == 7 || id == 4) && !(serializationName.equals(ID_SERIALIZATIONNAME_MAP.get(id))))) {
throw new IOException("Unexpected serialization id:" + id + " received from network, please check if the peer send the right id.");
}
return serialization;
}
异常抛出后,没有做处理,导致的服务端hang住不返回,需要等待超时报错。代码在如下位置:
com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.decode(Channel, ChannelBuffer, int, byte[]) Line:124
try {
return decodeBody(channel, is, header);
} finally {
if (is.available() > 0) {
try {
if (logger.isWarnEnabled()) {
logger.warn("Skip input stream " + is.available());
}
StreamUtils.skipUnusedStream(is);
} catch (IOException e) {
logger.warn(e.getMessage(), e);
}
}
}
}
protected Object decodeBody(Channel channel, InputStream is, byte[] header) throws IOException {
byte flag = header[2], proto = (byte) (flag & SERIALIZATION_MASK);
Serialization s = CodecSupport.getSerialization(channel.getUrl(), proto);
ObjectInput in = s.deserialize(channel.getUrl(), is);
Line:141 抛出异常.
Line:124 不做处理。
导致服务不返回。