2017-01-21 7 views
5

単一障害点を持たないシステムを作成したいと考えています。 私はルータがそれを行うためのツールであるという印象を受けましたが、期待通りにルータが動作するかどうかはわかりません。 これは私のプログラムのエントリポイントである:(ので、ルータはリモート・ノードにTestActorコードを展開できます)Akka単一障害点

object Main extends App{ 
    val system = ActorSystem("mySys", ConfigFactory.load("application")) 
    val router = system.actorOf(
    ClusterRouterPool(RoundRobinPool(0), ClusterRouterPoolSettings(
     totalInstances = 2, maxInstancesPerNode = 1, 
     allowLocalRoutees = false, useRole = Some("testActor"))).props(Props[TestActor]), 
    name = "testActors") 
} 

そして、これがリモートActorSystemを実行するためのコードです:

object TestActor extends App{ 
    val system = ActorSystem("mySys", ConfigFactory.load("application").getConfig("testactor1")) 
    case object PrintRouterPath 
} 

私はこれを2回、testactor1で1回、testactor2で1回実行しています。

TestActorコード:

class TestActor extends Actor with ActorLogging{ 
    implicit val ExecutionContext = context.dispatcher 
    context.system.scheduler.schedule(10000 milliseconds, 30000 milliseconds,self, PrintRouterPath) 

    override def receive: Receive = { 
    case PrintRouterPath => 
    log.info(s"router is on path ${context.parent}") 
    } 
} 

そしてapplication.conf

akka{ 
actor { 
    provider = "akka.cluster.ClusterActorRefProvider" 
} 
remote { 
    log-remote-lifecycle-events = off 
    netty.tcp { 
    hostname = "127.0.0.1" 
    port = 2552 
    } 
} 
cluster { 
    seed-nodes = [ 
    "akka.tcp://[email protected]:2552" 
    "akka.tcp://[email protected]:2553" 
    "akka.tcp://[email protected]:2554"] 
    auto-down-unreachable-after = 20s 
    } 
} 
testactor1{ 
    akka{ 
    actor { 
     provider = "akka.cluster.ClusterActorRefProvider" 
    } 
    remote { 
     log-remote-lifecycle-events = off 
     netty.tcp { 
     hostname = "127.0.0.1" 
     port = 2554 
     } 
    } 
    cluster { 
    roles.1 = "testActor" 
     seed-nodes = [ 
     "akka.tcp://[email protected]:2552" 
     "akka.tcp://[email protected]:2553" 
     "akka.tcp://[email protected]:2554"] 
     auto-down-unreachable-after = 20s 
    } 
    } 
} 
testactor2{ 
    akka{ 
    actor { 
     provider = "akka.cluster.ClusterActorRefProvider" 
    } 
    remote { 
     log-remote-lifecycle-events = off 
     netty.tcp { 
     hostname = "127.0.0.1" 
     port = 2553 
     } 
    } 
    cluster { 
    roles.1 = "testActor" 
     seed-nodes = [ 
     "akka.tcp://[email protected]:2552" 
     "akka.tcp://[email protected]:2553" 
     "akka.tcp://[email protected]:2554"] 
     auto-down-unreachable-after = 20s 
    } 
    } 
} 

今問題となっているルータを開始したプロセスが殺されたとき、TestActorのコードを実行している俳優、 (スケジューラーが送信するメッセージ)を受信して​​いない場合、クラスター内の別のシードノードにルーターがデプロイされ、アクターが回復することが予想されます。これは可能ですか?またはこのフローを実装し、単一の障害点を持たない他の方法がありますか?

答えて

2

routerを1つのノードに配置することで、マスターが定義上の単一障害点であるマスター/スレーブクラスターをセットアップしていると思います。

私が理解しているところ(docsを参照)から、ルータは、クラスタ内のノードでルート(プールモード)またはルックアップ(グループモード)を展開できるという意味でクラスタを認識できます。ルータ自体は、クラスタ内の他の場所に産み出すことで障害に反応しません。私はあなたが2つのオプション持っていると信じています

  1. は、あなたのシステムよりフォールトトレラントにする複数のルータを使用しています。ルーターは、ルーター間で共有(グループモード)することも、プールモード(プールモード)でもかまいません。

  2. パターンを使用すると、マスターが自動的に障害発生時に再生成されるマスタースレーブ設定が可能になります。あなたの例に関連して、この動作は、各ノードにアクター(ClusterSingletonManager)を配備することによって実現されることに注意してください。この俳優は、選ばれた師匠が返還される必要がある場合、そしてどこでどこで働かなければならないのかを明らかにする目的を持っています。あなたが設定したようなクラスタ対応ルータの場合は、このロジックはありません。

複数のクラスタ設定の例は、Activator sampleにあります。

+0

1)私はあなたが各ルータ上でまったく同じ2つのインスタンスを持っている(グループ)それらの一つ一つにルータを起動することをお勧め、その後testActorを実行している2つのノードを持って言うことができます役立ちます願っています。今はどのようにルータを使用しますか?私はそれを使用する目的は何ですか?ブロードキャストメッセージをルートに送信したい場合は、ルータを含むノードの1つにメッセージを送信するか、そのノードを使用できないか、またはすべてのノードに送信してから、複数のメッセージ処理を行います。何か不足していますか? 2) 'ClusterSingletonManager'を使うと' TestActor'で2人のアクターを起動できないでしょうか? –

0

私は最初にあなたのコードをClusterRouterPool と使って2つのアプローチをテストしました。あなたが言ったように、ルータを起動したプロセスが殺されたとき、TestActorはそれ以上のメッセージを受信しません。TestActorがメッセージを受信し続けるこの

`auto-down-unreachable-after = off` 

ため

`auto-down-unreachable-after = 20s` 

私は `tの(次のメッセージが表示されたログにあるが、:あなたはapplication.confに変更した場合 は、ドキュメントやテストを読んでいる間ここでログを保存する方法を知っておいてください):

[警告] [01/30/2017 17:20:26.017] [mySys-akka.remote.default-remote-dispatcher-5] [akka.tcp ://[email protected]:2554/system/endpointManager/reliable EndpointWriter-akka.tcp%3A%2F%2FmySys%40127.0.0.1%3A2552-0]協会と遠隔システム[akka.tcp://[email protected]:2552]失敗した、アドレスが今のゲートされる[5000]ミズ。理由:[協会は[akka.tcpで失敗しました://[email protected]:2552]]によって引き起こさ:[接続を拒否:/127.0.0.1:2552] [INFO] [2017年1月30日午後5時20: 29.860] [MYSYS-akka.actor.default-ディスパッチャ-4] [akka.tcp://[email protected]:2554/remote/akka.tcp/[email protected]:2552 /ユーザ/ testActors/C1]ルータは経路俳優である[akka.tcp://[email protected]:2552 /ユーザ/ testActors位-1120251475] [20:2017年1月30日17 32.016] [WARN] [MYSYS-akka.remote。デフォルト・リモート・ディスパッチャー-5] MainAppには、ログを再起動した場合には

とは、警告やエラーなしで正常に動作します

MainAppにログイン:

[INFO] [2017年1月30日17:23:32.756] [MYSYS-akka.actor.default-ディスパッチャ-2] [akka.cluster.Cluster(アッカ:// MYSYS)]クラスタノード[akka.tcp ://[email protected].0.0.1:2552] - [akka.tcpからようこそ://[email protected]:2554]

TestActorログイン:

INFO] [2017年1月30日17:23:21.958]クラスタノード[akka.cluster(akka:// mySys)] [akka.cluster(akka:// mySys)] [akka.tcp://[email protected]:2554] [mySys-akka.actor.default-dispatcher- - 既存のメンバー[Member(address = akka.tcp://[email protected]:2552、status = Up)]の新規インカネーションが参加しようとしています。既存のものはクラスタから削除され、新しいメンバーが参加することが許可されます。 [INFO] [2017年1月30日17:23:21.959] [MYSYS-akka.actor.default-ディスパッチャ-14] [akka.cluster.Cluster(アッカ:// MYSYS)]クラスタノード[akka.tcp。 //[email protected]:2554] - 到達不能なノードをマーキング[akka.tcp://[email protected]:2552]のように[DOWN] [INFO] [2017年1月30日17:23:22.454]を[ mySys-akka.actor.default-dispatcher-2] [akka.cluster.Cluster(akka:// mySys)]クラスタノード[akka.tcp://[email protected]:2554] - リーダーは再び任務を実行できます [INFO] [2017年1月30日17:23:22.461] [MYSYS-akka.actor.default-ディスパッチャ-2] [akka.cluster.Cluster(アッカ:// MYSYS)]クラスタノード[akka.tcp。 //[email protected]:2554] - リーダーが到達不能ノードを削除して[akka.tcp://[email protected]:2552] [INFO] [2017年1月30日17:23:32.728] [mySys- akka.actor.default-dispatcher-4] [akka.cluster.Cluster(akka:// mySys)]クラスタノード[akka.tcp://[email protected]:2554] - ノード[akka.tcp:// [email protected]:2552]はJOINING、roles [] [INFO] [2017年1月30日17:23:33.457] [MYSYS-akka.actor.default-ディスパッチャ-14] [akka.cluster.Cluster(アッカ:// MYSYS)]クラスタノード[akka.tcp。 //[email protected]:2554] - リーダーは、ノードを移動さ[akka.tcp://[email protected]:2552] [上へ] [INFO] [2017年1月30日まで17:23:37.925] [MYSYS-akka.actor.default-ディスパッチャ-19] [akka.tcp://[email protected]:2554/remote/akka.tcp/[email protected]:2552 /ユーザ/ testActors/C1]ルータでありますon pathアクタ[akka.tcp://[email protected]。1:2552 /ユーザ/ testActors#-630150507]

routeesクラスタ

  • グループのノード間で共有されるので、他のアプローチは、ClusterRouterGroupを使用することである - にメッセージを送信するルータアクターの選択を使用して指定されたパスルートは、クラスター内の異なるノード上で実行されているルーター間で共有できます。このタイプのルーターのユースケースの1つの例は、クラスター内のいくつかのバックエンドノードで実行され、クラスター内のフロントエンドノード上で実行されているルーターによって使用されるサービスです。
  • ルート - 子アクターとしてルートを作成し、リモートノードに展開するプールルーター。各ルータには独自のルートインスタンスがあります。たとえば、10ノードのクラスタ内の3つのノードでルータを起動する場合、ルータがノードごとに1つのインスタンスを使用するように設定されている場合、合計30のルートがあります。異なるルーターによって作成されたルートは、ルーター間で共有されません。このタイプのルータのユースケースの1つの例は、ジョブを調整し、実際の作業をクラスタ内の他のノード上で実行されているルートに委譲する単一のマスタです。

メインのApp

object Main extends App { 

    val system = ActorSystem("mySys", ConfigFactory.load("application.conf")) 
    val routerGroup = system.actorOf(
ClusterRouterGroup(RoundRobinGroup(Nil), ClusterRouterGroupSettings(
    totalInstances = 2, routeesPaths = List("/user/testActor"), 
    allowLocalRoutees = false, useRole = Some("testActor"))).props(), 
name = "testActors") 
} 

あなたは起動時にrouteeの俳優ができるだけ早期に開始する必要がある各リモートノードでTestActor

object TestActor extends App{ 
    val system = ActorSystem("mySys", ConfigFactory.load("application").getConfig("testactor1")) 
    system.actorOf(Props[TestActor],"testActor") 
    case object PrintRouterPath 
} 

http://doc.akka.io/docs/akka/2.4/scala/cluster-usage.html#Router_with_Group_of_Routees

を開始する必要がありますルータがthを使用しようとするため、俳優のシステムメンバーのステータスが「Up」に変更されるとすぐに表示されます。

私はそれはあなた

関連する問題