JetのOrder Management System(OMS)はさまざまなビジネス機能を担っており,当初はタスクを編成するマイクロサービスの集合体として開発されていた。企業が成長するにつれ,このアーキテクチャの問題点も大きくなり,ついに同社は,ワークフローベースのプラットフォームを新たに構築することを決定した。同社のエンジニアであるJames Novino氏はブログ記事に,旧システムの課題についての説明とともに,新たなプラットフォームの概要と,1年間の運用経験について記している。
OMSは元々,pub/subやイベントソーシング,その他のテクノロジを組み合わせたマイクロサービス上で動作していた。各サービスは同じ定型コードを使用して,次の3ステップで実装されていた。
- Decode – 入力ストリームからドメインイベントを読み,それを入力タイプに変換する。
- Handle – 入力をチェックして,必要なデータを取り出す。
- Interpret – サイド・エフェクトを実行する。
企業と要件が大きくなるにつれて、アーキテクチャの複雑さも増大し,システムのメンテナンスが困難になった。サービスの数も増え,機能が複数のサービスに分散することが多くなったため,開発サイクルも長くなった。Novino氏はこれを,定形コードにありがちなプロセスの複雑さによるものと考えている。さらに氏は,このアーキテクチャの開発とメンテナンスの複雑さが,システムの成長とともに,システムとチームの両方に悪影響を及ぼした点も指摘している。
そのため同社は,すべてのビジネスワークフローをより効率的に処理可能にすべく,新たなプラットフォームの開発に着手した。Pat Helland氏と氏の論文"Life Beyond Distributed Transactions"に強く触発された同社では,ワークフローベースのシステムの設計と開発を行うことを決定した。新システムの中核となるデザインは,次の2つの保証を基盤としている。
- イベントの重複を回避する冪(べき)等性。
- 一貫性。同社では複数のバッキングストアをサポートしているが,自身の書き込んだものを読み取り可能であることが必要であるため,ストアには常に,強力な一貫性モデルを実装している。
これらを保証することで,次のような機能を備えたシステムが実現した。
- イベントソーシング。状態変更はすべてジャーナルに記録される。
- ワークフロー定義とそれに対応するステップで構成された,シンプルな実装。 これにより,まずビジネスフローを考えることが可能になると同時に,システムのモジュール化が促進される。
- ワークフローの冪等性の保証。
- 現在動作中の実行環境に関わらず、ワークフローへの変更のデプロイを可能にする、ワークフローのバージョニング
- スケーラビリティ。 各サービスのインスタンスを複数使用することで、ワークフローの並行実行が可能になること。
Novino氏は新たなアーキテクチャについて、以前のDecode -> Handle -> Interpretパイプラインを抽象化し、操作間のサービスバウンダリを明確にしたものだ、と説明している。
- Decodeに対応するWorkflow Trigger
- Handlingに対応するWorkflow Executor
- Interpretに対応するSide Effect Executor
ワークフローを定義する手段として、一連の必要な実行ステップを定義するドメイン固有言語(DSL)を開発した。さらに、実行中ワークフローと履歴ワークフローの両方を表示可能な、視覚化ツールも用意した。
ワークフローのオーケストレーションには既存の選択肢もあるが、同社では次のような理由から独自開発の方法を選択した、とNovino氏は記している。
- ワークフローイベント用に分離されたデータストアをメンテナンス可能にするため
- 実行中の任意の時点での状態を再生あるいは視覚化可能にするため
- 拡張性とスケーラビリティ
1年以上の運用を続けた結果、約2,200万のジャーナルが生成され、9,300万程度のワークフローが実行された。
Novino氏は結論として、分散型マイクロサービスをベースとしたアーキテクチャからワークフローベースのものへの移行が、同社の設計、開発、サポートにおけるオーバーヘッドに劇的な影響を与えた、と記している。さらに氏は、DSLを使用したワークフロー設計と、単一の責任ステップとしての実装が可能になったことで、複雑な新システムを開発する能力が向上した、とも述べている。氏の今後の記事は、新しいシステムをより詳細に説明する予定である。