代码之家  ›  专栏  ›  技术社区  ›  user8690484

Hazelcast with global serializer(Kryo)—没有适合类型的反序列化程序

  •  1
  • user8690484  · 技术社区  · 6 年前

    Im使用Hazelcast 3.9对用户会话进行集群。

    为了序列化会话对象,我创建了一个用Kryo实现的全局序列化程序(或者更准确地说是KryoReflectionFactorySupport,它允许在没有默认构造函数的情况下序列化对象)。

    public class GlobalKryoSerializer implements StreamSerializer<Object> {
        //use ThreadLocal because Kryo is not thread safe
        private static final InheritableThreadLocal <Kryo> kryoThreadLocal = new InheritableThreadLocal <Kryo>() {
            @Override
            protected Kryo initialValue() {
               Kryo kryo = new KryoReflectionFactorySupport();
               //Kryo uses its own class loader       
               kryo.setClassLoader(java.lang.Thread.currentThread().getContextClassLoader());
               return kryo;
            }
        };
    
        public GlobalKryoSerializer(){    }
    
        public int getTypeId() {
            return 123;
        }
    
        public void destroy() {    }
    
        public void write(ObjectDataOutput objectDataOutput, Object object) throws IOException {
            Output output = new Output((OutputStream) objectDataOutput);
            Kryo kryo = kryoThreadLocal.get();
            kryo.writeClassAndObject(output, object);
            output.flush();
        }
    
        public Object read(ObjectDataInput objectDataInput) throws IOException {
            InputStream in = (InputStream) objectDataInput;
            Input input = new Input(in);
            Kryo kryo = kryoThreadLocal.get();
            Object retVal = kryo.readClassAndObject(input);
            return retVal;
        }
    }
    

    哈泽尔卡斯特。xml类似于 https://github.com/hazelcast/hazelcast/blob/master/hazelcast/src/main/resources/hazelcast-default.xml 使用全局序列化程序配置:

    <serialization>
          <portable-version>0</portable-version>
          <serializers>
               <global-serializer override-java-serialization="true"> GlobalKryoSerializer</global-serializer>       
          </serializers>
    </serialization>
    

    会话无效时,Hazelcast无法反序列化,出现以下错误(类型编号不时变化):

    com.hazelcast.nio.serialization.HazelcastSerializationException: There is no suitable de-serializer for type 16843028. This exception is likely to be caused by differences in the serialization configuration betw
    een members or between clients and members.
            at com.hazelcast.internal.serialization.impl.AbstractSerializationService.newHazelcastSerializationException(AbstractSerializationService.java:236) ~[hazelcast-all-3.9.jar:3.9]
            at com.hazelcast.internal.serialization.impl.AbstractSerializationService.readObject(AbstractSerializationService.java:263) ~[hazelcast-all-3.9.jar:3.9]
            at com.hazelcast.internal.serialization.impl.ByteArrayObjectDataInput.readObject(ByteArrayObjectDataInput.java:570) ~[hazelcast-all-3.9.jar:3.9]
            at com.hazelcast.session.HazelcastSession.deserializeMap(HazelcastSession.java:141) ~[hazelcast-tomcat7-sessionmanager-1.1.2.jar:na]
            at com.hazelcast.session.HazelcastSession.readData(HazelcastSession.java:127) ~[hazelcast-tomcat7-sessionmanager-1.1.2.jar:na]
            at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.readInternal(DataSerializableSerializer.java:158) ~[hazelcast-all-3.9.jar:3.9]
            at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.read(DataSerializableSerializer.java:105) ~[hazelcast-all-3.9.jar:3.9]
            at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.read(DataSerializableSerializer.java:50) ~[hazelcast-all-3.9.jar:3.9]
            at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:48) ~[hazelcast-all-3.9.jar:3.9]
            at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toObject(AbstractSerializationService.java:185) ~[hazelcast-all-3.9.jar:3.9]
            at com.hazelcast.map.impl.proxy.MapProxySupport.toObject(MapProxySupport.java:1149) ~[hazelcast-all-3.9.jar:3.9]
            at com.hazelcast.map.impl.proxy.MapProxyImpl.remove(MapProxyImpl.java:212) ~[hazelcast-all-3.9.jar:3.9]
            at com.hazelcast.session.HazelcastSessionManager.remove(HazelcastSessionManager.java:328) ~[hazelcast-tomcat7-sessionmanager-1.1.2.jar:na]
            at com.hazelcast.session.HazelcastSessionManager.remove(HazelcastSessionManager.java:294) ~[hazelcast-tomcat7-sessionmanager-1.1.2.jar:na]
            at org.apache.catalina.session.StandardSession.expire(StandardSession.java:833) ~[catalina.jar:7.0.82]
            at org.apache.catalina.session.StandardSession.expire(StandardSession.java:732) ~[catalina.jar:7.0.82]
            at org.apache.catalina.session.StandardSession.invalidate(StandardSession.java:1264) ~[catalina.jar:7.0.82]
            at org.apache.catalina.session.StandardSessionFacade.invalidate(StandardSessionFacade.java:183) ~[catalina.jar:7.0.82]
            at org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler.logout(SecurityContextLogoutHandler.java:65) ~[spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Alparslan Avci    6 年前

    Hazelcast基于Tomcat的Web会话复制仅支持 Serializable 当需要对对象进行群集时,将其作为会话对象。当在集群配置中设置全局序列化程序时,此要求也适用。因此,您需要创建会话对象 可序列化 让它发挥作用。

    您还可以在文档中找到此要求: https://github.com/hazelcast/hazelcast-tomcat-sessionmanager#features-and-requirements

    我在回购协议上提出了一个关于此请求的Github问题,请从此处跟踪流程: https://github.com/hazelcast/hazelcast-tomcat-sessionmanager/issues/38

        2
  •  0
  •   mad_fox    6 年前

    将Kryo添加到全局序列化程序对我不起作用。我不得不将其添加为常规序列化程序。弹簧靴示例:

    Config config = new Config();
    /* other hazelcast configs omittedfor brevity */
    SerializerConfig kyroSerizlier = new SerializerConfig()
                    .setImplementation(new GlobalKryoSerializer())
                    .setTypeClass(Object.class);
    config.getSerializationConfig().addSerializerConfig(kyroSerizlier);