web-dev-qa-db-ja.com

Akkaと既存のJavaプロジェクト)との統合の例

Javaおよびspringコンテナを使用する既存のservletWebアプリケーションがすでにある場合。 Akkaを統合する適切な方法は何ですか?

_Actor1_と_Actor2_が相互に通信するようにします。それらのアクターを使い始めるためのエントリーポイントは何でしょうか? (例:1。そこに置く2.構成を変更する3.アクターへの参照を取得する)

私は見つけました http://doc.akka.io/docs/akka/2.2-M3/general/configuration.html しかし、彼は私に接着剤を提供しません。統合の実際の例を取得したいだけです。

簡単な統合の例はありますか?

EDIT:アプリケーションは検索を行い、外部からデータを取得し、情報をファイルに保存します。

アプリケーションはかなり大きいです。一部のコンポーネント/オブジェクトは、直接のクライアント要求から外れて、独自の寿命を残すことができます。それは、いくつかのことを並行して実行できます。可変状態を持ついくつかのシングルトンオブジェクトのように。

問題は、アクターをどこに適用できるか正確にはわからないということです。調査中です。しかし、私がすでに持っているのは、あちこちで同期されたブロックがたくさんあることです。

そして、それはすでに、俳優が適用されるかもしれないという一種の兆候であると私は信じています。 (わからないので、同期を入れるのを忘れたかもしれません。もちろん、の統合テストはありません。それ)

構成については、Actrors/Akkaをそこに住まわせるためにapplication.confを構成する必要があるかどうかわかりません(ドキュメント自体に説明されているため)。

私が見るもの:

_@Component("someManager")
public class SomeManager {
 List<Some> something;  // mutable state, that why I use locks here.
 // methods: add(), delete(), update()  
}
_

SomeManagerActorにすることができます

SomeManagercontrollerから使用されます。したがって、コントローラーアクターもあるといいですか? (onReceive()メソッド)へのフィードバックを受け取りたいです。

これは一種の議論の余地があります...それが私がいくつかのを必要とするもう1つの理由です。

_synchronized/whait/notify_のものをすべて取り除き、アクターとのコミュニケーション手段としてメッセージを使用し、アクターに責任を移すことで、アプリケーションを改善できると思います。

または、 this のように、プロパティファイルに書き込むのはアクターである可能性があります

編集:

たとえば、今のところ私が見つけたもの:Actor1にActor2にメッセージを送信させるには、次のトリックを使用します。

_// somewhere in existing code
public void initActors() {

        ActorSystem system = ActorSystem.create(example");

        // initializing
        final ActorRef actor1 = system.actorOf(Props.create(Actor1.class), "actor1");

}
_

Actor1にはメソッドpreStart()があり、それを参照するとすぐに開始されます(上記)。そして、Actor2にメッセージを送信します。

_@Override
public void preStart() {
_

しかし、2人のアクターを初期化して作業を行う理由が適切かどうかはわかりません。

18
ses

私自身の質問に答えます。私の考えを共有するために、私が思いついたもの。

サーブレット/ SpringMVCに基づく既存の動作中のWebアプリケーションがすでにある場合、Actors/AKKAに切り替える(またはハッキングのためだけに既存のシステムにアクターを導入する)理由がない場合が多いようです。それの)私たちのアプリケーションで私たちが:

  • 持っていない:スレッドワーカーロジック、タスクがバックラウンドで分割されている場合。 (通常、一般的なWebアプリケーションにはこれがありません)、長い長い計算のように..(並列処理)。
  • Have:シーケンシャルコールがある場合-1つのコンポーネントが別のコンポーネントを呼び出すと、別のコンポーネントが呼び出され、呼び出しは相互に依存します。コントローラーがコンポーネントを呼び出すように、コンポーネントはデータをリストに保存します(これは変更可能ですが、Synchronized-listとして同期されます)。
  • 持っていないすべてのSpringコントローラーをAkkaアクターに置き換えるか、別のサーバー(Tomcatではない)を使用する自由な時間(それを許可するマネージャー/製品所有者はそれほど多くありません)

この単純なシステムにアクターがいることの何が問題になっていますか:

  • コンポーネントを介して来るメッセージのトン(アクターとの間でコマンドをラップするクラス)一般的なメソッドを呼び出す代わりに(OPPの利点を使用し、インターフェイスを実装し、いくつかの実装を行う-しかし、俳優は通常final class)。

  • メッセージをstringとして持つことも、デバッグが難しいため、適切な解決策ではありません。

  • このようなシステム(mvcサイトなど)では、通常、同期するものはそれほど多くありません(すでにかなりstatelessです)。通常は0..2mutable shared data各コントローラー/コンポーネント。これは同期するのはそれほど難しくありません(クラスの最上位で共通で共有されているすべてのものを同期する習慣をつけてください(状態が認識可能/ローカライズされるように)。場合によっては、synchronized collectionまたはJava Atomicラッパータイプを使用します。

既存のアプリケーションでアクターが使用される可能性がある場合。ユースケースは次のようになります:

  • 長期にわたる検索を行う場合、それはいくつかのソース(スレッドワーカーの一種)を経由します。 MasterActor-> SiteSearchActorのいくつか/プルを持っている(計算のために説明されたようにPIここ )。 MasterActorが最終結果を出します。 SiteSearchActorが複数のクライアントを計算する(複数のサイトを検索する)場所。
  • または、現在のサーブレットのもののうち、スレッドフォークがある場合
  • 私たちのシステムが何百万ものクライアントによって使用されることを確実に/理解したとき(単純なロジックでも)、事前にscalabilityperformance()について考える必要があります。
    • アクターは良いサケールです-1つのアクターからN-oneに1つの作品を委任できます。
    • アクターは、スレッドを操作するときにプロセッサータイプを保護します(必要ありません10000スレッド10000クライアント、ほとんどの場合、十分に4スレッド(プロセッサーと同じ量コアとしましょう))

しかし、一般的に私はconcurrencyparallelismに関する this の記事に同意します。ゼロからアプリケーションを作成する機会があれば、Akka サーブレットコンテナなしおよびメッセージをどうにかして気にする(コマンドクラス)および[〜#〜 ] oop [〜#〜]使用する必要がある場合(一般的なWebアプリケーションではOOPはそれほど多くありません。とにかく言うべきです。しかし、ビジネスロジックをOOP方法、アクターは単なるコミュニケーションの接着剤です)。これは、たとえばJMSを使用するよりもはるかに優れています。

しかし、私が言ったように:

俳優/アッカは以下に適しています:

  1. サービス/コントローラ(サーブレット/ SpringMVCのものの代わりに)
  2. ロジックのようなスレッドワーカー
  3. 特にゼロからのプロジェクトの場合(現在のインフラストラクチャがアクター1を適用する際の障壁にならない場合)。

私が今持っている唯一の質問はperformance comparison。私たちがそれを知っていると仮定すると:

1つのJVMに10000のスレッドがあり、MVCコントローラー/サービスで共有された可変データの同期とロックが行われていると、パフォーマンスの観点から非常に悪い場合があります。考えられるロックは多数あるため、互いに並行しているスレッド(共有リソースのライバルまたは競合)。

Nを含むAKKA /サーブレット(アクター、Nが1000よりはるかに多い少ない)について同じシナリオがある場合、パフォーマンスがはるかに向上する可能性があります(キュー自体を除いて誰もブロックしないため、あるスレッドから別のスレッドに切り替える必要はありません)。

ただし、サーブレットベース(スレッドモデル)アプリケーション用に10000クライアントのシステムがある場合でも、100クライアントのシステムでは非常にうまく機能する可能性があります。そして、接続のプールがある場合(確かにあります)、それはアクターのキュー(受信ボックス)と同じ働きをし、クライアントがサービスの一部にアクセスできるようにスケジュールします。これにより、K回のパフォーマンスが向上する可能性があります(プールがない場合、Kははるかに多くなります-スレッドが互いに必死にブロックするようにします)。

質問は:

既存のサーブレットベースのアプリケーションにAKKAを適用しないのは正当な理由ですか?

これを議論する:Servlersに古いシステムがあっても、connection poolパフォーマンスが良好なレベルに向上する可能性があります。そして、このレベルは、サーブレットモデルを変更しようとするなど、既存のサーブレットアプリケーションにAKKAを適用しないために十分である可能性があります(これは、AKKA上のコントローラーと比較して悪いと思われます)。

このように考えるのは理にかなっていますか?

接続プルは、コマンド(接続)をスケジュールする一種のINBOX(AKKAのように)であると考えてください。

サーブレットモデルが不良(接続プールからの接続によって作成されているrest(アクティブ)スレッドのロックを処理している場合でも)。

Akkaをサーブレットベースのものと比較するときに忘れられる接続プールでは十分かもしれません。接続プールのMAX-CONNECTIONを変更して、アプリケーションを調整することはできます。そして通常、私たちはアプリケーションをステートレスにするために最善を尽くします。そのため、ほとんどの場合、何も同期しません。

しかしもちろん、全体アプリケーション用のOne接続プールしかないのは悪いことです。アクターと比較する場合、各アクターにはそれぞれ独自の接続プール(メールボックス)があり、各アクターがHTTP要求の受け入れを担当している可能性があります。そのモデルは確かに優れています。

P.S.ほとんどの場合、** Future ** sで十分です。アクターは、状態を「安全」に保存したい場合に適しています(基本的にFutureとは異なります)。

PDATE:一部の人々 アクターを使用することはまったく悪い考えだと信じています。良いのは、純粋関数アプローチか、 scalaz がすでに提供しているもの(およびHaskellだと思います)-ですが、リモート呼び出しにはまだ対応していません。

28
ses

私は同様の問題に遭遇しました。

ユーザー数が少ない単純なWebアプリケーションにAKKAを追加するメリットはほとんどないことに同意します。

しかし、既存のSpringMVCアプリにAKKAをアタッチするのは難しいとは思いません。プロジェクトをスケーリングする必要がある場合は、@ Serviceレイヤーをアクターにラップできます。したがって、@ Controllersはアクターの内部にある必要はありません。

春とakkaの統合に関するプレゼンテーションは次のとおりです。 https://www.youtube.com/watch?v=fALUf9BmqYE

プレゼンテーションのソースコード: https://github.com/jsuereth/spring-akka-sample/tree/master/src/main/Java/org/springframework/samples/travel

3