こんにちは。ティアフォーでWebサービス開発を担当している池谷です。
世の中はコロナで自粛モードが続いていますが、ティアフォーではリモートワークを活用し日々の業務に柔軟に取り組んでいます。
さて、私の所属するWebチームでは、オープンソースの自動運転OS「Autoware」を利用した多種多様なサービスを開発しています。その中でも代表的なサービスに「FMS」という運行管理サービスがあります。今回は、当サービスを開発してきた振り返りとして、主にドメイン駆動設計によるアーキテクチャの最適化に纏わるトピックについてお話したいと思います。
What's FMS?
過去にも一度ご紹介させていただきましたが、FMS(Fleet Management System)とは、業界的には「配車サービス」や「運行管理サービス」と呼ばれており、複数の車の走行予定・計画などを管理するサービスです。
例えば、海外ではUber社などが配車サービスを展開しています。国内にも配車サービスビジネスを展開しているプレイヤーは存在します。
ティアフォーのFMSの注目機能
弊社のFMSが運行管理サービスとして特殊な点は以下の通りです。
- 管理する車が自動運転車である
- ハイブリッドな運行モデルの走行管理が可能である
運行管理サービスというと、車両に一般的な自動車を用いる場合がありますが、弊社の場合はAutowareの自動運転技術とWeb技術をインテグレーションすることで、自動運転車を使った運行管理サービスを実現しています。
また、FMSは複数の運行モデルに対応しています。運行モデルというと聞き慣れない言葉かもしれませんが、モデルによって以下のような違いがあると認識していただければと思います。
オンデマンド配車モデル
例えば、自分が今いる場所まで車で迎えに来てほしい人がいた時に、まずその人がいる地点に車を迎車させ、その後目的地まで送り届けるといった車両スケジュールを管理します。
旅客ビジネスや配車ビジネスの場面において求められる運行モデルです。
巡回走行モデル
一方で、巡回走行モデルは決められた地点を延々と周回するような運行モデルです。
こちらは、工場などの物流ビジネスの場面で求められる運行モデルです。
ベストプラクティスを求めて
FMS開発における試行錯誤
自動運転やMaaSの分野は歴史が浅いこともあり、FMSを含めたWebサービスのデザインパターンが確立されていないのが実情です。そのような中、開発にあたっては常に自分達にとってベストな形を模索してきました。
FMSはこれまでに2度に渡る変遷を遂げています。第1の転換期は、α版からβ版への変更で、機能面の拡充やサービスとしてのスケーラビリティなどの非機能向上を目的にシステム再構築を実施した大イベントです。現在のFMSの礎はここで構築されました。
しかしその後、マイクロサービスとしての設計上の問題などが影響し、次第にバグが増加したりシステムの保守性が低下していきました。そこで、こういった課題を解決すべく実施したのがアーキテクチャの最適化です。これが第2の転換イベントです。今回はこのイベントにフィーチャーしたいと思います。
浮上していた課題
具体的には、β版は次のような課題を抱えていました。
- マイクロサービスにおけるコンポーネント間のメッセージング・I/Fが密結合してしまっていた
コンポーネントに閉じた修正のはずが他のコンポーネントに影響しデグレが発生 - リファクタリングが不足し変更容易性が低下していた
機能追加や機能変更時に必要以上に時間を消費 - システムとして仕様の明記や用語の整理が不十分なために全体の理解容易性が低下していた
新しい開発者がキャッチアップに躓いたり属人化の傾向が出ていた
これらの課題を解決するために、アーキテクチャを俯瞰的に見直し、各コンポーネントのリファクタリングや再開発を実施しました。
開発手法のアプローチ
ドメイン駆動設計
アーキテクチャ全体の見直しにあたって、開発手法としてドメイン駆動設計を取り入れました。人気度が高く話題に上がることの多いDDDですが、DDDを採用した理由は、次の利点に惹かれたところが大きいです。
- 変更容易性が高い
- 顧客やチームメンバーと共通認識を持ちやすい
FMSではモビリティやAutowareに纏わる専門用語を多く扱います。
- 例:Waypoint, Lane, LatLng, MGRS, ETA, Dispatch など
こうした専門用語のキャッチアップが、新しくジョインしたエンジニアが最初に躓くポイントになっていました。
DDDでは、ユビキタス言語というユーザーと開発者で互いに通じる用語に関する内容が登場しますが、これはユーザーのみならず、例えば他の開発メンバー達とも理解が促進されるものと思われます。これにより、上述の障壁を少しでも軽減したいと考えました。
また、FMSの開発チームでは、スクラム開発におけるフィーチャーチーム体制を導入しており、みんなで一緒に複数のコンポーネントをクロスファンクショナルに開発し合うスタイルを取っています。共通の認識を持てる言葉ができることでコミュニケーションが捗り、その結果チーム開発のアジリティ促進効果を期待できると考えました。
モデリングの実践
ではここで、車両のスケジュールを管理するSchedulerコンポーネントに対して実際に行ったモデリングについてご紹介します。
これらは、Schedulerが管理する最も基本的なドメインモデルです。スケジュールは、ステータスや走行の予実などを管理しますが、その他に別のドメインモデルであるタスクも管理していますね。こういった複数のモデルやオブジェクトを一つのまとまりとして管理することを「集約」と言います。
このように整理することで「タスクの○○の部分を☓☓に変更しておいて」「ああ、タスクね」といったコミュニケーションが可能となります。
設計・実装面のアプローチ
クリーンアーキテクチャ
Schedulerですが、以前は一般的なレイヤードアーキテクチャでしたが、DDDを具現化するために、DDDと相性が良いと言われるクリーンアーキテクチャを取り入れて再開発を行いました。
採用根拠
DDDの実装手段としては、クリーンアーキテクチャ以外にも候補はありましたが、大きな動機としてはやはり変更容易性の高さが決め手となりました。
Schedulerは、機能開発のボリュームは実はそれほど多くはありません。ある程度機能面での補完が終わったら、その後はスケジューリングの最適化問題などに対する試行錯誤が想定されます。
例えば、オンデマンド配車のユースケースを想定すると配車依頼がかかった時に、最適な車両を配車させるニーズが生じます。本格的に対応するには、離散最適化などの高度なコンピューターサイエンスが要求されます。こうした変更開発の比重が大きくなりそうなシステムの開発においては、変更容易性の高さを享受できるクリーンアーキテクチャは合理的だと判断しました。
新しくなったFMS
新アーキテクチャ
こうして、開発手法および技術の刷新によって新しくなったFMSの姿がこちらです。それぞれのコンポーネントが独立し、それぞれの責務を果たすアーキテクチャへと変貌を遂げました。
序盤に挙げた以下3つの課題ですが、まだ完全に解決できた訳ではありませんが、着実に進歩したものと感じています。
- バグの多発
- コンポーネントの変更容易性の低下
- システム全体の理解容易性の低下
この他にもまだ課題はありますが、現在はこのアーキテクチャをベースに新機能の開発や非機能の拡充に励んでいます。
開発手法や技術の選定にあたってのご注意
今回採用したDDDやクリーンアーキテクチャですが、勿論良い面ばかりではありません。例えば、ある程度規模感のあるシステムでないと、旨味が少ない割に開発コストばかり高くついたり、変更が少なかったり寿命が短いシステムにおいて、変更容易性はあまり重要ではないという考え方もできます。
この辺りは、良い面と悪い面をしっかりと理解した上で、自分達のシステムとの相性を見極めてから採用されることをお勧めします。
最後に
今回は、マイクロサービスのアーキテクチャ最適化について、代表的なサービスをベースにご紹介させていただきました。こう見えてFMSはまだまだ開発途上なサービスです。また、FMS以外にもWebチームではバラエティに富んだサービスを鋭意開発中です。
ティアフォーでは、これらサービスの開発を加速していただける優秀なソフトウェアエンジニアを募集しています。