nazolabo

フリーランスのWebエンジニアが近況や思ったことを発信しています。

ワンポイントTwelve-Factor App(8) : 並行性

この記事は、The Twelve-Factor Appを補足し、実際に現代的なWebアプリケーションで適用する場合の注意点などを紹介するシリーズです。下記の原文を読んだ上でのワンポイント解説になります。

12factor.net

概要

  • プロセスを並べることによってスケールアウトできるようにする
  • プロセス管理ツールによってプロセスを管理する

これは何を表しているか

「6. プロセス」で紹介した設計に即したプロセスであれば、そのままプロセスを違うコンピューター上で複数動作させても問題なく動作するはずです。これにより、プロセスを増やすだけでスケールアウトできるようになります。

また、アプリケーションが自前でデーモン化したりすると、それを共通の仕組みで管理することが困難になります。systemdのようなOSのプロセス管理ツールに任せる・任せられる構成にすることによって、アプリケーションはアプリケーションの動作のみに専念でき、どのような環境でも安全に再起動することが可能になります。

実際に運用する場合

autoscalingのような、自動でコンピューター数が増えるような構成にしたい場合、プロセスの数が不定になり、いつプロセスが増減するかもわからないので、このような構成にしておく必要があります。構成の詳細については他項での説明の通りになります。

通常のWebアプリケーションを通常通りに作成し、ステートレスかつシェアードナッシングな構成になっていれば、そのままプロセスを並べることで並列性を上げることが可能です。とはいえプロセス内の速度は書いたコードに依存しますので、並べられるからといって最適化のようなものが不要になるわけではありません。また、大規模になると「アプリケーションのプロセスは増えるが、それらがアクセスする単一のストレージ(特にDB)が限界になる」という現象が発生します。N+1のようなものには特に注意しましょう。

非Docker環境であれば、開発環境ではForemanのようなツール、本番ではsystemdなどでプロセスを管理することで、アプリケーション側からすると同一の方法でプロセスを管理することができます。Docker環境であれば、開発環境はdocker-compose、本番はECSやk8sといったものを使うことになると思います。

ECSやk8sのようなコンテナオーケストレーションツールでない本番環境の場合、シグナルによってプロセスの再起動が入る場合があります。この際、再起動時にリクエストが来てもエラーにならないように緩やかに再起動する、いわゆるGraceful Restartに対応できているか事前に確認しておきましょう。コンテナオーケストレーションツールの場合でも、リクエストを止める時間とプロセスがタイムアウトする時間を合わせないとユーザーからはエラーレスポンスに見える可能性があります。こちらも必ず確認しておきましょう。