Documentation

You are viewing the documentation for the 2.3.x release series. The latest stable release series is 2.4.x.

§フロント・エンドとなる HTTP サーバのセットアップ

HTTP ポートを 80 番に設定すれば、アプリケーションを簡単にスタンドアロンのサーバとしてデプロイすることができます。

$ /path/to/bin/<project-name> -Dhttp.port=80

プロセスを 80 番ポートにバインドするために root 権が必要なことがあります。

一方、同じサーバで複数のアプリケーションをホスティングしたり、スケーラビリティや耐障害性の観点から、アプリケーションのインスタンスを複数たちあげて、それらをロードバランシングしたいこともあるでしょう。その場合は、フロントエンド HTTP サーバを利用することができます。

フロントエンド HTTP サーバを利用する場合、Play サーバを直接利用する場合よりも優れたパフォーマンスが得られることはめったにないことに注意してください。しかしながら、HTTP サーバは HTTPS や条件付きの GET リクエスト、そして静的なアセットを処理することにとても優れているので、多くのサービスはフロントエンド HTTP サーバをアーキテクチャの一部として見なしています。

§lighttpd を使う

以下は lighttpd をフロントエンド Web サーバとして構成する例です。全く同じ用途に Apache を利用することもできますが、必要なものがバーチャルホスティングやロードバランスの機能だけであれば、 lighttpd の方が設定が簡単なのでおすすめです。

/etc/lighttpd/lighttpd.conf ファイルで、以下のように定義します:

server.modules = (
      "mod_access",
      "mod_proxy",
      "mod_accesslog" 
)
…
$HTTP["host"] =~ "www.myapp.com" {
    proxy.balance = "round-robin" proxy.server = ( "/" =>
        ( ( "host" => "127.0.0.1", "port" => 9000 ) ) )
}
 
$HTTP["host"] =~ "www.loadbalancedapp.com" {
    proxy.balance = "round-robin" proxy.server = ( "/" => ( 
          ( "host" => "127.0.0.1", "port" => 9001 ), 
          ( "host" => "127.0.0.1", "port" => 9002 ) ) 
    )
}

§nginx を使う

以下は nginx をフロントエンド Web サーバとして構成する例です。全く同じ用途に Apache を利用することもできますが、必要なものがバーチャルホスティングやロードバランスの機能だけであれば、 nginx の方が設定が簡単なのでおすすめです。

/etc/nginx/nginx.conf ファイルで、以下のように定義します:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
  include       mime.types;
  default_type  application/octet-stream;

  sendfile        on;
  keepalive_timeout  65;

  proxy_buffering    off;
  proxy_set_header   X-Real-IP $remote_addr;
  proxy_set_header   X-Scheme $scheme;
  proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header   Host $http_host;
  proxy_http_version 1.1;

  upstream my-backend {
     server 127.0.0.1:9000;
  }

  server {
    listen       80;
    server_name www.mysite.com;
    location / {
       proxy_pass http://my-backend;
    }
  }

  #server {
  #  listen               443;
  #  ssl                  on;
  #
  #  # http://www.selfsignedcertificate.com/ is useful for development testing
  #  ssl_certificate      /etc/ssl/certs/my_ssl.crt;
  #  ssl_certificate_key  /etc/ssl/private/my_ssl.key;
  #
  #  # From https://bettercrypto.org/static/applied-crypto-hardening.pdf
  #  ssl_prefer_server_ciphers on;
  #  ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # not possible to do exclusive
  #  ssl_ciphers 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA';
  #  add_header Strict-Transport-Security max-age=15768000; # six months
  #  # use this only if all subdomains support HTTPS!
  #  # add_header Strict-Transport-Security "max-age=15768000; includeSubDomains"
  #
  #  keepalive_timeout    70;
  #  server_name www.mysite.com;
  #  location / {
  #    proxy_pass  http://my-backend;
  #  }
  #}
}

バージョン 1.2 以降の Nginx を使っていることを 確認 してください。そうでないと、チャンクされたレスポンスは正常に動作しません。

§Apache を使う

以下は Apache httpd server を標準的な設定の Play アプリケーションの前段に配置するシンプルな設定の例です。

LoadModule proxy_module modules/mod_proxy.so
…
<VirtualHost *:80>
  ProxyPreserveHost On
  ServerName www.loadbalancedapp.com
  ProxyPass  /excluded !
  ProxyPass / http://127.0.0.1:9000/
  ProxyPassReverse / http://127.0.0.1:9000/
</VirtualHost>

§リバースプロキシに関する詳細設定

フロントエンド HTTP サーバを利用する場合、Play アプリケーションからすると、 HTTP リクエストがその HTTP サーバから送信されているように見えます。通常の設定では、同じマシン上で Play アプリケーションとリバースプロキシを起動している場合、 Play からはリクエストが 127.0.0.1 から送信されているように見えます。

リバースプロキシとなってる HTTP サーバは、プロキシ先の Play アプリケーションにリクエストの送信元を知らせるために、特別なヘッダを付与することができます。ほとんどの Web サーバは X-Forwarded-For というヘッダの第一引数にリクエスト元のクライアントの IP アドレスをつけて送信します。プロキシサーバがローカルで起動しており、127.0.0.1 から接続されている場合、Play は X-Forwarded-For ヘッダを信用します。別のマシンでリバースプロキシを実行している場合は、以下のようにアプリケーション設定ファイル内において trustxforwarded を true に設定することができます。

trustxforwarded=true

この設定を行った場合でも、 host ヘッダは変更されず、リバースプロキシが送信したままの内容になっています。そこで、例えば Apache 2.x を利用している場合は、次の設定を行うよいでしょう。

ProxyPreserveHost on

この設定を行うと、 Play アプリケーションへ送信される Host ヘッダが、クライアントから送信された元々の Host ヘッダの内容と同じになります。このように、XForwardedSupport と ProxyPreserveHost の二つの設定を組み合わせることで、アプリケーションが直接クライアントに公開されているように振る舞えるようになります。

もし、リバースプロキシへの一部のリクエストのみを Play アプリケーションに処理させたい場合は、一部のパスをプロキシ対象から除外する設定を追加してください。

ProxyPass /excluded !

§アプリケーションを透過的に更新するための、リバースプロキシとしての Apache

基本的な考え方は、 Play アプリケーションのインスタンスを二つ起動して、フロントエンドのプロキシサーバにそれらをロードバランスさせます。一方のインスタンスが落ちている場合には、稼働中のもう一方のインスタンスにのみリクエストを転送するようにします。

まず、同じ Play アプリケーションを 2 回起動します。一つはポート 9999 番、もう一つはポート 9998 で起動します。

$ start -Dhttp.port=9998
$ start -Dhttp.port=9999

次に、 Apache によるロードバランシングの設定を行います。

Apache の設定ファイルに、次のような設定を記述します。

<VirtualHost mysuperwebapp.com:80>
  ServerName mysuperwebapp.com
  <Location /balancer-manager>
    SetHandler balancer-manager
    Order Deny,Allow
    Deny from all
    Allow from .mysuperwebapp.com
  </Location>
  <Proxy balancer://mycluster>
    BalancerMember http://localhost:9999
    BalancerMember http://localhost:9998 status=+H
  </Proxy>
  <Proxy *>
    Order Allow,Deny
    Allow From All
  </Proxy>
  ProxyPreserveHost On
  ProxyPass /balancer-manager !
  ProxyPass / balancer://mycluster/
  ProxyPassReverse / balancer://mycluster/
</VirtualHost>

特に重要なのは、 balancer://mycluster という部分です。これがロードバランサーの定義です。 +H オプションは、2 番目の Play アプリケーションが待機系であるということの宣言です。ただし、同時にこの待機系をロードバランス対象に加えることもできます。

Apache には、宣言されたクラスタのステータスを表示する機能も備わっています。現在のステータスを表示するためには、ブラウザで /balancer-manager にアクセスしましょう。

Play は完全にステートレスなアーキテクチャになっているため、2 つのクラスタ間でのセッションの共有に頭を悩ませる必要はありません。そのおかげで、特に苦労せず 3 つ以上のインスタンスにスケールアウトさせることが可能です。

Apache は Websockets をサポートしていない ので、この機能を実装している (haproxy や nginx のような) 別のフロントエンドサーバを使いたくなるであろうことに注意してください。

Note that ProxyPassReverse might rewrite incorrectly headers adding an extra / to the URIs, so you may wish to use this workaround:

ProxyPassReverse / http://localhost:9999
ProxyPassReverse / http://localhost:9998

Next: HTTPS の設定


このドキュメントの翻訳は Play チームによってメンテナンスされているものではありません。 間違いを見つけた場合、このページのソースコードを ここ で確認することができます。 ドキュメントガイドライン を読んで、お気軽にプルリクエストを送ってください。