【Web初心者】ステートレスとステートフルの違い
本記事では、HTTP通信などを利用していく際に気にかけて置く必要のあるステートフル 、ステートレスのそれぞれの特徴とその違い、向いている使用場面について書いていきます。
ラーメン店でのトッピング注文を例に、ステートレスとステートフルの内容について解説していきます。
ステートレスとは
ステートレスな通信のやり取りの代表例として、私たちが普段からブラウザでWebサイトをなどにアクセスする際に使用するHTTPが挙げられます。
HTTPでは、リクエストとレスポンスの1セットのやりとりが完結された処理であるとみなされ、複数の処理を関連づける仕組みがありません。
このようにステートレスとは、「状態を保存しない」という意味を持っており、ブラウザとサーバ間で1回のリクエスト/レスポンスを行った後に、再度同じブラウザとサーバ間でやり取りを行う場合、前回のやり取りを行ったという記憶をサーバは保持していません。
ステートレスのメリット
ステートレスとは、サーバがクライアントとの通信の履歴を保持していないことを意味しています。
クライアントは自分の通信に必要なデータなどの状態を保持しておき、サーバへリクエストを送るごとに通信に必要な情報を全て送ります。そのため、以下のようなメリットがあります。
サーバの負荷が少ない
サーバが各クライアントからのリクエスト内容を覚えておく必要がないため、単純にその分の負荷が少なくなります。
どのサーバにリクエストを送っても同じレスポンス
複数WebサーバでWebサイトなどを運営している場合でも、クライアント側は毎回全ての情報を詰め込んだ同じリクエストを送信します。
そのため、どのサーバに対してリクエストを送っても必ず同じレスポンスが返ってきます。
下の図に表すように、ステートレスな注文を行う場合には、お客さんが毎回、何のラーメンを頼んだのか、トッピングは何にするのか、という情報を店員に伝えます。
そのため、店員側は注文内容を記憶しておく必要がなく、もらった注文に対して即時にそのラーメンを提供するだけで済みます。
最初に注文した店員さんとは、別の店員さんに注文を行った場合にも、何ラーメンか、というところから始まるので、オーダー内容が確実に伝わります。

ステートレスのデメリット
現在でも広く使用されているステートレスにも、これは不便だと感じるデメリットも存在します。
パフォーマンスの低下
サーバをステートレスにする際に、クライアントは毎回必要な情報を全て送信することとなり、「リクエストで送信するデータ量が増える」「サーバに負荷のかかる認証などの処理を繰り返す必要がある」などの理由により、パフォーマンスに影響を与えます。
全ての情報を毎回送らなければいけない上、ID,パスワードの認証処理などを送った際には、サーバ側は毎回DB(データベース)へ接続しなくてはなりません。
DBへの接続は、一般的に重いものであるため、毎回この工程を踏むとパフォーマンスの低下につながります。
以下の例では、最初のラーメンとトッピングを注文したのちに、再度追加のトッピング(あぶら)を追加したくなった場合には「大ラーメン」から注文し直さなければならず、注文が面倒なことが伺えます。

エラー発生時の対応
ステートレスな通信では、エラー発生時に問題が生じてしまう可能性がございます。
1回目にリクエストを行い、過程で通信エラーなどが発生したとします。その後、クライアント側がリクエストを正常に送れなかったと判断して再度リクエストを送ることになった後、結局1回目のリクエストが成功していた場合には、同じリクエストを2回送ってしまうという問題が発生してしまいます。
サーバ側は、毎回のリクエストに対してレスポンスを送るだけなので、直前にも同じリクエストが来ていたかどうかなどの記録を保持していないために起きてしまう問題です。
ステートフルとは
ステートフルとは、ステートレスとは対照的に「状態を保持している」という意味を持っています。
1回のリクエスト/レスポンスの処理を行なった後、続く処理でも前回の処理の記憶を保持しており、スムーズに一連の処理を続けていくことができます。
また、Amazonなどのショッピングサイトでログイン→購入→ログアウトまでの一連の流れをセッションと呼びます。セッションをスムーズに行うことができる状態をステートフルな状態であるということができます。
ステートフルのメリット
一連の継続する流れを持つステートフルには、ステートレスとは反対のメリットがございます。
通信のパフォーマンスが高い
ステートレスな通信では、通信を1回行うごとにクライアント側が、サーバに対して毎回1から10までの情報を送信しており、データの量が膨大になり通信のパフォーマンスが懸念されています。
反対にステートフルな通信では、セッション中はサーバ側がクライアントの通信の履歴を保持しており、2回目、3回目のリクエストの際にも前回のリクエストを覚えています。
そのため、クライアントは前回送信したデータとの差分データを送信するだけで良くなり、送信するデータ容量が少なくなるのです。

ステートフルのデメリット
非常に便利なステートフルにも、便利な故のデメリットも存在しています。
サーバの負荷が大きい
ステートフルなやり取りを行う際には、サーバがクライアント1つ1つのセッション状態を保持しているため、クライアントの数が増えるに従ってサーバの負荷はどんどん大きくなっていきます。
クライアントの増加に伴って、ステートレスな通信を行うサーバとは比較にならないほどサーバの台数を増やさなければいけない事態に陥ります。
サーバを単純に増加(スケールアウト)できない
ステートフルな通信では、クライアント側の数が増えれば増えるほど、セッション状態を保持するためにサーバの台数が必要になってきますが、不特定多数のクライアント側はリクエストごとに接続するサーバを選択することができません。
そのため、 1回目のリクエストで接続したサーバと2回目に接続したサーバが同じサーバになるとは限りません。2回目のリクエストを異なるサーバに送ってしまうとサーバ側は、1回目と2回目の差分の内容しか受け取れないため、リクエストの内容が理解できず、処理を行うことができません。
そこでサーバ内容の同期を行い、どのサーバでも同様にセッション状態を保持する必要がありますが、サーバ台数が100台、1000台と増えていくと同期させるだけでも相当な負荷となり、不特定多数がアクセスするWebサイトのサーバとしては、ステートフルサーバは現実的ではないと言えます。
最後に
ここまで書いてきたように、ステートレス、ステートフルにはそれぞれメリット、デメリットが存在します。そこを補うようにできている仕組みである、Cookieやセッションについても書いているのでぜひご覧になってみてください。
-
前の記事
【Web初心者】HTTPSの仕組みと安全性 2023.01.18
-
次の記事
【Web初心者】Cookieの仕組み 2023.01.30