真北科技Zhenbei
Unilearning · アーキテクチャ

6 つのマイクロサービスを 1 バイナリに収めた後、私たちが失ったもの

モジュラーモノリスは「モノリスへの回帰」ではありません。実行時の制約をコンパイル時の制約に置き換えるもので、代償も利得も現実に存在します。

旧システムは 6 つのマイクロサービスで、HTTP と URL 設定を使って互いに呼び出し合っていました。聞こえは極めて標準的ですが、実際のコストは二箇所に集中していました。一つはサービス間呼び出しのネットワークオーバーヘッドと失敗処理、もう一つは「ある機能を変えるのに三つのリポジトリに手を入れ、三つのサービスをデプロイする」ことです。

呼び出しを関数呼び出しに戻す

モジュラーモノリスの核心は「分割しない」ではなく「プロセス内で分割する」です。8 つの業務ドメインが一つのプロセスに集まり、ドメイン間の呼び出しは普通の関数呼び出し —— ネットワークも、シリアライズも、サービスディスカバリもありません。

unile-go — 二層の依存グラフ
01// 每个域拆成两个 module:
02// cms/api → 契约,只依赖 base
03// cms/internal → 实现,外部不可 import
04
05// edge 层做跨域编排
06func (h *Handler) SubmitAttempt(c *gin.Context) {
07 node := cms.MustGetNode(id) // 域内调用
08 result := quiz.Grade(node, answers) // 跨域:只经 api
09 cms.Records.Save(node, result) // 再调回 cms
10 c.JSON(200, result)
11}

境界は lint ではなくコンパイラが守る

Go の internal の仕組みにより、ドメインを跨ぐ import はビルドが通らなくなります。この制約はどんな lint ルールやアーキテクチャ文書よりも硬い —— 文書は古くなりますが、コンパイラは古くなりません。

  • ドメイン間で import できるのは相手の api(契約)だけで、internal(実装)には触れない
  • api は base だけに依存し、base は外部依存ゼロ
  • 複数のドメインを編成するロジックは edge に統一して書き、依存グラフは二層の木になる
  • 新しいドメインは api と internal を足すだけで追加でき、境界ルールを議論し直す必要はない

私たちが失ったもの

代償は現実に存在します。包み隠しません。

  • 独立したスケール調整は失われる。どのドメインに負荷がかかっても、全体をスケールさせるしかない
  • 障害分離は弱くなる。あるドメインの panic がプロセス全体に影響しかねない(recover とヘルスチェックで支える)
  • リリース粒度は粗くなる。あるドメインの変更に、バイナリ全体の再リリースが付きまとう
  • 技術スタックの固定。あるドメインを Go にして別のドメインを Java にする、というわけにはいかない

なぜこの取引が割に合うのか

このシステムの本当のボトルネックは単一ドメインのスループットではなく、イテレーション速度と運用の複雑さだったからです。6 つのマイクロサービスは、十数個のコンテナ、サービスディスカバリ、設定センター、分散トレーシングを意味します —— そうしたインフラのコストは、スケール調整で失ったわずかな弾力性よりはるかに高い。

提供形態の比較
01之前:6 个服务 · 十余个容器 · 服务发现 · 配置中心
02现在:1 个二进制 · 1 个容器 · 启动时自动迁移
03
04$ make docker && docker run -p 8080:8080
05[migrate] cms v12 → v14 ✓
06[migrate] quiz v07 → v09 ✓
07[server] listening on :8080

アーキテクチャ決定の本質はコストの比較であって、何か「より先進的な」形態を追いかけることではありません。もしいつか単一ドメインのスループットが本当にボトルネックになったら、そのドメインを切り出すのは api 契約を一度コピーするだけで済みます。

More Notes
Get in touch

アイデンティティ・エージェント・プライベートドメインの複雑さを、統治可能なひとつのカーネルへ

既存の IAM の置き換え、エージェント基盤の構築、あるいはプライベートドメイン運用の本格化——まずは 30 分のアーキテクチャ相談から始めましょう。私たちが得意とする種類の問題かを先に判断し、適さない場合は率直にお伝えします。