- AWS Builder Center›
- builders.flash
AWS の新卒社員が考えた寿司配送システムのアーテクチャを、ベテラン社員にレビューしてもらってみた
2025-11-04 | Author : 冨山 英佑, 菅原 太樹, 濵 真一
はじめに
AWS Summit 2025 で、小さな寿司屋が開店していたことをご存知ですか ? 残念ながら回転はしていないのですが、開店はしていました。
時は遡り、2025 年 6 月。幕張で行われた AWS Summit Japan 2025 では、2024 年に入社した新卒ソリューションアーキテクトたちによる寿司配送システムが展示されていました。「Cloud Sushi」と名付けたこのプロジェクトは、AWS Step Functions と AWS IoT Core をベースに設計された、寿司配送モノレールのデモンストレーションです。
来場者の方々に実際に体験していただきながら、AWS の各種サービスがどのように連携して動作するのかを、寿司の注文・調理・提供というわかりやすいプロセスを通じて理解していただくことを目指しました。
当日は順調にシステムが稼働。たくさんの人に寿司 (を模した消しゴム) を配送することができました。
しかし !!!
時が経つにつれ、もっといいアーキテクチャにできたのでは ? という思いが勃発。メンバーの間ではモヤモヤとした思いが溢れていました。そこで Head of Startup Solutions Architect, Japan のはまさんにアーキテクチャレビューをお願いしました。
この記事では、新卒 SA たちが先輩 SA にアーキテクチャをレビューしてもらう様子をお届けします。
builders.flash メールメンバー登録
builders.flash メールメンバー登録で、毎月の最新アップデート情報とともに、AWS を無料でお試しいただけるクレジットコードを受け取ることができます。
寿司配送マシンと体験の流れ
寿司注文システムの物理デバイスはこのようになっています。写真に写っているのが寿司配達モノレールと、注文受付用のタブレット端末です。注文フローは下記の流れで行われます。
- 注文者がタブレットから寿司を注文する
- モノレールに頼んだ寿司が積載される
- モノレールが注文者の前まで配送する
- 注文者が寿司をとり、タブレットの配達完了ボタンを押す
- モノレールが定位置まで帰還する
このような形で寿司配送を自動で行うシステムが稼働しています。
現状のアーキテクチャ
現在のアーキテクチャは以下のようなアーキテクチャで構成されています。大きく分けて 2 つの AWS Step Functions で構成されており、右の Step Functions が配送レーンを、左の Step Functions が注文の状況を表しています。こだわったのは、Step Functions でできることは Step Functions で行う考え方でした。AWS Lambda のソースコードは極力減らし、最小限の管理と開発で動かすことを目指していました。
注文をさばくステートマシン
会場に置かれているタブレットから Amazon API Gateway を経由して注文が入ると起動します。注文情報を Amazon DynamoDB に書き込んだのち、注文 ID を Amazo SQS に格納します。
SQS に注文 ID を格納する際、タスクトークン を発行します。タスクトークンが返ってくるまでステートを待機させることによって、注文が完了するまで実行を続けるものになっています。
配送モノレールをコントロールするステートマシン
会場の寿司配達モノレールが準備完了すると、AWS IoT Core を経由して起動します。SQS をロングポーリング することによって注文を取得し、モノレールへ配達指示を行います。配送を完了すると、注文ステートマシンにタスクトークンを返却して一連の流れが終了します。
はまさんの指摘 1 : 注文ステートマシンは本当に必要 ?
指摘内容と考察
指摘内容
レビューで最初に指摘されたのは、注文ステートマシンの必要性についてでした。
はま :「この注文ステートマシン、なんか無駄に待っているように見えるんですが、これって本当に必要ですか ?」
確かに、当初の設計では API Gateway (WebSocket) で注文を受け付けた後、注文ステートマシン で注文情報を DynamoDB に書き込み、タスクトークンを使って配送ステートマシンの完了を待ってから注文完了を返すという流れになっていました。
はまさんの指摘は、「注文を受け付ける」という役割が終わったら、そこで処理を終了すべきで、わざわざモノレールの完了を待つ必要はないのでは ? というものでした。
考察
この指摘を受けて、なぜ同期的に待つ必要があるのかを改めて考えました。当初は「注文の状態」と「モノレールの動き」を概念的にマッピングし、注文はモノレールが動き終わるまで完了していないという考えでした。しかし実際には、注文受付は非同期で処理でき、ユーザーには「注文を受け付けました」と返せば十分で、モノレールの動作完了を同期的に待つ必要はありませんでした。
はまさんからは、API Gateway から DynamoDB に直接書き込み、DynamoDB Streams から Amazon EventBridge Pipes を使って SQS にイベントを流すという代替案が提示されました。この方が粗結合で役割が明確になり、無駄な待機処理もなく、リトライも SQS で自然に実現できます。
Step Functions は強力なサービスですが、「何でも Step Functions で解決する」のではなく、適材適所でサービスを選ぶことが重要です。注文受付という単純な処理には、API Gateway + DynamoDB Streams + SQS の組み合わせの方がシンプルで適切でした。
はまさんの指摘 2 : ステートの可視化と管理の難しさ
指摘内容と考察
指摘内容
はま : 「実運用を考えた時、この注文が今どの状態なのか、管理画面で見たいですよね ? 実運用では、板前さんが現在の注文一覧を把握したり、注文ごとにステータスを確認する必要がありますね。 DynamoDB にステートを入れちゃった方が楽じゃないですか ?」
これは痛いところを突かれました。実は開発中、注文状態を可視化しようとして Step Functions の GetExecutionHistory API を使ってステートを可視化しようとしたものの、実装が間に合わずに断念した経緯がありました。
考察
Step Functions のステートはワークフロー管理用であり、エンドユーザーに表示するための情報はビジネスロジック用として、この2つは分けて考えても良かったかもしれません。
実運用を考えると、寿司屋さんの立場では「この注文は今どこまで進んでいるか ?」を管理画面で見たいですし、トラブル時に「どこで失敗したか?」をすぐに確認したいはずです。Step Functions のログを毎回掘るのは現実的ではありません。
解決策として、現在の情報を外部の DynamoDB に持つことが提案されました。例えば、注文 ID ごとに「配達中」「到着通知待ち」といったステータスと最終更新日時を記録しておけば、管理画面からは単純に DynamoDB を読むだけで状態が分かります。これにより注文の進捗状況をリアルタイムで可視化でき、トラブルシューティングも容易になり、管理画面の実装もシンプルになります。
「Step Functions の多機能さを広める」という当初の目的は達成できましたが、実運用を考えると、情報を外部に持つ方が運用しやすいという現実的な判断が必要でした。技術的なチャレンジと実用性のバランスが重要ですね !
はまさんの指摘 3 : フローを分けるか、一つにまとめるか
指摘内容と考察
指摘内容
はま : 「配送ステートマシンも、配達指示を出したら一旦終了して、到着通知は別のステートマシンで処理するという考えもありますね」
当初の設計では、注文から配達、到着通知までを一つの長いステートマシンで管理していました。これについて、分割すべきか一つにまとめるべきかという議論ができます。
考察
一つにまとめる場合、ワークフロー全体を一つのステートマシンで管理でき、注文の流れが一目で分かり、ステート管理が一元化されるというメリットがあります。
逆に分割する場合は、役割が明確になり、個別にテストしやすく、トラブル時にどの部分で問題が起きたか特定しやすくなります。外部にステートを持てば、進捗管理も容易です。ただし、ワークフロー全体の流れが見えにくくなる可能性や、ステート管理を外部 (DynamoDB) で行う必要があるという側面もあります。
Step Functions の機能としてリトライや TestState API による単一ステートのテスト機能はありますが、適切なまとまりで切ることにより、そのメリットを最大にすることができるでしょう。
はま :「実運用を考えた時、役割を分けて、ステートを外部で管理する方が、トラブルシューティングも管理画面の実装もやりやすいかも」
今回の場合だと、注文受付フロー、タブレットへ到着を通知するフロー、モノレール帰還指示フローの三つのステートマシンに分割することで、それぞれの責務が明確になります。
一つの大きなワークフローで全てを管理することにより、Step Functions のオブザーバビリティを活かすことができていました。しかし実運用を考えると、適切な粒度でフローを分割し、SQS や EventBridge で疎結合にするという設計の方が、保守性・運用性が高くなるかもしれません。
まとめ
はま: 「そんなところかな。アーキテクチャに正解はないし、大事なのはどんなことを大切にして設計したかどうかですね。今回皆さんは Step Functions をたくさん活用したい ! というコンセプトのもとやっていたから、いいアーキテクチャだと思いますよ。」
冨山・菅原 : 「ありがとうございます !」
はま : 「ただ、Step Functions 好きの先輩としてアドバイスすると、どんなサービスでも銀の弾丸にはなり得ない。Step Fucntions の他にも Event Bridge や SQS を活用して、より良いアーキテクチャを目指してみてください !」
冨山 : 「さすがは私の上司 ! さて、打ち上げは回らない寿司屋ですか ?」
はま :「.......。」
冨山・菅原 : 「......。」
今回、Cloud Sushi のアーキテクチャをベテラン社員のはまさんにレビューしていただき、実運用を見据えた 3 つの貴重なフィードバックを紹介しました。
展示物として「こんなこともできる !」と見せることと、実際に運用するシステムを作ることは目的が違います。今回のレビューを通じて、技術的なチャレンジと実用性のバランスを考える重要性を実感しました。
皆さんも、この記事を読んだ疑問点があればぜひこちらの URL とともに SNS でご意見ください。来年にはよりアップグレードして展示されるかもしれません。
筆者プロフィール
冨山 英佑 (Eisuke Tomiyama)
アマゾンウェブサービスジャパン合同会社
スタートアップソリューションアーキテクト
2024 年に新卒で入社した 2 年目 SA。スタートアップのお客様を担当している。強い SA になるために日々学び続けた結果、入社 6 ヶ月で AWS 資格を全冠。ついでに筋肉も鍛えている。
LinkedIn
菅原 太樹 (Taiki Sugawara)
アマゾンウェブサービスジャパン合同会社
フィナンシャルサービス技術本部 ソリューションアーキテクト
冨山と同期の 2 年目 SA。主に保険業界のお客様を担当している。
Cloud Sushi プロジェクトでは全体の設計を担当。Step Functions 愛を全面に押し出し、それ以外の意見は全て却下した。
X: @taikis_tech | LinkedIn
濵 真一(Shinichi Hama)
アマゾンウェブサービスジャパン合同会社
スタートアップ事業本部 技術統括部 部長
ベテラン SA。コーラと AWS をこよなく愛している。
冨山の上司で、スタートアップのお客様を支援している。
X : @track3jyo