web-dev-qa-db-ja.com

Akka-アクターのインスタンスをいくつ作成する必要がありますか?

私はAkkaフレームワークを初めて使い、Netty + Akkaの上にHTTPサーバーアプリケーションを構築しています。

これまでの私の考えは、リクエストのタイプごとにアクターを作成することです。例えば。 POSTへの/ my-resourceへのアクターと、GETへの/ my-resourceへの別のアクターがあります。

私が混乱しているのは、アクターの作成についてどのようにすべきかです。したほうがいい:

  1. リクエストごとに新しいアクターを作成します(これにより、リクエストごとに適切なアクターのTypedActor.newInstance()を実行する必要があります)?新しいアクターを作成するのに費用はかかりますか?

  2. サーバー起動時に各アクターのインスタンスを1つ作成し、リクエストごとにそのアクターインスタンスを使用しますか?アクターは一度に1つのメッセージしか処理できないと読んでいますが、これはボトルネックにならないでしょうか?

  3. 他に何かしますか?

フィードバックをありがとう。

62
Brian DiCasa

さて、管理したい可変状態のインスタンスごとにアクターを作成します。

あなたの場合、my-resourceは単一のオブジェクトであり、各要求を連続して処理する必要があります。これにより、変更間で一貫した状態のみを返すことが簡単に保証されます。

(おそらく)複数のリソースを管理する場合、何千ものリソースに遭遇しない限り、リソースインスタンスごとに1つのアクターが通常理想的です。リクエストごとにアクターを実行することもできますが、それらのリクエストがアクセスしている状態を考えないと、奇妙なデザインになってしまいます。 POSTリクエストごとに1つのアクターを作成する場合、それらが同じリソースを同時に変更しないようにする方法を心配していることがわかります。これは、アクターを誤って定義したことを示しています。

私は通常、外部システムとの通信を抽象化することを主な目的とする、かなり些細な要求/応答アクターを持っています。 「インスタンス」アクターとの通信は、通常、実際のアクションを実行するための1つの要求/応答ペアに制限されます。

33
themel

オプション1)または2)には両方の欠点があります。それでは、オプション3)を使用してみましょう ルーティング (Akka 2.0 +)

ルーターは、ロードバランサーとして機能し、必要なタスクを実行する他のアクターにリクエストをルーティングする要素です。

Akkaは、メッセージをルーティングするためのさまざまなロジック(SmallestMailboxPoolやRoundRobinPoolなど)を持つさまざまなルーター実装を提供します。

すべてのルーターには複数の子があり、そのタスクはメールボックスを監視して、受信したメッセージのルーティング先をさらに決定することです。

//This will create 5 instances of the actor ExampleActor
//managed and supervised by a RoundRobinRouter
ActorRef roundRobinRouter = getContext().actorOf(
Props.create(ExampleActor.class).withRouter(new RoundRobinRouter(5)),"router");

この手順は このブログ で詳しく説明されています。

24
Didac Montero

Akkaを使用している場合、リクエストごとにアクターを作成できます。 Akkaはリソースが非常に少なく、ごく普通のJVMヒープ上に文字通り何百万ものアクターを作成できます。また、彼らは実際に何かをするときだけcpu/stack/threadsを消費します。

1年前、スレッドベースの標準アクターとイベントベースの標準アクターのリソース消費の間に 比較 を作成しました。そして、Akkaはイベントベースよりも優れています。

私の意見では、Akkaの大きなポイントの1つは、以前のアクターシステムがしばしば強制する「使用ごとに1つのアクター」としてシステムを設計できることですallowsリソースのオーバーヘッドのため、「共有サービスにはアクターのみを使用する」必要があります。

オプション1に進むことをお勧めします。

24
  1. これは非常に合理的なオプションですが、適切かどうかはリクエスト処理の詳細に依存します。

  2. はい、もちろん可能です。

  3. 多くの場合、最善の方法は、すべてのリクエストに1人のアクター(またはリクエストのタイプごとに1つのアクター)だけを応答させることですが、このアクターが行うことは、タスクを別のアクターに転送する(またはFuture)実際にジョブを実行します。

9
Alexey Romanov

シリアルリクエストの処理を拡大するには、マスターアクター( Supervisor )を追加します。マスターアクターはワーカーアクター( Children )に委任します( ラウンドロビン方式 )。

4
vijay