5

独自の ExecutionContext を作成する方法、または play フレームワークのグローバルなものをインポートする方法を知っています。しかし、複数の context/executionServices が背後でどのように機能するかについて、私は専門家にはほど遠いことを認めなければなりません。

私の質問は、サービスのパフォーマンス/動作を向上させるために、どの ExecutionContext を使用する必要があるかということです。

2 つのオプションをテストしました。

import play.api.libs.concurrent.Execution.defaultContext

implicit val executionContext = ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()))

どちらも同等のパフォーマンスをもたらします。

私が使用するアクションは、playframework 2.1.x でこのように実装されています。SedisPool は、通常の sedis/jedis クライアント プールの追加の Future ラッピングを備えた私自身のオブジェクトです。

def testaction(application: String, platform: String) = Action {
    Async(
      SedisPool.withAsyncClient[Result] { client =>
        client.get(StringBuilder.newBuilder.append(application).append('-').append(platform).toString) match {
          case Some(x) => Ok(x)
          case None => Results.NoContent
        }
      })
  }

このパフォーマンスの点では、Node.js や Go のまったく同じ関数と同じか、わずかに遅くなります。それでも Pypy よりは遅いです。しかし、Java での同じことよりもはるかに高速です (この場合、jedis を使用した redis へのブロッキング呼び出しを使用)。ガトリングで負荷テストを行いました。私たちは redis 上の単純なサービスを求めて技術者の「競争」を行っていましたが、その基準は「コーダーからの同じ量の努力」でした。私はすでに fyrie を使用してこれをテストしました (API が気に入らないという事実は別として)、この Sedis 実装とほぼ同じように動作しました。

しかし、それは私の質問の横にあります。playframework/scala のこの部分についてもっと知りたいだけです。

推奨される行動はありますか?または、誰かが私をより良い方向に向けることができますか? 私は今scalaを使い始めています。私は専門家とはほど遠いですが、コードの答えを自分で説明することができます.

助けてくれてありがとう。

更新 - さらに質問があります。

プール内のスレッド数を改ざんした後、次のことがわかりました: Runtime.getRuntime().availableProcessors() * 20

サービスのパフォーマンスが約 15% から 20% 向上します (1 秒あたりのリクエストと平均応答時間で測定)。実際には、node.js や go よりわずかに優れています (かろうじてですが)。そこで、さらに質問があります: - 15x と 25x をテストしましたが、20 が最適なようです。なんで?何か案は?- 他にもっと良い設定はありますか? 他の「スイートスポット」は?- 20 倍が最適ですか、それとも実行中のマシン/jvm の他のパラメータに依存しますか?

更新 - この件に関するその他のドキュメント

Play フレームワークのドキュメントに関する詳細情報を見つけました。 http://www.playframework.com/documentation/2.1.0/ThreadPools

IOの場合、彼らは私が行ったことに何かアドバイスをしますが、* .confファイルを介して構成可能なAkka.dispatchersを介してそれを行う方法を提供します(これは私のopsを幸せにするはずです)。

だから今私は使用しています

implicit val redis_lookup_context: ExecutionContext = Akka.system.dispatchers.lookup("simple-redis-lookup")

によって構成されたディスパッチャ

akka{
    event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]
    loglevel = WARNING
    actor {
        simple-redis-lookup = {
            fork-join-executor {
                parallelism-factor = 20.0   
                #parallelism-min = 40
                #parallelism-max = 400
            }
        }
    }
}

JVM が「ホット」になると、約 5% 向上し (目で見てわかるように)、パフォーマンスの安定性が向上しました。そして、私のシステム運用者は、サービスを再構築することなく、これらの設定をいじって喜んでいます。

私の質問はまだそこにあります。なぜこの数字?

4

2 に答える 2

1

スレッドプールを変更してみましたか:

  • FixedThreadPool の代わりに CachedThreadPool を使用して、ThreadPool がどれだけ成長するかを把握するために、それを制限する前に
  • コアごとに 1 つ以上のスレッド、おそらく 2 つを使用しますか?
于 2013-04-25T12:09:09.123 に答える