非同期実行(共通編)
================================================================================

.. only:: html

 .. contents:: 目次
    :depth: 3
    :local:

Overview
--------------------------------------------------------------------------------

| 本ガイドラインでは、クラウド環境における非同期実行について、クラウドベンダに依存しない共通的な事項を説明する。
|
| システムによっては、特定のタイミングで大量のトラフィックが発生し、リソースへの負荷が増大するような場合が存在する。
| 航空チケット予約システムを例に挙げると、大型連休等の高需要な日程のチケットの予約開始日などは、一時的に大量の予約注文が発生する事が想定される。
| 以降で説明する処理方式は、そのような状況においても滞りなくユーザへレスポンスを返す事を目的としている。

処理方式概要
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

| 本ガイドラインで例に挙げる航空チケット予約システムでは、チケット予約処理時に、ユーザの顔写真解析等の所要時間を要する主処理を行う事を想定している。
| 本方式では、先述した大量の予約注文が発生する状況においても、ユーザへのレスポンスタイムを確保するため、比較的負荷の軽い予約受付処理と、処理時間を要する主処理を切り離して実行する。
| 予約受付処理が完了した段階で、ユーザに予約受付完了のレスポンスを返し、ユーザの待ち時間を短く抑える。その後、主処理は非同期にバックグラウンドで実行され、処理完了後改めてユーザへ予約完了通知を送信する。

処理方式イメージ
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

本ガイドラインで紹介する非同期実行方式のイメージを示す。

.. figure:: ./imagesAsynchronousProcessing/AsynchronousProcessingOverview.png
   :alt: Screen image of asynchronous processing.
   :width: 100%

上記イメージでは、アプリケーションサーバはフロントサーバとバックサーバに分けた構成としている。
フロントサーバには予約受付を行うアプリケーションを配置し、バックサーバには主処理を行うアプリケーションを配置する。

クラウド環境では、リクエスト数の増減やインスタンスの状態に応じてリソースのオートスケーリングが可能だが、
データベースなどのオートスケーリング不可なリソースがボトルネックとなり、性能問題となる恐れがある。
本方式では、予約受付処理と主処理とをキューサービスを介し非同期に実行させる事で、
主処理で長時間を要しても、クライアントへのレスポンスに影響が出ないようにしている。

.. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}|
.. list-table::
   :header-rows: 1
   :widths: 10 90

   * - 項番
     - 説明
   * - | (1)
     - | フロント側アプリケーションは、クライアントからのリクエストを受け付ける。
   * - | (2)
     - | フロント側アプリケーションは、キューサービスに主処理の実行要求メッセージを送信し、クライアントにレスポンスを返却する。
   * - | (3)
     - | バック側アプリケーションは、キューサービスから主処理の実行要求メッセージを受信し、フロント側アプリケーションとは非同期に主処理を実行する。
   * - | (4)
     - | バック側アプリケーションは、通知サービスに処理完了通知を依頼する。
   * - | (5)
     - | 通知サービスは、クライアントに処理完了通知を送信する。

.. _asynchoronous-processing-front-label:

フロントサーバの処理方式
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

フロントサーバの処理方式について説明する。フロントサーバでは、バックサーバへの処理要求メッセージを送信する。

メッセージ送信
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

| フロントサーバからバックサーバへの処理要求は、クラウドベンダが提供するメッセージングサービスのキューを介して行う。
|
| フロントサーバは、キューに対してメッセージを同期送信する。
| 送信完了後、クライアントに処理を受け付けた旨のレスポンスを返却する。
|
| 本ガイドラインでは、メッセージ送信のインタフェースにSpring Frameworkが提供するインタフェースを使用する事を前提としている。実装には、クラウドベンダーが提供するライブラリを利用する。
| なお、クラウドベンダーがJMS互換のメッセージングをサポートしている場合は、|base_framework_name| のメッセージング連携のノウハウを活用できる為、|base_framework_name| Development Guideline `メッセージを同期送信する場合 <https://macchinetta.github.io/server-guideline/1.7.0.RELEASE/ja/ArchitectureInDetail/MessagingDetail/JMS.html#jmsoverviewsyncsend>`_ を参照されたい。


メッセージに持たせる情報
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

送信するメッセージに持たせる情報を以下に例示する。

 * **主処理に必要となる情報**

   チケット予約の主処理を行うにあたり必要となる、予約チケット情報、航路情報、ユーザ情報などの業務的な情報。

 * **メッセージの識別子**

   メッセージを一意に特定できるメッセージID。処理のトレーサビリティを確保する為に利用する。
   採用するメッセージングサービスにて一意なIDが採番される場合(例:Amazon SQSのSQSMessageIDなど)は、そちらを利用すると良い。

   .. note::

      メッセージ送信の失敗時に、前回送信と同一のメッセージIDでリトライ送信を行いたいなど、
      メッセージングサービスにて採番されたIDでは実現できない要件がある場合は、
      アプリケーションにて独自に採番する方式を検討されたい。

メッセージ送信に関連するエラー処理
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

| メッセージ送信を行う処理を設計する際は、メッセージ送信前後で例外が発生する場合について検討する必要がある。
| メッセージ送信に関連するエラーとしては、以下のような観点が考えられる。

 - メッセージ送信後の処理で業務エラーが発生した場合
 - メッセージ送信後の処理でシステムエラーが発生した場合
 - メッセージ送信先のキューに異常が発生した場合

| 特に、メッセージ送信後に例外が発生した場合に、フロントサーバ側とバックサーバ側で処理の整合性が保たれるよう、例外処理を設計すること。

.. note::

   フロントサーバとバックサーバのデータ整合性を保つための対処法としては、戻し更新処理の実装や、運用対処によるデータ修正などが考えられる。

.. _asynchoronous-processing-back-label:

バックサーバの処理方式
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

バックサーバの処理方式について説明する。バックサーバでは、フロントサーバからの処理要求メッセージの受信、要求に基づく主処理およびクライアントへの処理完了通知を行う。

メッセージ受信
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

| フロントサーバからの処理要求を、メッセージングサービスのキューを介して受信する。
|
| メッセージの受信は非同期にて行い、受信後の処理は性能要件に応じてマルチスレッドで高速化を図る。
| ただし、厳密な順序性が求められる要件の場合は、順序性が担保されている製品を使用するか、アプリケーション側で順序性を担保するよう設計すること。

.. warning::

  Amazon Web Serviceが提供するAmazon SQSの\ `標準キュー <http://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues.html>`_\のように、メッセージングサービスによっては順序性を担保していない。厳密な順序性が求められる場合は注意されたい。

| 本ガイドラインでは、メッセージ非同期受信のインタフェースにSpring Frameworkが提供するインタフェースを使用する事を前提としている。実装には、クラウドベンダーが提供するライブラリを利用する。
| なお、クラウドベンダーがJMS互換のメッセージングをサポートしている場合は、|base_framework_name| のメッセージング連携のノウハウを活用できる為、|base_framework_name| Development Guideline `メッセージを非同期受信する場合 <https://macchinetta.github.io/server-guideline/1.7.0.RELEASE/ja/ArchitectureInDetail/MessagingDetail/JMS.html#jmsoverviewasyncreceive>`_ を参照されたい。


メッセージのトレース
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

メッセージのトレーサビリティ向上のために、各ログにリクエスト単位で一意なメッセージID等をTrackIDとして出力させることを推奨する。
TrackIDは、logbackのMDCを利用してログ出力する事ができる。TrackIDの利用方については、|base_framework_name| Development Guideline `ログの出力内容 <https://macchinetta.github.io/server-guideline/1.7.0.RELEASE/ja/ArchitectureInDetail/GeneralFuncDetail/Logging.html#id3>`_ を参照されたい。

処理完了通知
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

| 非同期に実行した主処理が完了した後、処理の完了をクライアントに通知する。
| 通知先が個人ユーザであれば、メールやモバイル端末へのSMS、プッシュ通知等を用いる。システム向けであれば、HTTPやメッセージング等が選択肢となる。
| 必要に応じて、クラウドベンダが提供するサービスを利用して通知すると良い。

.. note::

  非同期処理の内容によっては、処理完了をユーザに通知するのではなく、ユーザが能動的に処理結果確認画面にアクセスして確認する方式も考えられる。実行する処理内容を考慮し、完了通知の要否を検討されたい。

バックサーバのエラー処理
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

| フロントサーバのメッセージ送信と同様に、バックサーバについても、エラー処理の検討が必要である。
| 本ガイドラインで紹介する方式では、以下のような観点が考えられる。

- メッセージ受信処理でシステムエラーが発生した場合
- メッセージ受信後の主処理で業務エラーが発生した場合
- メッセージ受信後の主処理でシステムエラーが発生した場合
- クライアントへの処理完了通知処理にてシステムエラーが発生した場合

.. warning::

   本来フロントサーバで行っていた業務処理のうち、高負荷が想定される処理をバックサーバに切り出す場合について、
   フロントサーバ、バックサーバの両方でデータ更新が行われていると、エラー発生時にデータの不整合が発生する。
   必要に応じて戻し処理や運用対処でのデータ修正等を検討されたい。また、採用するクラウドベンダがメッセージのトランザクション機能を提供している場合もある為、併せて検討されたい。

How to use
--------------------------------------------------------------------------------

メッセージングサービスの利用
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

クラウドベンダが提供するメッセージングサービスを利用し、非同期処理を実装する。

Amazon Web Service
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

クラウドベンダとしてAWSを使用する場合の非同期処理の実装例については、
:doc:`../../AWSCollaboration/Queuing/AsynchronousProcessing`
を参照されたい。

.. raw:: latex

   \newpage