【问题标题】:Hazelcast with global serializer (Kryo) - There is no suitable de-serializer for typeHazelcast 与全局序列化器 (Kryo) - 没有适合类型的反序列化器
【发布时间】:2018-01-24 17:14:02
【问题描述】:

我正在使用 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;
    }
}

Hazelcast.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]

【问题讨论】:

  • 您能否检查一下是否所有 Hazelcast 集群成员都可以访问/使用相同的配置?
  • 我目前只使用一个应用服务器检查异常
  • 我认为我的问题被误解了。所有 Hazelcast 成员是否具有相同的配置?
  • 只有成员从我上面描述的 hazelcast.xml 中读取配置。这是来自 hazelcast 的日志:
  • [com.hazelcast.config.UrlXmlConfig] ... [com.hazelcast.core.LifecycleService] ... 成员 {size:1, ver:1} [ 成员 [172.16.200.65]:5701 - fcf18ad9-0a8c-4adf-8715- bf659782fc9a this ] ... [com.hazelcast.core.LifecycleService]

标签: java deserialization hazelcast kryo


【解决方案1】:

Hazelcast 的基于 Tomcat 的 Web Session Replication 仅在您需要将 Serializable 对象作为 Session 对象进行集群时才支持它们。当在集群配置中设置全局序列化程序时,此要求也适用。因此,您需要将会话对象设置为Serializable 才能使其工作。

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

我在 repo 上提出了关于此请求的 Github 问题,请从那里跟踪流程:https://github.com/hazelcast/hazelcast-tomcat-sessionmanager/issues/38

【讨论】:

    【解决方案2】:

    将 Kryo 添加到全局序列化程序对我不起作用。我必须将它添加为常规序列化程序。春季启动示例:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 2013-05-30
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2016-12-30
      相关资源
      最近更新 更多