20
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

PlayFramework2.0とAkkaの設定

遅刻してしまった・・・。

あまり深い内容はできないのですが、PlayFrameworkのプロジェクトでプロダクション環境にデプロイするときにAkkaの設定をちゃんとやらんとやばそうなので、そのへんのことを共有(まだ本番デプロイしたことはないのですが)。

負荷テストの実施

まず、負荷の検証の内容として、自宅のiMacに簡単なPlayアプリケーションを作って、MacbookAirから負荷をかけてみました。

iMac側のアプリケーションには1000回ループして、hogeをひたすら連結するというアクションを作成。

MacbookAir側からはJMeterを使って、100スレッドで100秒間ひたすらリクエストを投げまくってみる、という雑なパフォーマンスのかけ方をしてみました。

その結果、75%くらいのエラーが発生しました。∑(゚Д゚)ガーン

原因

PlayFrameworkのマニュアルによればActionのディスパッチにAkkaのアクターを使って、複数のリクエストを並列に捌いています。

Action invoker アクターは Action のコードを実行するために使われます。複数の Action を並列に実行するために、複数のアクターを起動し、それらを Round Robin ルータで制御しています。また、全てのアクターはステートレスです。

Action invoker アクターは、リクエストボディをパーズするために使われる ボディ・パーサー を取得するためにも使われます。この取得処理はアクターからの返信(パーズに使われる BodyParser オブジェクト)を待機するという実装になっていて、設定されたタイムアウト時間を経過すると失敗する仕様です。

Action invoker アクターは actions-dispatcher ディスパッチャーによって実行されます。

で、このaction-dispatcherの並行度が最大24にデフォルトでは制限されています。

play {

    akka {
        :       
        actor {
            :            
            actions-dispatcher = {
                fork-join-executor {
                    parallelism-factor = 1.0
                    parallelism-max = 24
                }
            }
            :            
        }
    }
}

akkaのデフォルト設定の上書き

そこで、上記の設定を変更するためにデフォルトのakkaの設定を上書きします。で、PlayFrameworkの初心者の私はこの設定をどこに書くかで早速迷いましたが、ようはakka用のconfを作ってメインのconfファイルでincludeするだけでした。

/path/to/play-project/conf/application.conf
# 最後の方で・・・
include "akka.conf"
/path/to/play-project/conf/akka.conf
play {

    akka {
        event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]
        loglevel = WARNING

        actor {

            deployment {

                /actions {
                    router = round-robin
                    nr-of-instances = 256
                }

                /promises {
                    router = round-robin
                    nr-of-instances = 24
                }

            }

            retrieveBodyParserTimeout = 1 second

            actions-dispatcher = {
                fork-join-executor {
                    parallelism-factor = 128.0
                    parallelism-max = 256
                }
            }

            promises-dispatcher = {
                fork-join-executor {
                    parallelism-factor = 1.0
                    parallelism-max = 24
                }
            }

            websockets-dispatcher = {
                fork-join-executor {
                    parallelism-factor = 1.0
                    parallelism-max = 24
                }
            }

            default-dispatcher = {
                fork-join-executor {
                    parallelism-factor = 1.0
                    parallelism-max = 24
                }
            }

        }

    }

}

変更したのは以下のパラメーター。

  • play.akka.deployment./actions.nr-of-instances
  • play.akka.actions-dispatcher.fork-join-executor.parallelism-factor
  • play.akka.actions-dispatcher.fork-join-executor.parallelism-max 。

このへんの値はこちらの記事を参考にしました。

結果

当初のテストでは75%近くまでエラーが発生していたのが、同一条件の負荷をかけてもエラーが0%にまで下がり、スループットも若干向上しました。効果は明らかにありました。が、まだ、これらの値の設定をどのように変更すれば良いのかは現在見ている、、というか調べたかったのですが、遅刻もしているので、とりあえずここまで。。。

アドヴェント・カレンダーに突っ込んだものの、薄い内容でごめんなしあ。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
20
Help us understand the problem. What are the problem?