dubbo序列化问题(二)hession2与kryo切换

阅读更多

dubbo提供了好几种序列化方式,一般我们都是用的是默认的hession2,而dubbox为我们增加了kryo和fst许了方式,主要体现在速度快,占用内存小,然后我们将序列化配置改为是用kryo:

  
 

 

但是是用一段时间后遇到了不少问题,其中最困扰人的是不兼容以前的版本,我们的需求变动频繁,并且迭代比较快,经常需要增加字段或者对类进行重构,这就导致dubbo反序列化时经常报如下错误:

 

 

ERROR] [2017-08-10 17:18:55] Tried 3 times of the providers [172.20.50.35:20980] (1/1) from the registry 172.18.50.29:2181 on the consumer 172.19.21.69 using the dubbo version 2.8.4a. Last error is: Failed to invoke remote method: getApptConfig, provider: dubbo://172.20.50.35:20980/com.appt.api.appointment.ApptService?anyhost=true&application=web&check=false&dubbo=server&environment=test&generic=false&interface=com.appt.api.appointment.ApptService&methods=changgeAppRecordDate,confirmDiagnosisByApptOrderCode,getWaitUserTreatmentConfirm,getApptMinAndMaxDayConfig,getApptRecordBySchedule,getApptConfig,getApptConfirmRecord,userTreatmentConfirm,clinicApptConfirm,getApptImageUrl,confirmRecordByApptOrderCode,getScheduleDaysByClinic,getApptOptLog,getTreatmentProve,uploadApptTreatmentProveImages,getConfig2IsNeedClinicConfirmAppt,getApptItem,getClinicApptCount,getApptPoolSummary,getWaitApptConfirm,getScheduleSetApptDetailByClinic,getApptRecord,getClinicApptRecord,getDoctorScheduleDays,getApptRecordByApptOrderCode,getApptScheduleByDept,getPerToCreateOrEdit,modifyAppt,getApptPoolDetail,getDocotrApptStatisByDay,getApptRecordsByType,getApptRecordWx,cancleRecordByApptOrderCode,getHealthProductByHealthProductId,getScheduleSetApptByClinic,clinicTreatmentConfirm,apptCancel,getDepartmentApptStatisByDay,apptSubmit,checkTreatmentNumByApptOrderCode,getScheduleList,deleteByApptOrderCode&organization=wanjia&owner=xujie510&pid=576&revision=2.0.0&serialization=kryo&side=consumer&timeout=30000×tamp=1502356382889, cause: java.io.IOException: com.esotericsoftware.kryo.KryoException: java.lang.ArrayIndexOutOfBoundsException: -2
Serialization trace:haveScheduleDoctorInfos (com.model.appt.vo.ApptConfigRsp)result (com.appt.domain.JsonResponse)
java.io.IOException: com.esotericsoftware.kryo.KryoException: java.lang.ArrayIndexOutOfBoundsException: -2
Serialization trace:
haveScheduleDoctorInfos (com.model.appt.vo.ApptConfigRsp)
result (com.appt.domain.JsonResponse)
at com.alibaba.dubbo.common.serialize.support.kryo.KryoObjectInput.readObject(KryoObjectInput.java:127)
at com.alibaba.dubbo.common.serialize.support.kryo.KryoObjectInput.readObject(KryoObjectInput.java:140)
at com.alibaba.dubbo.common.serialize.support.kryo.KryoObjectInput.readObject(KryoObjectInput.java:151)
at com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcResult.decode(DecodeableRpcResult.java:87)
at com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcResult.decode(DecodeableRpcResult.java:117)
at com.alibaba.dubbo.rpc.protocol.dubbo.DubboCodec.decodeBody(DubboCodec.java:98)
at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:134)
at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:95)
at com.alibaba.dubbo.rpc.protocol.dubbo.DubboCountCodec.decode(DubboCountCodec.java:46)
at com.alibaba.dubbo.remoting.transport.netty.NettyCodecAdapter$InternalDecoder.messageReceived(NettyCodecAdapter.java:134)
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:109)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:312)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:90)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
Caused by: com.esotericsoftware.kryo.KryoException: java.lang.ArrayIndexOutOfBoundsException: -2
Serialization trace:
haveScheduleDoctorInfos (com.model.appt.vo.ApptConfigRsp)
result (com.appt.domain.JsonResponse)
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125)
at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:528)
at com.esotericsoftwa
 

 

只要输入参数、输出参数或者嵌套类有任何变动,就报以上错误,很是困扰人。

 

后来针对该问题,又将配置改为了dubbo默认序列化配置,才解决版本兼容问题。所以针对频繁变动的输入输出时,一般建议采用dubbo默认配置,虽然kryo速度快,但是还不够成熟,这也是dubbo默认配置是hession2而不是kryo。

 

 还有一个值得注意的问题:输入输出参数最好都实现Serializable接口,因为hession2要求必须实现Serializable接口,而kryo不作要求,所以为了方便切换,最好都按要求实现序列化接口

你可能感兴趣的:(hession2,kryo,dubbo,序列化)