確認

2016-07-06 5 views
0

アッカ-HTTPで実行コンテキストとスレッド割り当て異なっていないことが、この質問確認

のために右stackexchangeだ場合、私はいくつかの重い計算のフロントとして機能アッカ-HTTPアプリケーションを持っています。処理する要求は、処理に要する時間が異なります。 1秒以内に終了するものもあれば、それを超えるものもあります。

val spotsJsonF: Future[String] = spotsF.map(spots => DebugFormatter.produceJson(text, spots._1, spots._2, env)) 

complete(spotsJsonF.map { t => HttpEntity(ContentTypes.`application/json`, t) }) 

マイ要件/仮定:計算が将来と私の完全な要求、すなわち、任意の時点ではAwaitはありません、純粋に非同期であり、私は並列性を最大化するために必要

  • 、すなわち接続shouldn」
  • サービスがビジー状態であれば(少しでも)要求が長くかかることがあります。
  • 非常に長い要求では、負荷がかかっていない限りタイムアウトしていますHTTP要求がタイムアウトした後、並列処理に多大な影響を与えます。これを行うには

は、私はそれがスポーンとアッカのHTTPディスパッチャによって使用されるものとは異なるスレッドプールにFuture Sを変更すなわち、重い計算のために別個の実行コンテキスト(すなわち、ScalaのデフォルトExecutionContext.global)を得ました。私はこれがAkkaのスレッドに計算を「止めさせる」ことを止めると思ったので、より多くの接続を受け入れることができました。現時点では、(私のreference.confが空である)アッカのデフォルトのディスパッチャです:

"default-dispatcher": { 
     "attempt-teamwork": "on", 
     "default-executor": { 
     "fallback": "fork-join-executor" 
     }, 
     "executor": "default-executor", 
     "fork-join-executor": { 
     "parallelism-factor": 3, 
     "parallelism-max": 64, 
     "parallelism-min": 8, 
     "task-peeking-mode": "FIFO" 
     }, 
     "mailbox-requirement": "", 
     "shutdown-timeout": "1s", 
     "thread-pool-executor": { 
     "allow-core-timeout": "on", 
     "core-pool-size-factor": 3, 
     "core-pool-size-max": 64, 
     "core-pool-size-min": 8, 
     "fixed-pool-size": "off", 
     "keep-alive-time": "60s", 
     "max-pool-size-factor": 3, 
     "max-pool-size-max": 64, 
     "max-pool-size-min": 8, 
     "task-queue-size": -1, 
     "task-queue-type": "linked" 
     }, 
     "throughput": 5, 
     "throughput-deadline-time": "0ms", 
     "type": "Dispatcher" 
    }, 

長時間実行計算はアッカがタイムアウトのための要求をキャンセルした後も長く実行し続けるということですが、何が起こります。限られた数のコアでは、このオーバーロードを開始した計算がもはや必要なくなったとしても、拒否された要求の数は増加し始めます。

明らかに、このアプリケーションでスレッドを適切に管理する方法はわかりません。

私の要件を満たす最も良い方法は何ですか?いくつかのスレッドプール - 良い/悪い考えですか?明示的に取り消す必要はありますか? Scalaのバニラフューチャーを使用している可能性がありますこの時点で最良の選択肢ではありませんか?

+0

あなたは別の俳優、各リソースごとに1つずつ作成して考えがありますか?それをスケールすることは非常に容易であるべきであり、他のノードへの重い計算をプロキシし、マスタノードはこのシナリオではルータとしてのみ使用される。 –

+0

非常に重い(13G)構造をメモリに保持しなければならないため、これを分散アプリケーションとして使用しないため、大きなEC2インスタンスにのみ展開します – Anton

答えて

2

私にとって、これは、スレッドを管理し、重い作業を既に行っている別のディスパッチャに分けているのではなく、実際の処理を管理するということです。

長期間実行されているプロセスを中期的に停止できるようにするには、話をするために、小さなまとまりに分割する必要があります。

アクターとよく似たパターンは、処理者が結果を「これまで」保存するか、それをメッセージとして送信することです。この方法で、その間に「作業中止」メッセージに反応します。それはそれが中止すべきそのような長い壁の時間のために処理しました。作業負荷をトリガーするメッセージは、例えば、「クライアント」がそれを指定できるように、そのようなタイムアウト値を含むことができる。

(これは基本的に手スレッドで正しくInterruptedExceptionThread.isInterruptedを扱う、アプリケーションをブロックするようにほとんど同じことである)