非同期処理 - ユーザー画面はレスポンス良くしたい(1)
Webアプリケーションにおける非同期処理 - 非同期処理の利点
ブログサイトのようなアプリケーションを考えてみましょう。ブログ編集用の画面にある「更新」ボタンを実装していたとします。このとき、実際にブログ記事を更新するために内部では、HTML、CSS、JavaScriptなどを含めてアップデートすることになります。もっと具体的に考えてみると、複数のWebサーバーがあれば、それら全てを更新しなければなりません。
全てのWebサーバーの更新が完了した際にユーザーに「更新が完了しました」画面を表示するように実装したとすると、ボタンをクリックしてから画面が遷移するまでに5分かかってしまうかもしれません。これでは大変不便です。
このようなユースケースでは、「更新」ボタンクリックイベントに更新完了までの全処理を実装するのではなく、リクエストの受付だけを行うことにします。ユーザーへは、リクエストの受付完了のレスポンスをすぐに返せるようにして、実際の更新処理はバックエンドのプログラムに任せます。こうすることで、ユーザーを待たせることがなくなり、ユーザー側の負担を軽減させることができます。
後者の方法は、リクエストの受付時に全ての更新を完了させるわけではないため、非同期的に処理を行っています。前者の方法、全ての更新完了までレスポンスを返さない仕様は、非同期処理に対して、同期的な処理を行っていると言えます。
同期処理では、図4のようにユーザーが「更新」ボタンをクリックしたことを受け、フロントエンドシステムが各バックエンドシステムに更新を要求します。全てのバックエンドシステムの更新が完了したのち、フロントエンドシステムはユーザーにレスポンスを返します。ユーザーはこの時点で「更新が完了しました」という画面を目にすることになります。
一方、非同期処理の場合、図5のようにユーザーが「更新」ボタンをクリックしたのち、フロントエンドシステムがバックエンドシステムに処理を引き渡した時点で、バックエンドシステムの処理完了を待たずにユーザーにレスポンスを返します。
このようなアプリケーションでは、非同期処理を活用することで、同期処理に比べてユーザーの待ち時間を大きく短縮することができます。
キュー
図5において、「リクエストキュー」という言葉が登場してきました。これは、フロントエンドから送られてきたリクエストをキューイング(順番待ち)しておく領域になります。
キューは、プログラムのデータ構造としてもお馴染みかもしれません。キューの実現にあたっては、さまざまなライブラリやフレームワークが提供されています。
インフラ設計の観点において図5の例では、リクエストキューを挟まず、フロントエンドからランダムにバックエンドのサーバーを選んで、リクエストを送信してもよかったでしょう。
しかし、サーバー単体ではダウンする可能性があるので、最悪の場合、リクエストが消失する事態を招きます。また、リクエストがあるサーバーに集中する、過負荷のような状況が発生する可能性もあります。
このような場合にキューを用いることで、リクエスト処理が完了するまでバックエンドシステムが再施行する猶予を設け、過負荷の際の調整弁としてバックエンド側の負荷を軽減させることができます。
