2016-11-09 1 views
0

많은 게시물을 읽은 후 kryo에 대한 내 답변에 대한 답변을 찾지 못했습니다.Kryo ClassNotFoundException 갑자기 발생했습니다.

우리는 두 서버 사이에 매우 많은 양의 메시지를 직렬화/비 직렬화하는 Kryo (v4.0.0)를 구현하려고합니다.

우리의 문제는 직렬화/역 직렬화가 다음과 같은 예외가 작업을 중단 갑자기 몇 분 (그래서 더 천 이상의 메시지) 동안 잘 작동 할 수 있다는 것입니다 :

2016-11-09 13:23:32,968 [AMQP_consumer_blk-ic-p.tradair.com_TMSOutWL_TMSOutWL_streaming-1] ERROR Driver handleDelivery - 
com.esotericsoftware.kryo.KryoException: Unable to find class: ^AA^]^A^@^A^B^C^_^C ^C!^C^A59927910321794 
Serialization trace: 
payload (com.trade.common.messagebus.AMQPPacket) 
     at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:160) ~[kryo-shaded-4.0.0.jar:?] 
     at com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:133) ~[kryo-shaded-4.0.0.jar:?] 
     at com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:693) ~[kryo-shaded-4.0.0.jar:?] 
     at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:118) ~[kryo-shaded-4.0.0.jar:?] 
     at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:540) ~[kryo-shaded-4.0.0.jar:?] 
     at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:813) ~[kryo-shaded-4.0.0.jar:?] 
     at com.tradair.common.serialization.kryo.KryoSerializer.deserialize(KryoSerializer.java:60) ~[common-4.7.3.12.jar:?] 
     at com.trade.common.messagebus.AbstractMessageBusConsumer$1.handleDelivery(AbstractMessageBusConsumer.java:106) ~[common-4.7.3.12.jar:?] 
     at com.rabbitmq.client.impl.ConsumerDispatcher$5.run(ConsumerDispatcher.java:144) ~[amqp-client-3.4.3.jar:?] 
     at com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:95) ~[amqp-client-3.4.3.jar:?] 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_40] 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_40] 
     at java.lang.Thread.run(Thread.java:745) [?:1.8.0_40] 
Caused by: java.lang.ClassNotFoundException: ^AA^]^A^@^A^B^C^_^C ^C!^C^A59927910321794 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[?:1.8.0_40] 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_40] 
     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[?:1.8.0_40] 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_40] 
     at java.lang.Class.forName0(Native Method) ~[?:1.8.0_40] 
     at java.lang.Class.forName(Class.java:348) ~[?:1.8.0_40] 
     at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:154) ~[kryo-shaded-4.0.0.jar:?] 
     ... 12 more 

당신은 Kryo 성공하지 못한 것을 볼 수있다 클래스 이름을 읽을 수 없습니다 (클래스를 찾을 수 없습니다 :^AA ^]^A^@^A^B^C^_^C^C!^C^A59927910321794).

내 직렬화 클래스 :

내가 아는 한
public class KryoSerializer extends AbstractSerializer { 

    private Logger logger = LoggerFactory.getLogger(KryoSerializer.class); 
    protected Kryo kryo; 
    protected Output output; 
    protected Input input; 
    protected ByteArrayOutputStream bos; 
    protected ByteArrayInputStream bis; 

    public KryoSerializer(List<Class> list) { 
     kryo = new Kryo(); 
     kryo.setRegistrationRequired(false); 
     kryo.setReferences(true); 
     for (Class cl : list) { 
      kryo.register(cl); 
     } 
    } 

    @Override 
    public <T> byte[] serialize(T msg) { 
     try { 
      bos = new ByteArrayOutputStream(); 
      output = new Output(bos); 
      kryo.writeClassAndObject(output, msg); 
      output.flush(); 
      return bos.toByteArray(); 
     } finally { 
      try { 
       if (output != null) { 
        output.close(); 
       } 
       if (bos != null) { 
        bos.close(); 
       } 
      } catch (IOException eio) { 
       logger.warn("", eio); 
      } 
     } 
    } 

    @Override 
    public <T> T deserialize(byte[] bytesArray) { 
     try { 
      bis = new ByteArrayInputStream(bytesArray); 
      input = new Input(bis); 
      return (T) kryo.readClassAndObject(input); 
     } finally { 
      try { 
       if (input != null) { 
        input.close(); 
       } 
       if (bis != null) { 
        bis.close(); 
       } 
      } catch (IOException eio) { 
       logger.warn("", eio); 
      } 
     } 
    } 
} 

답변

0

의 Kryo 클래스는 스레드로부터 안전하지 않습니다. 동시 환경에서이를 사용하는 경우, 매번 새 인스턴스를 작성해야합니다. 이와 같이 :

bos = new ByteArrayOutputStream(); 
output = new Output(bos); 
new Kryo().writeClassAndObject(output, msg); 
output.flush(); 
return bos.toByteArray(); 

이 방법으로 비슷한 문제를 해결하는 데 사용되었습니다.

관련 문제