28

I/O (データベース操作など) を実行する必要がある場合、(Akka の) アクター モデルはどのように機能しますか?

ブロッキング操作が例外をスローすることは理解しています (そして、Akka が使用する Netty のイベント化された性質により、本質的にすべての同時実行が台無しになります)。したがって、Futureまたは同様のものを使用する必要がありますが、同時実行モデルがわかりません。

  1. 1 つのアクターが複数のメッセージを同時に処理できますか?
  2. futureアクターが(つまり)でブロッキング呼び出しを行った場合future.get()、現在のアクターの実行のみがブロックされます。それとも、ブロッキング呼び出しが完了するまで、すべてのアクターでの実行を防止しますか?
  3. すべての実行をブロックする場合、将来の支援同時実行をどのように使用しますか?
  4. 各ステップが最後のステップに依存する多段階プロセス (つまり、データベースからの読み取り、ブロッキング Web サービスの呼び出し、データベースからの読み取り、データベースへの書き込み) を処理する最良の方法は何ですか?

基本的なコンテキストは次のとおりです。

  • 何千ものセッションを維持する Websocket サーバーを使用しています。
  • 各セッションにはいくつかの状態 (つまり、認証の詳細など) があります。
  • Javascript クライアントは JSON-RPC メッセージをサーバーに送信し、サーバーはそれを適切なセッション アクターに渡します。サーバーはそれを実行して結果を返します。
  • RPC 呼び出しの実行には、いくつかの I/O 呼び出しとブロッキング呼び出しが含まれます。
  • 多数の同時リクエストが発生します (各ユーザーは WebSocket 接続を介して大量のリクエストを行い、多くのユーザーが存在します)。

これを達成するためのより良い方法はありますか?

4

3 に答える 3

28

ブロッキング操作は、Akkaで例外をスローしません。アクターからの呼び出しをブロックすることができます(おそらく最小化する必要がありますが、それは別の話です)。

  1. いいえ、1つのアクターインスタンスはできません。
  2. 他のアクターをブロックすることはありません。特定のディスパッチャを使用して、これに影響を与えることができます。Futuresはデフォルトのディスパッチャー(通常はグローバルイベント駆動型)を使用するため、プール内のスレッドで実行されます。アクターに使用するディスパッチャーを選択できます(アクターごと、またはすべて)。本当に問題を作成したいのであれば、まったく同じ(スレッドベースの)ディスパッチャーを先物とアクターに渡すことができるかもしれませんが、それはあなたの側からある程度の意図が必要です。膨大な数の先物が無期限にブロックされていて、executorserviceが一定量のスレッドに構成されている場合は、executorserviceを爆破する可能性があります。だからたくさんの「ifs」。f.getは、Futureがまだ完了していない場合にのみブロックします。それはあなたがそれを呼び出すアクターの「現在のスレッド」をブロックします(あなたがそれをアクターから呼び出す場合、
  3. 必ずしもブロックする必要はありません。f.getの代わりにコールバックを使用できます。ブロックせずに先物を作成することもできます。詳細については、「akkaの有望な未来」に関するViktorの講演をご覧ください:http ://skillsmatter.com/podcast/scala/talk-by-viktor-klang
  4. ステップ間で非同期通信を使用するので(ステップがそれ自体で意味のあるプロセスである場合)、すべてのアクターが次のアクターに一方向のメッセージを送信し、場合によっては他のアクターに一方向のメッセージを送信するすべてのステップにアクターを使用します。プロセスを監視できるブロック。このようにして、アクターのチェーンを作成し、その多くを作成することができます。その前に負荷分散アクターを配置して、1つのアクターが一方のチェーンでブロックした場合、同じタイプの別のアクターがもう一方のチェーンにない可能性があります。これは、「コンテキスト」の質問、ローカルアクターへのワークロードの受け渡し、負荷分散アクターの背後にそれらをチェーンする場合にも機能します。

nettyについては(NettyがAkkaで使用されるのはこれだけなので、リモートアクターを意味すると思います)、心配な場合は、できるだけ早くローカルアクターまたは将来(コールバック付き)に作業を渡します。タイミングやnettyが何らかの方法でその仕事をするのを防ぐことについて。

于 2011-06-30T06:30:04.700 に答える
10

ブロック操作は通常、例外をスローしませんが、(メソッドの使用!!または!!!送信などによる) 将来の待機は、タイムアウト例外をスローする可能性があります。そのため、可能な限りファイア アンド フォーゲットに固執し、意味のあるタイムアウト値を使用し、可能な場合はコールバックを優先する必要があります。

  1. akka アクターは連続して複数のメッセージを明示的にthroughput処理することはできませんが、構成ファイルを介して値を操作することはできます。メッセージ キューが空でない場合、アクターは複数のメッセージを処理します (つまり、受信メソッドが連続して数回呼び出されます)

  2. アクター内で操作をブロックしてもすべてのアクターが「ブロック」されるわけではありませんが、アクター間でスレッドを共有する場合 (推奨される使用方法)、操作が再開されるまでディスパッチャーのスレッドの 1 つがブロックされます。そのため、可能な限り先物を作成し、タイムアウト値に注意してください)。

3 と 4. Raymond の回答に同意します。

于 2011-06-30T09:15:40.430 に答える