会社の技術スタックの中でもアプリケーションサーバまわりの要素技術が曖昧な気がしていて,せっかくなので調べて整理してみようと思った.
まず自分の目の前にある要素はこちら.入社直後は,ぜんぶ「サーバをなんとかするやつ」という印象だった.というわけで入社直後の自分が涙を流して喜ぶような,概観がつかめるエントリを書くことにする.
- PSGI
- Plack
- plackup
- Starman
- Starlet
- Server::Starter
- daemontools
では説明しよう.
TL;DR -- より先に起動する下層から
どちらから説明することもできるが,今回はレイヤー下層から説明する.基本的に,何らかのソフトウェアが別のソフトウェアを起動して,その足元を支え,より抽象的な仕事に集中できるようにする,という関係で成立していることに意識を向けてほしい.
daemontools
-- 汎用スーパーバイザ
daemontools
やsupervisord
,systemd
は,フォアグラウンドで動作するサーバプログラムをデーモン化しサービスとして管理する.また,プロセスが死んだときに再起動を行う死活管理や,標準出力などに掃き出されるログをファイルとして管理し適宜分割するといったログ管理などをとりもつ.
このように他のプロセスを内部で起動して管理するデーモンをスーパーバイザ(デーモン)と呼ぶ.
キーワード: デーモン化,logrotate,シグナル
Server::Starter
-- ホットデプロイ用スーパーバイザ
Server::Starter
は,デプロイによってコードベースが入れ替わりサーバが再起動する際に生じるデッドタイム,つまりリクエストを処理できない時間を無くす,すなわち無停止でデプロイできるようにする.これは先に新たなプロセスを起動してから古いプロセスを終了させるという動作によって実現されている.このような機能をホットデプロイと呼ぶ.
Server::Starter
はstart_server
コマンドで起動するPerlソフトウェアである.
Server::Starter
に対応するには上位層の対応が必須である.なぜならソケットのファイルディスクリプタ等を環境変数を通じて受け渡すからである.下層のdaemontools
等から起動される.
キーワード: ホットデプロイ,ソケット,ファイルディスクリプタ,SO_REUSEADDR
/SO_REUSEPORT
最近だとServer::Starterやdaemontoolsはsystemdの管掌になるかもしれないですね.
参考文献
Starman
/ Starlet
-- PSGIサーバ
Starman
やStarlet
は,PSGI
(後述)に対応しているPerlプログラムをWebアプリケーションとして起動する.別の視点では,Perlで書かれ動作するWebサーバである.このような,ある言語で動作するプログラムを特定の仕様を通じてあるプロトコルに対応させるサーバをアプリケーションサーバと呼ぶ.Starman
やStarlet
はPSGI
という仕様を通じて,HTTPやCGIというインターフェイスとPerlプログラムとを結び付けるPSGI
サーバであると表現する.
PSGI
サーバは直接起動する,または前述したServer::Starter
等のスーパーバイザ,もしくは後述するplackup
,もしくはそれらの組合せによって起動される.
Plack
-- PSGIリファレンス実装
Plack
ライブラリは,Perlによってウェブアプリケーションを書くための枠組みを提供する.Plack
はPerlによる典型的なウェブアプリケーションフレームワーク(WAF)であり,PSGIのリファレンス実装である.開発者は,Plackが提供するモジュールやAPIによりWebアプリケーションを記述することができ,PSGIを直接使ってプログラミングする必要性を最小限に留められる.他言語におけるPlay FrameworkやRailsに対応するソフトウェアである.
PlackアプリケーションをPSGIサーバで立ち上げる方法はplackup
コマンドで統一されており,コマンドラインオプションでPSGIサーバを指示する.このためPlackアプリケーションではstart_server
コマンドでplackup
コマンドを呼び出すという形式をとりがちである.
PSGI
-- アプリケーションインターフェイス
PSGI
は,StarmanやStarletといったPSGIサーバと,ウェブアプリケーションとして振る舞おうとするPerlプログラムとの間を,インターフェイス仕様として定義する.他言語におけるWSGIやRackに対応する概念である.
このようなインターフェイスを呼ぶ一般的な名称を筆者は知らない.
(ユーザのアプリケーション)
PlackなどのPSGI実装の上に,ユーザによるPerlソフトウェアが構築され,Webアプリケーションとして動作する.
個々の説明
PSGI
PSGIはPerl Web Server Gateway Interfaceの略.WebサーバとPerlソフトウェアを結ぶために定義された仕様.PSGIに対応したWebサーバとPSGIに対応したアプリケーションがあれば,これらを結合させてWebアプリケーションにすることができる.
Plack
PSGIに対応した,アプリケーション側のリファレンス実装である.言うなればWAFである.いろいろなミドルウェアが用意されている.リファレンス実装なので,他のPSGIを実装したWAFもある.
補足: PSGIサーバ
WebサーバなどとはCGIやHTTPなどで交信し,PSGI対応アプリケーションとはPSGIで交信することで,両者を仲介するサーバ.ゲートウェイに近い.このためHTTPサーバとしてふるまうものが多い.
以下のページを参考にした.
補足: Plackハンドラ
PSGIサーバとPlackとの橋渡しをするモジュール.
plackup
Plackアプリケーションを起動させるコマンド.Plackの一部として同梱されている.とはいえPSGIサーバがなければPlackアプリケーションは動作しないので,-s
オプションでPSGIサーバを指定する.plackup
への対応,すなわちPlackハンドラはPSGIサーバ側が実装している.おそらくplackup
はモジュール名規約などを用いてPlackハンドラを呼び出している?
補足: preforkモデル
複数同時接続を捌くためのWebサーバの実装モデルの一つであるが,Webサーバである必要はなく,複数同時接続が起こるサーバに共通して適用できるモデル.また複数同時接続をしない場合は考える必要がない概念である.
このモデルでは,親プロセスがリクエストを受け付け,受信したリクエストのレスポンスを子プロセスに任せるというモデルになっている.ここで,子プロセスは特にワーカプロセスと呼ばれる.しかしforkにはメモリコピーのコストがかかり,毎回forkしていてはコストがかかりすぎるので事前にいくつかforkしておき,これを使い回す.この事前にforkされたワーカプロセスの集合を(プロセス)プールと呼ぶことがある.
同時接続を捌くためのモデルとして,他にはマルチスレッドモデルやイベント駆動モデルがある.
以下のページを参照した.
Starman
PSGIサーバでありWebサーバ.preforkモデル.多機能.
Starlet
PSGIサーバでありWebサーバ.preforkモデル.シンプル.
Server::Starter
再起動に伴うリクエストの喪失を防ぐためのホットデプロイを行うためのスーパーバイザデーモン.Server::Starterによるホットデプロイを実施するにはPSGIサーバ側の対応が必要で,StarmanやStarletなどが対応している.また対応さえしていればPSGIサーバでなくともホットデプロイができるようになると思う.再起動時には新たなPSGIサーバを起動し,その後で既存のPSGIサーバを停止させる.
以下のページを参照した.
daemontools
サービス管理用のスーパーバイザデーモンであり,プログラムをデーモン化してくれる.うっかり死んだときに叩き起こす死活管理,ログローテートを行ってくれる. 同じようなソフトウェアとしてsupervisord,systemdなどがある.daemontoolsは1サービス1プロセスとして設定を記述するが,supervisordなどは複数プロセスを割り当てることができるなど,様々な特徴がある.daemontoolsは古くから使われておりノウハウがある状態だが設定が難しいらしい.