2016-08-24 2 views
2

Ich setze Akka-Cluster (mit akka-Bibliothek Version 2.3.9) mit einem Hauptdarsteller und mehrere Arbeiter Schauspieler. Master Actor ist mit einem Pool-Cluster-fähigen Router konfiguriert.AKKA (V2.3.9) Spring-Integration :: Cluster Remote Routes Failover wegen Spring Class Serialization Fehler

Anwendung mit der Bildung von 4 Cluster-Knoten bereitstellen. Anfangs verbinden sich alle Knoten, um ordnungsgemäß zu clustern, aber nach einigen Minuten trennen sich Knoten vom Cluster und bilden ihren eigenen Cluster.

**Getting below warn message logged when enabling remote debug logging -** 

**ERROR] []** [ClusterSystem-akka.remote.default-remote-dispatcher-23] [akka.tcp://ClusterSystem 
@localhost:2551/system/endpointManager/reliableEndpointWriter-akka.tcp%3A%2F%2FClusterSystem%40localhost%3A2552-0/en 
dpointWriter] AssociationError [akka.tcp://[email protected]:2551] -> [akka.tcp://[email protected]:2552 
]: **Error [Failed to write message to the transport] [ 
akka.remote.EndpointException: Failed to write message to the transport 
Caused by: java.lang.IllegalArgumentException: Can't serialize object of type class org.springframework.context.supp 
ort.ClassPathXmlApplicationContext** 
    at akka.cluster.protobuf.ClusterMessageSerializer.toBinary(ClusterMessageSerializer.scala:74) 
    at akka.serialization.Serialization$$anonfun$serialize$1.apply(Serialization.scala:90) 
    at akka.serialization.Serialization$$anonfun$serialize$1.apply(Serialization.scala:90) 
    at scala.util.Try$.apply(Try.scala:161) 
    at akka.serialization.Serialization.serialize(Serialization.scala:90) 
    at akka.remote.serialization.DaemonMsgCreateSerializer.serialize(DaemonMsgCreateSerializer.scala:107) 
    at akka.remote.serialization.DaemonMsgCreateSerializer$$anonfun$propsProto$1$1.apply(DaemonMsgCreateSerializ 
er.scala:56) 
    at akka.remote.serialization.DaemonMsgCreateSerializer$$anonfun$propsProto$1$1.apply(DaemonMsgCreateSerializ 
er.scala:56) 
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) 
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) 
    at scala.collection.immutable.List.foreach(List.scala:318) 
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) 
    at scala.collection.AbstractTraversable.map(Traversable.scala:105) 
    at akka.remote.serialization.DaemonMsgCreateSerializer.propsProto$1(DaemonMsgCreateSerializer.scala:56) 
    at akka.remote.serialization.DaemonMsgCreateSerializer.toBinary(DaemonMsgCreateSerializer.scala:62) 
    at akka.remote.MessageSerializer$.serialize(MessageSerializer.scala:36) 
    at akka.remote.EndpointWriter$$anonfun$serializeMessage$1.apply(Endpoint.scala:842) 
    at akka.remote.EndpointWriter$$anonfun$serializeMessage$1.apply(Endpoint.scala:842) 
    at scala.util.DynamicVariable.withValue(DynamicVariable.scala:57) 
    at akka.remote.EndpointWriter.serializeMessage(Endpoint.scala:841) 
    at akka.remote.EndpointWriter.writeSend(Endpoint.scala:742) 
    at akka.remote.EndpointWriter$$anonfun$2.applyOrElse(Endpoint.scala:717) 
    at akka.actor.Actor$class.aroundReceive(Actor.scala:465) 
    at akka.remote.EndpointActor.aroundReceive(Endpoint.scala:410) 
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516) 
    at akka.actor.ActorCell.invoke(ActorCell.scala:487) 
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:254) 
    at akka.dispatch.Mailbox.run(Mailbox.scala:221) 
    at akka.dispatch.Mailbox.exec(Mailbox.scala:231) 
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) 
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.pollAndExecAll(ForkJoinPool.java:1253) 
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1346) 
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) 
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) 
+0

Nicht sicher, was Sie versuchen zu erreichen, aber das klingt wirklich seltsam zu serialisieren der gesamte 'ClassPathXmlApplicationContext' ... –

Antwort

1

Ich habe mit dem gleichen Problem in meiner Java-Spring-Akka-Anwendung konfrontiert. Ich benutze IndirectActorProducer zur Instanziierung von Akteuren als Bean (mit Scope-Prototyp). Dieser Producer enthält Spring ApplicationContext. Ein solcher Weg funktioniert perfekt mit Cluster Sharding. Aber der einfache gepoolte Router in der Cluster-Umgebung (Round-Robin-Pool in meinem Fall) versucht Props mit IndirectActorProducer (und mit ApplicationContext) über Cluster zu senden. Ich kann einige Workarounds für Hacks vorschlagen, die für mich funktionieren: Erstellen Sie einen benutzerdefinierten Serializer und definieren Sie ihn in der Klasse "ConfigurableApplicationContext". Siehe nachstehendes Beispiel:

public class SpringContextSerializer extends JSerializer { 
private static ConfigurableApplicationContext configurableApplicationContext; 

public static void init(ConfigurableApplicationContext configurableApplicationContext) { 
    SpringContextSerializer.configurableApplicationContext = configurableApplicationContext; 
} 

public SpringContextSerializer() { 
    if (configurableApplicationContext == null) { 
     throw new RuntimeException("Serializer mist be initialized before creating."); 
    } 
} 

@Override 
public int identifier() { 
    return getClass().toString().hashCode(); 
} 

@Override 
public byte[] toBinary(Object o) { 
    return new byte[0]; 
} 

@Override 
public boolean includeManifest() { 
    return false; 
} 

@Override 
public Object fromBinaryJava(byte[] bytes, Class<?> manifest) { 
    return configurableApplicationContext; 
} 
} 

Config:

akka.actor { 
serializers { 
    context = "ru.ddg.elleps.hubcache.integration.SpringContextSerializer" 
} 

serialization-bindings { 
    "org.springframework.context.annotation.AnnotationConfigApplicationContext" = context 
} 
} 

Außerdem haben Sie Serializer mit Container initialisiert vor dem ein ActorSystem gestartet wird.

+0

wirklich eine gute Antwort, löste mein Problem, ich weiß nicht, warum nur die Remote-Bereitstellung hat Problem –