Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[JPN] Multi-Module Repository in Golang

783718ebd2faaa896d4cb347835c07fb?s=47 tarotaro0
December 06, 2019

[JPN] Multi-Module Repository in Golang

- What is multi-module repository
- How to use multi-module repository
- Pros/Cons of multi-module repository
- How to apply microservice architecture

783718ebd2faaa896d4cb347835c07fb?s=128

tarotaro0

December 06, 2019
Tweet

Transcript

  1. mercari.go #12 @tarotaro0 Multi-Module Repoitoryのススメ

  2. Multi-Module Repository とは Agenda Multi-Module Repository の操作 Multi-Module Repository の

    Pros/Cons Microservice Architecture への適用 02 03 04 01
  3. Multi-Module Repository とは

  4. Go Module • Go 1.11から導入された、Goの依存 管理システム • Moduleはgo.modファイルをルートと するツリー内のパッケージの集合 •

    go.modはModule Pathと、依存関係 を定義する 参考:https://github.com/golang/go/wiki/Modules#modules go.mod
  5. Multi-Module Repository A multi-module repository is a repository that contains

    multiple modules, each with its own go.mod file. From: Go wiki • Multi-Module Repositoryは、複数のModuleが含まれるリポジトリ • Moduleは、go.modファイルを含むディレクトリから始まり、そのディレクトリとそ こから再帰的に辿ることの出来るサブディレクトリの集合 (※ただし、go.modファイルを含むディレクトリは除く)
  6. Multi-Module Repository Image from: Go wiki

  7. Multi-Module Repository の操作

  8. 実験したリポジトリ • https://github.com/tarotaro0/exp-mm-repo • commit&commandごとの説明docs ◦ https://github.com/tarotaro0/exp-mm-repo/blob/master/docs/process.md • 実験 ◦

    Moduleの追加・バージョニング・更新 ◦ Module同士の依存 ◦ etc...
  9. Main Repository /exp-mm-repo ├─ main.go └─ go.mod • $ cd

    /exp-mm-repo • $ go mod init Main Moduleの追加 /go.mod
  10. Main Foo Repository /exp-mm-repo ├─ main.go ├─ go.mod └── /services

    └── /foo   ├── go.mod   └── main.go • $ mkdir /services/foo • $ cd /services/foo • $ go mod init github.com/tarotaro0/exp-mm-repo/s ervices/foo Sub Module の追加 /services/foo/go.mod
  11. • $ git tag services/foo/v1.0.0 ◦ タグ名はルートからgo.modまでの pathに依存する ◦ ex.)

    {{path}}/v1.x.x • $ git push origin master services/foo/v1.0.0 • 更新も同様にタグ付けするだけ ◦ $ git tag services/foo/v1.1.0 Sub Module のバージョニング https://github.com/tarotaro0/exp-mm-repo/release s/tag/services%2Ffoo%2Fv1.0.0
  12. Github • Module化されると依存無しにimportが 出来ない • $ go mod edit -require

    github.com/tarotaro0/exp-mm-repo/s ervices/foo Module間の依存 Main Foo Repository /exp-mm-repo ├─ main.go ├─ go.mod └── /services └── /foo   ├── go.mod   └── main.go services/foo/v1.0.0 /main.go /go.mod
  13. • $ go mod edit -replace github.com/tarotaro0/exp-mm-repo/s ervices/foo@v1.0.0=./services/foo Github Local

    Moduleへの依存 Main Foo Repository /exp-mm-repo ├─ main.go ├─ go.mod └── /services └── /foo   ├── /go.mod   └── /main.go services/foo/v1.0.0 /go.mod
  14. Github • $ cd /services/foo • $ go mod edit

    -require github.com/tarotaro0/exp-mm-repo • ※packageの循環参照には注意 Module同士の依存 Main Foo Repository /exp-mm-repo ├─ main.go ├─ go.mod └── /services └── /foo   ├── go.mod   └── main.go services/foo/v1.0.0 /services/foo/go.mod
  15. ここまでのまとめ • go.modファイルを複数置くことによって簡単にMulti-Moduleに出来る • それぞれのModuleごとにバージョニングを行うことが出来る ◦ ただしタグ名はModuleのルートからのpathによって決まる • replaceを付けることで同repository内のModuleを参照できる •

    Module同士の依存は可能 ◦ ただしpackageの循環参照にならないように注意
  16. Multi-Module Repository のPros/Cons

  17. Cons it is almost always easier and simpler to manage

    a single-module repository rather than multiple modules...     from Go wiki 1. バージョン管理の手間が増加 2. go test ./… で全体のテストが出来ない 3. リポジトリの肥大化
  18. • Moduleが増えれば増えるほど、個々のModuleのバージョン管理が大変になる ◦ 追加 ◦ 更新 ◦ 削除 • 依存するModuleのアップデートが頻発する

    ◦ ex.)Subのバージョンが上がる度にMainを上げなければいけない ◦ 自動でアップデートに追従するdependabot等の対応が必要 Cons 1. バージョン管理の手間が増加
  19. • MainのModuleで go test ./… しても、Module化されたディレクトリはテストされ ない ◦ 個々のModuleでテストを実行する必要がある ◦

    テストを自動化するための仕組みが必要 Cons 2. go test ./… で全体のテストが出来ない
  20. • 複数リポジトリに分かれたサービスを一つのリポジトリにまとめる場合、必然的 にリポジトリが肥大化する ◦ clone/build等の時間が増加 ◦ リポジトリに関わるチームが増えた場合にコミュニケーションコストが増加 ▪ リリースの連携や、feature branch等の対応が必要になる可能性がある

    Cons 3. リポジトリの肥大化
  21. Pros It's important for long-term evolution of code storage options

    that a repo can contain multiple modules... from Russ Cox commented 1. 粒度の細かい依存関係の構築 2. Mainに関係ないコードの独立 3. アーキテクチャ変更の柔軟性 4. リポジトリ共通化の恩恵
  22. • 各Moduleが個別にクライアントに依 存されてる場合、必要なModuleの特 定のバージョンを選択して依存でき る ◦ 提供側は個別のバージョニングを 考えるだけで良い ◦ google-cloud-go

    はAPI毎に Moduleを提供している Pros 1. 粒度の細かい依存関係の構築 Repository Mod Mod Mod Mod v1.0.0 v1.1.0 v1.2.0 v1.0.0 v1.0.1 v1.1.0 v1.0.0 v1.1.0 v1.0.0 v1.1.0 v2.0.0 Client A Client B Client C
  23. • 各Moduleが個別にクライアントに依 存されてる場合、必要なModuleの特 定のバージョンを選択して依存でき る ◦ 提供側は個別のバージョニングを 考えるだけで良い ◦ google-cloud-go

    はAPI毎に Moduleを提供している Pros 1. 粒度の細かい依存関係の構築 Repository Mod Mod Mod Mod v1.0.0 v1.1.0 v1.2.0 v1.0.0 v1.0.1 v1.1.0 v1.0.0 v1.1.0 v1.0.0 v1.1.0 v2.0.0 Client A Client B Client C
  24. • 各Moduleが個別にクライアントに依 存されてる場合、必要なModuleの特 定のバージョンを選択して依存でき る ◦ 提供側は個別のバージョニングを 考えるだけで良い ◦ google-cloud-go

    はAPI毎に Moduleを提供している Pros 1. 粒度の細かい依存関係の構築 Repository Mod Mod Mod Mod v1.0.0 v1.1.0 v1.2.0 v1.0.0 v1.0.1 v1.1.0 v1.0.0 v1.1.0 v1.0.0 v1.1.0 v2.0.0 Client A Client B Client C
  25. Pros 2. Mainに関係ないコードの独立 • One-Off tool等のスクリプトや Example用ディレクトリなど ◦ Mainのコードには関係しないが、 チームとしてリポジトリに置いてお

    きたい場合 ◦ 余計な依存を増やさない ◦ testなどが含まれる場合もgo test ./… で参照されない Main Scripts Repository /exp-mm-repo ├─ main.go ├─ go.mod └── /scripts   ├── go.mod   ├── main.go   └── main_test.go
  26. Pros 3. アーキテクチャ変更の柔軟性 • Moduleの取り外しを簡単に行える ◦ Module化されているコードをその まま別リポジトリに移すだけで切り 離すことが出来る ◦

    逆に他のリポジトリで管理されて いるModuleをそのまま取り込むこ とも出来る Repository Mod Mod Mod Mod Repository Mod
  27. • 各Moduleの共通部分を共有できる ◦ 複数リポジトリで同様の変更を行う必要が無くなる ▪ ex.) ・ 3rd partyライブラリのアップデート ・

    共通基盤の変更 • チームの管理コストが減る ◦ Issueの集約、test/build/releaseなどのフローの共通化 • いわゆるmonorepoと同様の恩恵 Pros 4. リポジトリ共通化の恩恵
  28. Microservice Architecture への適用

  29. • 類似するサービスをまとめてドメインチームに分割 ◦ Notification ◦ User ◦ etc... • 1チーム辺り複数のサービスを持つことがある

    ◦ Notification in app ◦ email/sms/push notification • 1 repo, multiple services vs multiple repo, multiple services 1 Team, 1 Repository, Multiple Services repo repo repo repo repo vs
  30. 1 Team, 1 Repository, Multiple Services • Notification Teamは 1

    repository, multiple services に取り組んでいる ◦ 共通基盤の共有 ◦ チームの開発が一つのリポ ジトリに集約 ◦ 今後Moduleを切り離す可能 性がある
  31. Microservice 共通基盤のmulti-module化 • 各microservice teamで共通に使 われるライブラリのmulti-module化 ◦ middleware ◦ 3rd

    party ライブラリの 共通設定 ◦ etc... • google-cloud-go のように、必要な moduleだけ参照可能 Repository Mod Mod Mod Mod v1.0.0 v1.1.0 v1.2.0 v1.0.0 v1.0.1 v1.1.0 v1.0.0 v1.1.0 v1.0.0 v1.1.0 v2.0.0 MS A MS B MS C
  32. 始めからMicroserviceを意識したBackend構成 • replaceを用いてローカルを参照 することでほぼ通常と変わらな い開発が可能 • Multi-Module Repositoryは Moduleの取り外しが容易 →monolithのスピード感を得つつ

    サービスの成長に合わせて microserviceへの変更がしやすい Repository Mod Mod Mod Repo Mod 初期 Mod Repo Mod Repo Mod Repo Mod 後期
  33. • Multi-Module Repositoryは良いぞ ◦ Moduleの分離による独立性の恩恵 ◦ Monorepo的な恩恵 ◦ Microservice Architectureとの親和性

    • どういう時に使えそう? ◦ スクリプトやexampleの分離 ◦ 個別パッケージが複数のクライアントに使われる ◦ サービスの成長に伴い構成が変化する可能性がある まとめ