SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Herokuでスタート! はじめてのPaaSアプリケーション開発

Heroku上に構築するWebアプリケーションは「Memcached」でサーバサイドセッションを管理する

Herokuでスタート! はじめてのPaaSアプリケーション開発 第6回


  • X ポスト
  • このエントリーをはてなブックマークに追加

サンプルアプリケーションの入手とローカルでの実行

 それでは実際にHerokuアプリケーションにMemcachedを追加してみましょう。

 本連載で作成しているJavaアプリケーションにサーバサイドセッションを使用する簡単なサンプルを作成したので、これを用いてサーバサイドセッションがどのように機能するのか、またMemcachedを使用しない場合どのような問題が発生するのかを見ていきます。

 サンプルは筆者のGitHubリポジトリの06ブランチで実装されているので、まずはそちらからコードを取得してください。手順は次のとおりです。

$ git fetch origin
$ git co 06 -b origin/06

または、

$ git clone -b https://github.com/shunjikonishi/codezine-sample.git
$ cd codezine-sample

 今回使用するサンプルの実装コードは次の2つです。

 実際の画面はこちらで確認できます。

 このサンプルでは画面上で入力した文字列をサーバサイドセッションに保存し、それを画面に表示しています。また、SessionIdとHeroku上で処理に使用されたDynoの番号も同じく画面に表示しています[1]

 まずはローカルで実行してみます。

# Mac
$ ./run.sh

# Windows
$ run.bat

 ブラウザでlocalhost:5000にアクセスして、以下のことを確認してください。

  • リロードしてもSessionIdが変わらないこと
  • 入力したメッセージが画面に表示されること
  • リロードしてもメッセージが維持されること
  • 別ブラウザで同じ画面を開いた場合にSessionIdが異なること
  • ブラウザが異なる場合、他方のメッセージが表示されないこと

 このように同一ブラウザからの連続するアクセスで、サーバサイドで値を維持することがサーバサイドセッションの機能です。

[1] ローカルで実行した場合、Dynoは「null」と表示されます。

Herokuで動かしてみる

 続いて、このアプリケーションをHerokuで動かしてみます。このサンプルアプリケーションをまだHerokuに登録していない場合は、新たにアプリケーションを作成してからHerokuに06ブランチをpushしてください。

# サンプルアプリケーションをHerokuに登録していない場合
$ heroku create

# 06ブランチをHerokuにpush
$ git push heroku 06:master

 Herokuでもローカル同様にセッションが機能していることが確認できると思います。 1Dynoで動かしている場合、画面上のDynoの項は常に「web.1」となります。

Dynoの数を上げてみる

 次にDynoの数を2に上げてみます。

$ heroku ps:scale web=2

 この状態で再度ブラウザにアクセスすると、今度はセッションに保存したメッセージがほとんどの場合、正しく表示されません。リロードしながら注意深く画面を観察すると、次のことがわかります。

  • Dynoの項が「web.1」になったり「web.2」になったりする
  • Dynoが変わるとSessionIdも変わる
  • SessionIdが変わるとメッセージはもはや保持されない

 リロード時にDynoが切り替わるのは、Dynoが複数ある場合に、リクエストがどちらのDynoで処理されるかがわからないからです。

 今回使用しているフレームワークでは未知のSessionId(他方のDynoで生成されたSessionId)が来た場合は、新たにSessionIdを生成し直しているため、Dynoが切り替わるたびにSessionIdも変わります。

 まれに入力したメッセージが正しく表示されることがあるのは、メッセージをセッションに保存するPOSTリクエスト後のリダイレクト処理がたまたま同じDynoで処理されたためです。

Memcacheirの追加

 次に、複数のDynoでもセッションが正しく動作するようにMemcachedを追加します。

 ここでは一番古参のMemcachied Add-onであるMemcachierを使用します。

$ heroku addons:add memcachier

 追加したら、heroku configコマンドでMemcachier関連の環境変数が追加されていることを確認してください。

$ heroku config
MEMCACHIER_SERVERS:  ...
MEMCACHIER_USERNAME: ...
MEMCACHIER_PASSWORD: ...

 次に、アプリケーション側でサーバサイドセッションとしてMemcachedを使用するように改修する必要があります。今回使用しているフレームワーク「Webapp Runner」は、Herokuの中の人が、ServletをHeroku上で簡単に動かすことを目的として開発しているものです。そのため、起動時の引数に指定するだけでMemcachedを使用するように変更できます。

 Procfileに「--session-store memcache」というオプションを追加してください。

web: java $JAVA_OPTS -jar target/dependency/webapp-runner-7.0.40.0.jar --session-store memcache --port $PORT target/heroku-sample

 この設定により、フレームワークが自動的に環境変数からMECACHIER_XXXXに設定された情報を読みだして使用してくれるようになります。ちなみに、Memcached Add-onとしてMemcachier以外を使用した場合には、手動でMemcachedサーバの情報をheroku configに設定する必要があります。これは最もポピュラーなMemcached Add-onであるMemcachierをWebapp Runnerが特別扱いしているためです。

 修正ができたら、git pushしてもう一度動作を確認してみましょう。

$ git add .
$ git commit -m "Mod Procfile to use memcachier."
$ git push heroku 06:master

 今度はDynoが切り替わってもSessionIdは切り替わらず、メッセージも維持されているはずです。

Dyno数に関する注意

 このテストでは一時的にDyno数を2つに上げていますが、テストが終わったら、必ずDyno数を1に戻してください。上げっぱなしにしていると課金されます。

 Dynoの無料枠は750時間です。1か月は最大でも744時間(24時間×31日)なので、逆にいえば6時間までは2Dynoで動かしても大丈夫です。

ローカルでの開発

 先の変更はProcfileのみだったので、run.sh(run.bat)を用いてローカルで実行する場合に、Memcachedは使用されません。

 ローカルでもMemcachedを試したい場合には、次のようにします。

  • run.sh(run.bat)に「--session-store memcache」を追加する
  • Memcached関連の環境変数をローカルに設定する

 Add-onとして追加したMemcachierをそのまま使用するのであれば、次のようにheroku configから値をコピーすることもできます(Macの場合)。

export MEMCACHIER_SERVERS=`heroku config:get MEMCACHIER_SERVERS`
export MEMCACHIER_USERNAME=`heroku config:get MEMCACHIER_USERNAME`
export MEMCACHIER_PASSWORD=`heroku config:get MEMCACHIER_PASSWORD`

 ただし、この場合Memcachierの物理ホストはUS Eastにあるのでローカル(日本)からのアクセスは非常に遅いです。これを回避しようとするとMemcachedサーバ自体も自前でローカルに立てる必要があるのですが、実際のところはローカル環境での開発でもMemcachedを使用する必然性はほとんどありません。ローカル開発では、従来どおりのオンメモリのサーバサイドセッションをそのまま使うのがよいと思います。

おわりに

 今回はHerokuでの開発を行う上で非常に重要なAdd-onであるMemcachedを紹介しました。次回はもう1つの重要Add-onであるログ関連のAdd-onを見ていきます。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Herokuでスタート! はじめてのPaaSアプリケーション開発連載記事一覧

もっと読む

この記事の著者

小西 俊司(コニシ シュンジ)

株式会社Giveryに所属するエンジニア。CODEプロジェクトというエンジニアの成長を促進するプラットフォーム開発のテックリード。Herokuも使った新しいプロダクトを今秋リリース予定。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/8345 2015/04/13 17:09

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング