応用情報技術者 2013年 春期 午後 問08
プロビジョニングシステムの設計に関する次の記述を読んで、設問1~4に答えよ。
L社では、新規に仮想サーバのホスティングサービスを開始することになった。このサービスでは、利用者が任意のタイミングで仮想サーバの作成、起動、停止及び削除を行うことができるプロビジョニングの機能を提供する。仮想サーバのホスティングサービスのシステムの全体構成を図1に示す。
仮想サーバのホスティングサービスのシステムは、仮想サーバシステムと、仮想サーバホスティングシステムから構成される。
仮想サーバシステムには市販の製品を用いる。仮想サーバ管理 API は、仮想サーバシステムと他のシステムとの連携動作を実現するために用いる API である。仮想サーバホスティングシステムは、これを呼び出すことで、仮想サーバの制御を行う。
仮想サーバホスティングシステムは、管理ポータルサイトとプロビジョニングシステムから成り、これらはL社が新規に開発する。
管理ポータルサイトは、仮想サーバの作成、起動、停止及び削除を指示したり、現在の状態を確認したりする、利用者向けのポータルサイトである。
プロビジョニングシステムは、管理ポータルサイトからのメッセージに応じて仮想サーバ管理 API を呼び出すことで、仮想サーバの作成、起動、停止及び削除を行うシステムである。

〔仮想サーバ管理APIの仕様〕
仮想サーバ管理 API の仕様上、仮想サーバには、未作成中、作成中、起動中、起動停止中、停止、削除中及び削除済の状態がある。仮想サーバ管理 API の仕様を表1に示す。

仮想サーバ管理 API は、呼び出された API の処理が完了した時点で応答を返す。例えば CreateServer を実行すると、サーバの作成が完了した時点で、呼出し側にサーバIDを返す。
仮想サーバ管理 API は、複数のスレッドから同時に呼び出すことで並列に動作させることができるが、同一のサーバIDに対する API を複数のスレッドから同時に呼び出すと、API がエラーになることがある。同一のサーバIDに対する API 呼出しの排他制御は、API を呼び出すアプリケーションで行う必要がある。
〔プロビジョニングシステムの設計〕
仮想サーバホスティングシステムの開発に当たって、プロビジョニングシステムの設計を行った。
まず、プロビジョニングシステムの管理下に置く仮想サーバについて、プロビジョニングシステム上での状態遷移の仕様を定義した。仮想サーバの状態遷移は、仮想サーバごとに独立に制御する。二つの仮想サーバの状態遷移の仕様を図2に示す。
仮想サーバの状態は、管理ポータルサイトからのメッセージの受信や、処理完了の検出などのイベントが発生したときに遷移する。
なお、プロビジョニングシステム上での仮想サーバの状態の定義は、仮想サーバ管理 API の仕様上の定義と必ずしも一致している必要はないが、ここでは API を利用しやすくするために、同じ定義を用いることにした。

次に、図2の状態遷移の仕様を実現するための、プロビジョニングシステムの構成を検討し、図3にまとめた。
プロビジョニングシステムの管理下に置く仮想サーバの状態は、仮想サーバのサーバIDなどの情報をあわせてデータベース上に格納しておく。イベント発生時の状態遷移は、メッセージキューとメッセージハンドラを用いて実現する。
管理ポータルサイトから送信されたメッセージは、メッセージキューに格納される。メッセージキューに格納されたメッセージは、ディスパッチャが順次取得する。ディスパッチャは、取得したメッセージの内容と、仮想サーバの現在の状態に応じて、適切な種類のメッセージハンドラを生成する。生成したメッセージハンドラは、それぞれ独立した別々のスレッドで動作させる。メッセージキューに複数のメッセージが存在した場合は、メッセージごとに別々のスレッドを生成し、それぞれのメッセージハンドラを並列に動作させる。
メッセージハンドラは、データベースを更新し、仮想サーバ管理APIを呼び出す。メッセージハンドラの定義を表2に、ディスパッチャによるメッセージハンドラの選択ルールを表3に示す。



例えば、ある仮想サーバの現在の状態が“起動”のときにサーバ停止のメッセージを受け取ると、ディスパッチャは表3のルールに従って、Stoppingのメッセージハンドラを生成する。Stoppingのメッセージハンドラでは、表2の定義に従って、データベース中の仮想サーバの状態を“停止中”に変更した後、仮想サーバ管理APIのStopServerを呼び出す。メッセージハンドラは、メッセージハンドラの処理完了のイベントを発生させる必要がある場合に限り、呼び出したAPIの処理終了後に処理完了メッセージを生成し、メッセージキューに格納する。
〔仮想サーバ削除時の自動停止機能の仕様変更〕
仮想サーバの状態が“起動”のときに、サーバ削除のメッセージを受信した場合は、メッセージハンドラが StopServer の API を呼び出した後、自動的に状態遷移して、続いて DeleteServer の API が呼び出されるようにすることで、サーバを削除できるように仕様を変更することにした。このとき、(i)サーバ停止とサーバ削除の二つのメッセージをメッセージキューに格納するだけだと、意図した結果にならないことがある。そこで、“停止・削除中”の状態を新設することにした。
変更後の状態遷移では、仮想サーバの状態が“起動”のときにサーバ削除のメッセージを受け取ると、仮想サーバは“停止・削除中”の状態に遷移し、StopServer の API が呼び出される。StopServer が完了すると、自動的に“削除中”の状態に遷移し、DeleteServer の API が呼び出される。
仕様を変更するために、表2と表3について、(1)〜(3)の修正を加えた。
(1) 表2に、StopDeleting の行を追加する。追加する内容を表4に示す。
(2) 表3に、“停止・削除中”の列を追加する。追加する内容を表5に示す。
(3) 表3中の仮想サーバの状態が“d”で、メッセージの種類が“e”の箇所のメッセージハンドラ名を、“f”に変更する。

設問1:
表2及び表3中のa〜cに入れる適切な字句を答えよ。
模範解答
a:停止
b:Starting
c:Deleting
解説
解答の論理構成
-
a の決定
- 表2「Created」の説明文は “仮想サーバの状態変更内容” を記載しています。
- 図2の状態遷移では “作成中” から “処理完了” イベントで “停止” へ遷移します。
“作成中 →(処理完了)→ 停止”
- よって “Created” ハンドラの新しい状態は “停止” になります。
- したがって a = 停止 です。
-
b の決定
- 表3「サーバ起動」行を確認します。
- “サーバ起動” メッセージは “停止” 状態のときだけ受け入れられる仕様です(図2および API 仕様より)。
- “停止” → “起動中” への遷移を担うのは表2で “起動中” に変更し StartServer を呼び出す “Starting” ハンドラです。
- したがって b = Starting です。
-
c の決定
- 表3「サーバ削除」行を確認します。
- “停止” 状態で “サーバ削除” メッセージを受信した場合、図2では “停止” → “削除中” へ遷移します。
- “削除中” への遷移と DeleteServer 呼び出しを行うのは表2で定義されている “Deleting” ハンドラです。
- したがって c = Deleting です。
誤りやすいポイント
- CreateServer 完了後の状態を “起動” と誤解する
→ API 仕様には「CreateServer は仮想サーバを作成し…」としか書かれておらず、自動起動は行いません。図2も “停止” を示しています。 - “サーバ起動” のハンドラを “Ready” と混同する
→ “Ready” は処理完了メッセージを受け取った後に “起動” に確定させるハンドラであり、起動要求そのものを処理するのは “Starting” です。 - “サーバ削除” 時に StopServer が必要と考え “c” に “Stopping” を入れてしまう
→ “停止” 状態からは直接 “削除中” へ遷移できるため DeleteServer を呼び出す “Deleting” が正解です。
FAQ
Q: CreateServer が返すサーバIDはいつデータベースに登録されますか?
A: “Creating” ハンドラが CreateServer 呼び出し後に処理完了メッセージを送信し、次の “Created” ハンドラが走った段階で “停止” 状態として登録されます。
A: “Creating” ハンドラが CreateServer 呼び出し後に処理完了メッセージを送信し、次の “Created” ハンドラが走った段階で “停止” 状態として登録されます。
Q: 同じサーバIDに対して並列にメッセージハンドラが生成されるとどうなりますか?
A: 仮想サーバ管理 API の仕様に「同一のサーバIDに対する API 呼出しの排他制御は、API を呼び出すアプリケーションで行う必要がある」とあります。したがってプロビジョニングシステム側で排他機構を実装しないとエラーになります。
A: 仮想サーバ管理 API の仕様に「同一のサーバIDに対する API 呼出しの排他制御は、API を呼び出すアプリケーションで行う必要がある」とあります。したがってプロビジョニングシステム側で排他機構を実装しないとエラーになります。
Q: “処理完了” メッセージを送らないハンドラはありますか?
A: 表2で “する/しない” と明示されており、Err ハンドラは “しない” です。API 呼出しを伴わない、またはエラー処理専用のハンドラで送信不要な場合に該当します。
A: 表2で “する/しない” と明示されており、Err ハンドラは “しない” です。API 呼出しを伴わない、またはエラー処理専用のハンドラで送信不要な場合に該当します。
関連キーワード: 状態遷移, 非同期処理, 排他制御, API呼び出し
設問2:
表2中の①〜⑦について、処理完了メッセージを生成し、メッセージキューに格納するメッセージハンドラはどれか、①〜⑦の番号で全て答えよ。
模範解答
②、④、⑥
解説
解答の論理構成
-
処理完了メッセージが必要となる条件
- 【問題文】「メッセージハンドラは、メッセージハンドラの処理完了のイベントを発生させる必要がある場合に限り、呼び出したAPIの処理終了後に処理完了メッセージを生成し、メッセージキューに格納する。」
- すなわち、次の状態遷移を“自動で”発生させる必要があるかどうかが判断基準です。
-
“次の状態遷移”が必要なメッセージハンドラ
- Starting:状態を“起動中”に変更し【表2】「StartServer」を呼び出す。完了後は“起動”へ遷移させる必要があるため、②は「する」。
- Stopping:状態を“停止中”に変更し【表2】「StopServer」を呼び出す。完了後は“停止”へ遷移させる必要があるため、④は「する」。
- Deleting:状態を“削除中”に変更し【表2】「DeleteServer」を呼び出す。完了後は“削除済”へ遷移させる必要があるため、⑥は「する」。
-
“次の状態遷移”が不要なメッセージハンドラ
- Created・Ready・Stop・Deleted は「処理完了」メッセージを受け取って呼び出されるハンドラです。すでに完了イベントが到達しているため、さらに処理完了メッセージを送ると無限ループになります。よって①・③・⑤・⑦は「しない」。
-
結論
- 処理完了メッセージを送信する番号は ②、④、⑥ です。
誤りやすいポイント
- 「CreateServer は完了してから応答を返す」ため、Creating が即座に“停止”へ遷移できると誤解し、①も「する」と答えてしまう。
- Ready・Stop・Deleted も API を呼び出さないので“暇だから送る”と考え、③・⑤・⑦を「する」としてしまう。
- 「_中」状態=必ずメッセージ送信、と機械的に覚えて②④⑥以外も選んでしまう。
FAQ
Q: API が完了してから応答を返すなら、すべてのハンドラで処理完了メッセージは不要では?
A: API が返る時点で「対象サーバの操作」は終了していますが、プロビジョニングシステム内部の状態遷移をもう一段進める必要があるケース(②④⑥)だけは完了メッセージで次のハンドラを起動します。
A: API が返る時点で「対象サーバの操作」は終了していますが、プロビジョニングシステム内部の状態遷移をもう一段進める必要があるケース(②④⑥)だけは完了メッセージで次のハンドラを起動します。
Q: Created で状態を“停止”に変えればメッセージ不要では?
A: Created は “処理完了”メッセージを受け取って起動するハンドラです。呼び出し元(Creating)がすでに完了メッセージを発行しているため、二重に送る必要がありません。
A: Created は “処理完了”メッセージを受け取って起動するハンドラです。呼び出し元(Creating)がすでに完了メッセージを発行しているため、二重に送る必要がありません。
Q: StopDeleting 追加後も判断基準は変わりますか?
A: 変わりません。StopDeleting は StopServer 完了後に「Deleting」を起動させる必要があるので、同様に“する”となります。
A: 変わりません。StopDeleting は StopServer 完了後に「Deleting」を起動させる必要があるので、同様に“する”となります。
関連キーワード: 状態遷移, メッセージキュー, 非同期処理, API 呼び出し, 排他制御
設問3:
本文中の下線(i)について、意図した結果にならない理由を、図2を参考に仮想サーバの状態と送信されるメッセージについて言及し、40字以内で述べよ。
模範解答
仮想サーバの状態が“停止”になる前にサーバ削除のメッセージが送信されるから
解説
解答の論理構成
- 下線部は「サーバ停止とサーバ削除の二つのメッセージをメッセージキューに格納するだけだと、意図した結果にならない」と述べています。
- その理由は、【問題文】の「メッセージキューに複数のメッセージが存在した場合は、メッセージごとに別々のスレッドを生成し、それぞれのメッセージハンドラを並列に動作させる。」という仕様により、
• “サーバ停止”メッセージ(Stopping ハンドラ)と
• “サーバ削除”メッセージ(Deleting ハンドラ)
が同時並行で処理され得る点にあります。 - 図2の状態遷移では、削除要求が有効になるのは仮想サーバが“停止”になってからです。しかし並列実行のため、「停止処理中」に “削除” ハンドラが先に動くと、
• 仮想サーバはまだ“起動”または“停止中”であり
• 表3のルール「サーバ削除 × “起動”=Err」「サーバ削除 × “停止中”=Err」に該当し、APIエラーになります。 - よって「仮想サーバの状態が“停止”になる前にサーバ削除のメッセージが送信されるから」という解答となります。
誤りやすいポイント
- 同期的に順番どおり処理されると思い込み、並列スレッドによる競合を見落とす。
- 「停止中」は“停止”とは別状態であることを無視し、削除が許可されると誤解する。
- 表3の“Err”セルの意味を読み飛ばし、APIが成功するケースだと勘違いする。
FAQ
Q: 停止と削除のメッセージを連続送信しても、常に停止→削除の順序で処理されないのはなぜですか?
A: メッセージキューに投入された順序ではなく、別々のスレッドが並列実行されるため、CPUスケジューラ次第で削除ハンドラが先に動く場合があります。
A: メッセージキューに投入された順序ではなく、別々のスレッドが並列実行されるため、CPUスケジューラ次第で削除ハンドラが先に動く場合があります。
Q: “停止中”のときに削除 API を呼ぶと必ずエラーですか?
A: はい。表3では「サーバ削除 × 停止中=Err」、表1でも “停止” 以外で DeleteServer を呼ぶとエラーになると明示されています。
A: はい。表3では「サーバ削除 × 停止中=Err」、表1でも “停止” 以外で DeleteServer を呼ぶとエラーになると明示されています。
Q: “停止・削除中”状態を導入すると何が解決しますか?
A: 先に StopServer を完了させてから自動的に DeleteServer を呼び出す単一ハンドラにでき、並列競合を排除できます。
A: 先に StopServer を完了させてから自動的に DeleteServer を呼び出す単一ハンドラにでき、並列競合を排除できます。
関連キーワード: 状態遷移, メッセージキュー, 並列処理, 排他制御, APIエラー
設問4:〔仮想サーバ削除時の自動停止機能の仕様変更〕について、(1)、(2)に答えよ。
(1)状態遷移図に“停止・削除中”の状態を追加し、状態遷移図を完成させよ。
模範解答

解説
解答の論理構成
- まず、追加するメッセージハンドラ StopDeleting の役割を把握します。問題文には
「仮想サーバの状態が“起動”のときにサーバ削除のメッセージを受信した場合は、メッセージハンドラが StopServer の API を呼び出した後、自動的に状態遷移して、続いて DeleteServer の API が呼び出されるようにする」
とあります。StopDeleting は “StopServer を呼び出し、処理完了後に DeleteServer へバトンタッチする” ための専用ハンドラです。 - StopDeleting を表2に追加すると、対応する遷移先状態として “停止・削除中” が必要になります。これは「“停止・削除中”の状態を新設することにした」という仕様変更により決定されます。
- 表3の行・列を点検すると、(i) 以前は “起動 × サーバ削除” のセルに Err が入っており、削除要求をエラーにしていました。今回の仕様変更はまさにこの箇所を置き換えるものなので、
• 仮想サーバの状態: “起動”
• メッセージの種類: “サーバ削除”
• メッセージハンドラ名: “StopDeleting”
へ修正します。設問(3)の空欄は従って d=起動, e=サーバ削除, f=StopDeleting です。 - 表2・表3の他のセルは従来仕様と衝突しないため変更不要です。なお (1) の空欄 a は CreateServer 処理完了後の安定状態なので “停止”、(2) の b は “停止” から起動要求を受けた際のハンドラで “Starting”、(2) の c は “停止” から削除要求を受けた際のハンドラで “Deleting” となります。
誤りやすいポイント
- “停止中” に対しても StopDeleting を適用してしまう
→ StopServer が二重発行となり、問題文「同一のサーバ ID に対する API 呼出しの排他制御」を破ってしまいます。 - “停止・削除中” の追加だけで満足し、表3の Err セルを修正し忘れる
→ ディスパッチャが StopDeleting を生成できず、新仕様が動きません。 - StopDeleting で DeleteServer を直接呼び出すと誤解する
→ StopDeleting は StopServer を呼び出し「処理完了メッセージの送信: する」として次の Deleting を誘発する設計です。
FAQ
Q: StopDeleting が StopServer 完了後にどうやって DeleteServer を呼び出すのですか?
A: StopDeleting 自身は StopServer 完了後に “処理完了メッセージ” をキューへ投入します。ディスパッチャはこのメッセージと “停止・削除中” の状態を見て Deleting ハンドラを生成し、そこで DeleteServer を呼び出します。
A: StopDeleting 自身は StopServer 完了後に “処理完了メッセージ” をキューへ投入します。ディスパッチャはこのメッセージと “停止・削除中” の状態を見て Deleting ハンドラを生成し、そこで DeleteServer を呼び出します。
Q: “起動” 状態で StopServer を呼ばずに直接 DeleteServer を実行してはいけないのですか?
A: 表1の DeleteServer 仕様に「仮想サーバの状態が“停止”でなかった場合…エラー」とあるため、“起動” から直接 DeleteServer を呼ぶと失敗します。
A: 表1の DeleteServer 仕様に「仮想サーバの状態が“停止”でなかった場合…エラー」とあるため、“起動” から直接 DeleteServer を呼ぶと失敗します。
Q: 同一サーバ ID の排他制御はどこで担保していますか?
A: メッセージハンドラをサーバ ID 単位で一つのスレッドに限定し、ディスパッチャが重複生成しないことで排他制御を実装します。問題文にある「同一のサーバ ID に対する API 呼出しの排他制御は、API を呼び出すアプリケーションで行う必要」が根拠です。
A: メッセージハンドラをサーバ ID 単位で一つのスレッドに限定し、ディスパッチャが重複生成しないことで排他制御を実装します。問題文にある「同一のサーバ ID に対する API 呼出しの排他制御は、API を呼び出すアプリケーションで行う必要」が根拠です。
関連キーワード: 状態遷移表, メッセージキュー, 排他制御, API 仕様, ハンドラ設計
設問4:〔仮想サーバ削除時の自動停止機能の仕様変更〕について、(1)、(2)に答えよ。
(2)本文中のd〜fに入れる適切な字句を答えよ。
模範解答
d:起動
e:サーバ削除
f:StopDeleting
解説
解答の論理構成
- 仕様変更の目的を確認
- 問題文には「仮想サーバの状態が“起動”のときにサーバ削除のメッセージを受信した場合…サーバを削除できるように仕様を変更する」とあります。したがって “起動” 状態で “サーバ削除” メッセージを受け取った際の挙動を新しく定義する必要があります。
- 既存の表3(変更前)を確認
- “サーバ削除” 行の “起動” 列は “Err” になっています(引用:表3)。
- これは仕様変更前はエラーにしていたことを示します。
- 新設するメッセージハンドラの確認
- 表4で新たに追加するハンドラ名は “StopDeleting” です(引用:表4)。
- このハンドラは「“停止・削除中”に変更し」「StopServer」を呼び出し「処理完了メッセージを送信する」と定義されています。
- どのセルを “StopDeleting” に書き換えるか
- (3) の指示文:「表3中の仮想サーバの状態が“d”で、メッセージの種類が“e”の箇所のメッセージハンドラ名を、“f”に変更する。」
- 仕様変更の対象は「状態が“起動”」かつ「メッセージの種類が“サーバ削除”」のセルです。
- ここを新ハンドラ “StopDeleting” に書き換えることで、StopServer → DeleteServer の連続処理が実現します。
- 結論
d:起動
e:サーバ削除
f:StopDeleting
誤りやすいポイント
- “起動” と “起動中” の取り違え
“起動中” は StartServer 実行中、 “起動” は稼働完了後です。今回の変更対象は後者。 - “サーバ停止” と “サーバ削除” の混同
自動停止機能は削除要求時のみ。停止要求時は従来どおり “Stopping” を用います。 - 追加した “StopDeleting” をすべての削除要求に適用してしまう
仕様変更は “起動” 状態限定。 “停止” 状態の削除は従来どおり “Deleting” です。
FAQ
Q: “停止・削除中” 状態は誰が遷移させますか?
A: “StopDeleting” ハンドラがデータベースを書き換え、StopServer 完了後に “処理完了” メッセージを投げてディスパッチャが “Deleting” ハンドラへ橋渡しします。
A: “StopDeleting” ハンドラがデータベースを書き換え、StopServer 完了後に “処理完了” メッセージを投げてディスパッチャが “Deleting” ハンドラへ橋渡しします。
Q: 同一サーバIDに並列で “StopDeleting” と他のハンドラが動いたら?
A: 問題文にある「同一のサーバIDに対するAPI呼出しの排他制御は、APIを呼び出すアプリケーションで行う必要がある」ため、プロビジョニングシステム側で排他制御を設計しておく必要があります。
A: 問題文にある「同一のサーバIDに対するAPI呼出しの排他制御は、APIを呼び出すアプリケーションで行う必要がある」ため、プロビジョニングシステム側で排他制御を設計しておく必要があります。
Q: “StopDeleting” は DeleteServer を直接呼びませんか?
A: 呼びません。仕様では「StopServer → 処理完了 → Deleting ハンドラ → DeleteServer」という二段階に分けています。
A: 呼びません。仕様では「StopServer → 処理完了 → Deleting ハンドラ → DeleteServer」という二段階に分けています。
関連キーワード: 状態遷移, メッセージキュー, 排他制御, イベントドリブン, API呼出し


