SHOEISHA iD

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

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

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

構築・運用の必須知識! Herokuアプリケーションの実行プラットフォーム「Dyno」を徹底的に理解する

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


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

Dynoと再起動

 Dynoが再起動するタイミングには、デプロイや環境変数の変更などがあります。以下に、Dynoが再起動する主なケースを列挙します。

  • デプロイ(git push)
  • 環境変数の変更(heroku config:set)
  • Add-onの追加・削除(heroku addons:add、heroku addons:remove)
  • コマンドによる手動再起動(heroku ps:restart)
  • 起動時間が24時間を超えたDynoのサイクリング
  • DynoManagerによる異常検知

 他はともかく、起動時間が24時間を超えたDynoが定期的に再起動されることを不思議に思う方がいるかもしれません。

 これはHerokuの特徴的なリスクヘッジ戦略によるものです。

 どんなハードウェアでもいつかは必ず壊れます。このリスクを回避するために、オンプレミスでは定期的にハードのリプレースを行ったりするわけですが、ではどの程度使ったらリプレースするのが適切でしょうか? 2年? 1年? それとも半年でしょうか?

 この疑問に正解はありませんが、どんな選択をしたにせよ、リプレースの前にハードが故障するリスクはあるわけです。そしてこの問いに対するHerokuの回答は「1日」です。

 そんな選択は、実際に物理的なハードウェアを用意するオンプレミスでは絶対にできません。大規模にホストを運用するPaaSならではの戦略といえます。

 もちろん、この戦略にはトレードオフがあります。一番大きな注意点は、いつサーバが再起動してもアプリケーションが不整合を起こさないようにする。言い換えれば、アプリケーションをステートレスに保つ必要があるという点です。

 具体的にはOnMemorySessionやStickySession(コラムを参照)を、Herokuアプリケーションで使ってはいけません。

 この制約には不自由を感じる人もいるかもしれませんが、リリースサイクルの短くなっている近年のWebアプリケーションでは、アプリケーションをステートレスに保つことは、どんな環境であっても常に心がけるべき習慣であると、筆者は考えています。その立場から言うと、Herokuがステートレスであることを強要する点はむしろメリットの1つです。

OnMemorySessionとStickySession

 OnMemorySessionとは、ServletAPIにあるようなセッション情報をメモリ上に保持する仕組みのことです。 この仕組みには次のような問題があります。

 

  • 複数サーバ構成の場合にセッション情報を共有できない
  • うかつに再起動できない

 前者の問題の解決策の1つがStickySessionで、これはLoadBalancerが同一ブラウザからのリクエストを常に同じホストに回すことで、複数のサーバが同じセッション情報を保持する必要性自体をなくすというものです(AWSのELBではStickySessionを使うことができます)。

 しかし、StickySessionを使った場合でも、後者の問題は解決しません。このため、OnMemorySessionを使ったシステムでは、リリース時などに毎回現在接続中のユーザの状態に気を使う必要があります(この問題の典型的な解決策は利用者の少ない真夜中にリリースすることです!)。

 これらを排除したHerokuアプリケーションでは、いつでもコマンド1つで新しいバージョンをリリースできることも素晴らしい点です。

preboot

 再起動に関して、Dynoを2台以上起動しているアプリケーションではprebootという機能を使うことができます。prebootを有効にするには、コンソールから次のコマンドを実行します。

heroku features:enable preboot

 prebootを使わない場合の再起動のシーケンスは次のようになります。

  1. ルーティング停止
  2. 旧Dynoシャットダウン
  3. 新Dyno起動
  4. ルーティング再開

 これがprebootを使用した場合は次のように変わります。

  1. 新Dyno起動
  2. ルーティング切り替え
  3. 旧Dyno停止

 prebootを使わない場合、再起動中のリクエストはルーターのキューに溜まることになるので、その間のリクエストでは若干の遅延が発生しますが、prebootを使用することでリクエストの停滞がなくなります。

 可能であれば、常にprebootを使用することをお勧めします。

prebootの注意点

 画面の修正やサーバーサイドのちょっとしたロジックの変更などの場合、prebootはとても有益ですが、データベースのスキーマ変更を伴うようなリリースでは、prebootは実質的に機能しません(新バージョンのアプリが旧スキーマで動いてもまずいし、旧バージョンのアプリが新スキーマで動いてもまずいため)。

 この場合は、メンテナンスモードを利用して一切のユーザアクセスを遮断した上で、DBの変更と新バージョンのリリースを同時に行う必要があります。

 prebootの場合はリリースコマンド(git push)の実行から、実際にアプリが切り替わるまでに若干のタイムラグがあるので、事故を防ぐため、一時的にprebootを無効化することが推奨されています。

 

 以上、今回はHerokuの中心的概念であるDynoについて、かなり細かいところまで解説しました。次回はよく使うHerokuコマンドについて解説する予定です。

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

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

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

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

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング