ものレボのマイクロサービス

プログラミング

こんにちは。ものレボのCTO森松です。

今回はマイクロサービスの話です。

我々は、golangで作られた、独自仕様クリーンアーキテクチャのサービス群でマイクロサービスを実現しています。
右往左往してたどり着いた形を大雑把にご紹介しようと思います。

まず我々が作った独自のパターンを「ユースケースパターン」と呼んでいます。ご紹介しましょう。

クリーンアーキテクチャと分散システム

レイヤードアーキテクチャである、クリーンアーキテクチャですが、アプリケーションビジネスルールを記述する層がユースケースです。
ユースケースは、エンティティをコントロールし、設定されたユーザーストーリーのメソッド群として取り扱っています。マイクロサービスのモデルで言えば、システム全体のドメインに、サービスというサブドメイン、アグリゲートという業務ビジネス単位のサブサブドメインが存在し、そこにユースケースが紐付いている形です。

分散システムのメッセージングの単位は一般的にはアグリゲートを想定しますよね。私もそうでした。しかし、マイクロサービスをよく知らない開発者がメッセージングの基礎作って奇想天外な形になったのが、我々のユースケースパターンの始まりでした。

ユースケース同士がメッセージング

我々の仕組みでは、ベースメント担当者と一般エンジニア側という役割を明確に分けています。ファイルレベルで目に届かないようにしてます。ユースケースにはビジネスルールとイベントデータの作成・送信、それだけしか役割がありません。ベースメントがテクニカルサイドを全てカプセル化して、CQRSやEvent sourcingを実現しています。メッセージングもカプセル化されているので、ユースケース内で、別のサービスのユースケースを呼び出すことによって、開発者が分散システムを意識しすぎず分散できるよう仕組み化されています。クリーンアーキテクチャとの親和性はすごく良いと思います。

Eventのモデルは?

アグリゲート単位で状態を保存するのは、もはや不可能です。我々のイベントプロバイダーは、ユースケースであり、アグリゲート内で扱うエンティティが入り混じってるので、ドメインエンティティ単位のイベントになりました。一貫性が担保されないと言う人もいました。しかし、思い返してみましょう。独立性、原子性、持続性が担保されてるときに、一貫性がバグってたら、そもそもコードがバグってることがほとんどです。アグリゲートの全体状態を担保することは、一貫性を保証に繋がることに全く繋がっていないと思っています。Eventは多めに発生してまいますが、それに耐えうるベースメントと、プロセスの平行性を実現できれば、パフォーマンスはそれほど問題になりません。しっかりロックし、失敗したときにしっかり戻す(conpensation transaction)、これさえ出来ていれば問題はありません。

アグリゲートの存在意義は

モデリングの分割単位であり、頭整理するのにはやくにたってます。コーディングレベルになると、ただのディレクトリで影が薄い(笑)

楽しい開発が大事

マイクロサービスは、IDEALSを実現するために、「なぜ」を積み上げて出来上がると思います。
既存のパターンを積み上げる過程で発生した、開発者の発想を全部「なぜ」で拾って、独自解釈で魔改造しました。
最終的には、マイクロサービスは工数がかかると言わせない仕組みになったと思っています。

ベースメントが大変でしたが