アーキテクチャ・カタをやってみた

ヌーラボブログリレー2024 for Tech Advent Calendar 2024の22日目の記事です。

ヌーラボ、ソフトウェアエンジニアのsakaiです。

現在、Backlog課では書籍『アーキテクチャの基礎』の読書会を開催しています。本記事では、この書籍で紹介されている「アーキテクチャ・カタ」というアーキテクチャ設計の演習アプローチに有志で取り組んだときのことをご紹介します。

初めに

アーキテクチャ・カタとは

アーキテクチャ・カタは、ソフトウェアアーキテクチャの設計スキルを実践的に磨くための演習です。そもそもアーキテクチャの設計力を鍛えるにも、キャリアの中でアーキテクトを務める機会は限られています。そこで実際のシナリオを模倣したお題に基づいてアーキテクチャを設計し、そのプロセスや結果のフィードバックを受けながら改善していくことでアーキテクチャ設計の能力を鍛錬することがこの演習の目的です。

実際にやってみた

アーキテクチャ・カタはこれまで3回実施しました。今回は3回目に実施したアーキテクチャ・カタについてご紹介します。1回目、2回目に実施したアーキテクチャ・カタでは時間が足りず、アーキテクチャの設計に時間が十分に取れなかった反省から、3回目は要件の確認、アーキテクチャの設計、振り返りを3日間に分けて実施しました。

今回ご紹介するアーキテクチャ・カタでは下記のお題を選定しています。

シスオペ部隊
大手電子機器メーカーは、全国の店舗で顧客対応を行う IT コンサルタント (Sysop Squad) 向けに新しいトラブル チケット システムを必要としています。

  • ユーザー: 数千人の顧客、数百人のコンサルタント、数百人の店舗スタッフ
  • 要件:
    • トラブルチケットは、コールセンターの受付係、店舗スタッフ、または顧客がオンラインで入力できます。
    • チケットは、場所、空き状況、スキルに基づいて適切なコンサルタントにルーティングされます。
    • コンサルタントはモバイルデバイスのみを必要とする
    • 顧客はサービス後にコンサルタントの評価を入力する
    • コンサルタントは、将来の参照のために顧客記録で実行された作業を追跡します。
  • 追加のコンテキスト:
    • 稼働時間は会社の評判にとって重要です
    • サイトのパフォーマンスは、高負荷時にも適切に低下する必要がある
    • リクエストを適切にルーティングすることが利益を上げるために重要

1日目

当初のアーキテクチャ図

1日目は作図ツールのCacooを使用してメンバー8人ほどでお題の要件を確認していきます。

まずはこのシステムを使用するユーザーを整理して考えることから始めました。使用することが想定されるユーザーとしては、顧客とコールセンターの受付係、店舗スタッフ、コンサルタントが挙げられます。彼らのロールを分けるとすれば、顧客、コールセンターの受付係、店舗スタッフがトラブルチケットの登録者でコンサルタントが閲覧者と考えることができます。

登録者が分かればトラブル対応の流れも明確になりそうです。登録者は上で挙げた3通りですので、WEBから顧客が自分でトラブルを登録するパターン、コールセンターに電話して受付係に登録してもらうパターン、店舗に顧客が直接出向いて店舗スタッフに登録してもらうパターンの3パターンの登録方法が考えられます。

チケットが登録されれば、コンサルタントにチケットを割り当てて対応してもらう必要があります。コンサルタントのスキルや勤務場所、スケジュールを管理する外部システムがあることを前提に考えれば、コンサルタントへのチケットの割り当ては自動化できそうです。ここでは外部システムの存在を前提にして自動割り当てシステムを考えるようにしました。

チケットがコンサルタントに割り当てられれば、コンサルタントはトラブルの対応を行います。コンサルタントはトラブルの対応後に作業の記録と顧客に評価を入力してもらう必要があります。作業の記録は顧客の同意の上、コンサルタントがチケットを完了とすることで問題なさそうです。顧客に入力してもらう評価に関しては、システムの運用過程で形式が変化する可能性があるかもしれません。そこでサービス開始初期は顧客からは紙でサービスの評価を記載してもらい、それに基づいてコンサルタントが5段階の評価を代理入力する方法を考えました。コンサルタントが評価を捏造する可能性もありますが、ここではコンサルタントが評価を捏造するインセンティブは低く、顧客の評価を反映させるインセンティブの方が高いことを仮定しています。

顧客から受け取った評価を元に振り返りと改善を継続的に行うことで、より適切なスキルを持ったコンサルタントを適切なチケットに割り当てられるようになり、よりリクエストに対する良好なルーティングが実現できそうです。

結果として確認した要件は下記の通りになりました。

  • チケットの登録者は誰か
    • コールセンターの受付係
    • 店舗スタッフ
    • 顧客
  • チケットの閲覧者は誰か
    • コンサルタント
  • トラブル対応の流れはどうなっているか
    • 顧客が電子機器で問題を抱える
    • チケット登録
      • WEBから自分で登録
      • コールセンターに電話
      • 店舗に持ち込む
    • コンサルタントにチケットを自動で割り当て
    • コンサルタントがトラブルへ対応
    • コンサルタントが作業内容を記録
    • 顧客がサービスの評価を行う(コンサルタントが代理入力)
  • チケットに必要は情報はどれくらいか
    • 対応する場所(住所)
    • 予約日程
    • 機器の種別
    • 機器の型番
    • 発生した問題の詳細
  • 外部サービスとしては何を想定するか
    • コンサルタント管理サービス(各コンサルタントのスキルや場所などを管理)
    • スケジュール管理サービス(各コンサルタントのスケジュールを管理)
  • リクエストの良好なルーティングとは何を指しているか
    • 適切な場所、適切なスキルを持った空き状態のコンサルタントへチケットを割り当てられている状態
      • 割り当てはシステムが自動的に行うと想定
      • 評価は顧客になされる

個人的にはリクエストの良好なルーティングという要件が何を指しているのかを読み取ることができませんでした。言葉からしてWEBリクエストをいかに早くレスポンスするか、みたいな想像をしていたのですが、他メンバーとの会話の中でこれはコンサルタントの割り当てを指していることに気づきました。私は言葉に囚われすぎているようです。

また、メンバーの一人が外部サービスとしてコンサルタント管理サービスとスケジュール管理サービスの存在を仮定する提案をしてくれたのですが、これはとても良い提案だったと思っています。私一人で設計をしていたらコンサルタントのスキルや勤務場所、勤務スケジュールのデータをどう持つかに時間を使いすぎて時間切れになっていたかもしれません。

2日目

単一障害点を解消後のアーキテクチャ図

2日目は1日目で確認した要件をもとにアーキテクチャを設計していきます。ここでは1チーム4人で2チームに分かれてアーキテクチャの設計を行いました。上記の図は私が所属したチームの設計したアーキテクチャです。

私のチームではまず、チケットの登録と閲覧から考えました。コールセンターの受付係、店舗スタッフ、顧客はフロントエンドの起票者用WEBアプリを操作してトラブルチケットの登録を行い、コンサルタントはモバイル端末を持っていることが前提なので、コンサルタント用のモバイルアプリを用意して、そこから作業やチケットの確認ができることを仮定しました。

次にバックエンドのサービス構成を主に下記の責務で切り出していきます。

  • トラブルを登録する
  • コンサルタントを割り当てる
  • トラブルチケットに関するDBの操作を行う
  • コンサルタントへ通知を送信する
  • コンサルタントの作業を管理する
  • コンサルタントの評価を管理する

この内容をCacooに全員で付箋を貼っていくことで上記のアーキテクチャ図が完成しました。

ただ、この設計だとトラブルチケットサービスが単一障害点になるので、追加コンテキストの「稼働時間は会社の評判にとって非常に重要」を満たすことができません。また、例えばチケットの登録が大量に発生することでトラブルチケットサービスが高負荷になって落ちた時に、コンサルタントは自分の対応するトラブルチケットの閲覧や、作業の管理、評価の入力ができなくなります。これは追加コンテキストの「サイトのパフォーマンスは、高負荷時にも適切に低下する必要がある」も満たせなくなってしまいます。

そこで、この問題を解消するためにトラブルチケットサービスを追加・参照・更新に分離、チケットDBを更新用と参照用で分離することでトラブルチケットの追加サービス、参照サービス、更新サービスのいずれかが落ちても全ての機能が停止することを避ける方法を考えました。これで可用性が担保される上、高負荷時の機能の段階的な低下も満たせるので、先ほど触れた追加コンテキストの2つが満たせます。

下記が改善後のアーキテクチャ図です。


結果、トラブル情報の登録からトラブルの解決後のコンサルタントの評価までは下記の流れで処理されることになりました。

  1. コールセンター、店舗スタッフ、顧客が起票者用のWEBアプリを使用してトラブル管理サービスのAPIを叩くことでトラブルの登録を行う。
  2. トラブル管理サービスはトラブルの情報をトラブルチケット登録サービスに投げる。
  3. トラブルチケット登録サービスは受け取ったトラブル情報をコンサルタント割り当てシステムに投げて、スキル・場所・スケジュールにマッチしたコンサルタント情報を取得すると、トラブル情報とコンサルタント情報からトラブルチケットを生成して更新用DBにチケットを追加する。
  4. データ転送エージェントは更新用DBに新しいチケットが追加されているかを定期的に確認する。新しいチケットが追加されている場合は参照用DBに更新用DBの状態を反映させる。
  5. コンサルタント割り当てシステムは、トラブルチケット登録サービスにコンサルタント情報を返した後、通知システムへコンサルタント割り当てに関するイベントを送信する。
  6. 通知システムはコンサルタント割り当てのイベントを受け取るとコンサルタントが使用するモバイルアプリに通知を送信する。
  7. コンサルタントは通知を受け取ると、割り当てられたチケットに対応可能かを判断する。対応可能でない場合は、コンサルタント用モバイルアプリからBFFを通して作業管理サービスにスケジュールの調整リクエストを行う。
  8. 作業管理サービスはトラブルチケット更新サービスを使用して更新用DBからスケジュールを更新したいチケットのレコードを更新する。
  9. コンサルタントが作業を完了させるとコンサルタント用モバイルアプリからBFFを通して作業管理サービスに作業の完了リクエストが送られる。
  10. 作業管理サービスは作業の完了リクエストを受け取ると作業情報のDBに作業情報を追加してからトラブルチケット更新サービスを通してトラブルチケットのステータスを完了に更新する。
  11. コンサルタントがコンサル用モバイルアプリを操作して、作業の評価を顧客の代理で入力する。
  12. BFFが評価リクエストを受け取ると評価サービスに評価情報を投げる。
  13. 評価サービスはコンサル評価DBに評価情報を追加する。

3日目

ここでは2つのチームがお互いに設計したアーキテクチャを共有して振り返りを行います。振り返りの中では下記のような意見、感想がでました。

  • 時間的にサービス構成を考えるので精一杯
  • 段階的な劣化をどう捉えるべきかと思ったり。
  • 2つのチームでサービスにかかる負荷の印象が異なっていた。
    • 私が所属したチームはDBにアクセスするサービスの負荷がシステム全体に影響を与えることを考えていたのに対して、もう一方のチームではCDNとロードバランサーだけで負荷に十分対応できると考えていた。
  • チームの人数が増えると議論に参加するハードルは上がってしまうかもしれない。
  • 知識の差とかは浮き彫りになっていた気がしたので、勉強する機会になりそう
  • 4人のチーム、議論しやすい人数だったと思う。とはいえ、共通認識をもつのがすごく大変。気をつけながら進めないと、っていう学びがありました。

終わりに

アーキテクチャ・カタに参加することでコンテキストの読み解きや設計のアイデアなど他メンバーから学ぶことは多くあり、意義のある取り組みができました。ぜひ、継続的に行ってアーキテクチャの設計力の向上を目指したいと思います。

もし、本記事をきっかけにアーキテクチャ・カタに興味が湧くようでしたら、ぜひメンバーを募って実施されることをお勧めします。そして実施した際にはその時の状況をブログ記事に書いていただけると大変嬉しく思います。

開発メンバー募集中

より良いチームワークを生み出す

チームの創造力を高めるコラボレーションツール

製品をみる