Slide 1

Slide 1 text

モンストとGoとBazelと モンストサーバーT

Slide 2

Slide 2 text

モンストのサーバーサイドは Ruby です

Slide 3

Slide 3 text

モンストのざっくり構成図 オンプレを含むマルチクラウドでロール毎にさまざまなサーバーが動作しています 3

Slide 4

Slide 4 text

モンストのざっくり構成図 App や Batch サーバーで Ruby を使っています Ruby Logo by Yukihiro Matsumoto is licensed under the Creative Commons Attribution-ShareAlike 2.5 License 4

Slide 5

Slide 5 text

モンストとGo 主に各サーバーを操作する Deploy サーバーで使う自作 CLI ツールに Go を使ってます Ruby Logo by Yukihiro Matsumoto is licensed under the Creative Commons Attribution-ShareAlike 2.5 License 5

Slide 6

Slide 6 text

モンストとGo 今では自作 WebSockets サーバー(on GKE)など、本番環境でも一部使われてます Ruby Logo by Yukihiro Matsumoto is licensed under the Creative Commons Attribution-ShareAlike 2.5 License 6

Slide 7

Slide 7 text

モンストとGo これら全てモノレポで管理されてます Git Logo by Jason Long is licensed under the Creative Commons Attribution 3.0 Unported License 7

Slide 8

Slide 8 text

課題:モノレポのCI/CD Go製 CLI ツールの配布(deb package)やテストの実行などを自動化したい! Makefile などで管理・実行してまわるのは大変です Git Logo by Jason Long is licensed under the Creative Commons Attribution 3.0 Unported License 8

Slide 9

Slide 9 text

Bazel

Slide 10

Slide 10 text

Bazel Bazelは次のような特徴を持つビルドツールです ビルドを独自のサンドボックス環境の中で行う 依存関係を明記するためキャッシュ効率が良い Starlark という Python サブセットな言語で拡張可能 いわゆるライブラリのようなものを使うことで、簡単にさまざまなプログラムのビル ドやテストの実行を同じインタフェースで行うことができます bazelbuild/rules_go : Goプログラムのビルドやテストなど bazelbuild/rules_docker : Dockerイメージのビルドやプッシュなど tweag/rules_haskell : Haskellプログラムのビルドやテストなど 10

Slide 11

Slide 11 text

BazelとGo Go は Bazel との相性が良い(個人の感想) Go はシングルバイナリを作る際に C などの依存がほとんどない 通信・暗号系のライブラリが Go で書かれている(公式パッケージ) Bazel は依存関係を明示する必要があるため他言語との依存は扱いにくい Go はクロスコンパイルが簡単にできる Bazel にはクロスコンパイルのためのインターフェースがある Mac から Linux のバイナリを作ってそのまま Docker イメージにできる Bazel でのイメージ作成は基本的に Docker の外で行われるため、クロスコンパイルできた方がいい 11

Slide 12

Slide 12 text

BazelとGo Bazel では依存関係を全て列挙しなければいけない しかし、依存関係を全て Bazel の設定ファイルに手書きするのは大変です Gazelle : Goコードから自動で Bazel の設定ファイルを生成してくれる load("@bazel_gazelle//:def.bzl", "gazelle") # gazelle:prefix github.com/example/project gazelle(name = "gazelle") bazel run //path/to/project:gazelle とするだけ 12

Slide 13

Slide 13 text

BazelとGo Go プロジェクトの依存パッケージは vendoring しています Go プロジェクト間で依存パッケージが完全に独立できる Gazelle を利用することで vendoring 先にも Bazel の設定ファイルを配置可能 注意:元から Bazel の設定ファイルがあるとうまく動作しない go mode vendor + 元からある Bazel の設定ファイルの削除 + Gazelle をコマンド化 load("//build/rules/go:def.bzl", "go_project") go_project() # gazelle をラップしている bazel run //path/to/project:vendoring とするだけ 13

Slide 14

Slide 14 text

BazelとGo 欠点:Go プロジェクト毎に Go のバージョンを別にはできない 解決方法:ツールチェインを別名で設定 load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies", "go_download_sdk") go_rules_dependencies() go_register_toolchains(version = "1.18") go_download_sdk(name = "go_sdk_old", version = "1.17.6") オプション --extra_toolchains=@go_sdk_old//:go_linux_amd64 で切り変える 14

Slide 15

Slide 15 text

おまけ:BazelのGo以外の用途 コンテナの作成(rules_docker) Helm による GKE へのデプロイ(自作ルール) 設定ファイルの自作テストスイートのビルドと実行 配布されているソフトウェアのパッケージ化 サーバー構成図(diagrams)の生成(rules_docker) Elm プロジェクトのビルドとテスト(自作ルール) OpenAPI のビルド(自作ルール) Ruby プロジェクトのテストと静的型検査(rules_ruby) Rust 製 OSS のインストール(rules_rust) 15

Slide 16

Slide 16 text

まとめ

Slide 17

Slide 17 text

まとめ モンストのサーバーサイドの本体は Ruby です 開発を支援する自作ツールで Go が使われています サーバーに配布したい自作 CLI ツール GKE上で動かしてる自作アプリケーション モンスト本体の一部機能でも Go が使われています WebSockets サーバー レコメンドサーバー これらはモノレポ + Bazel で効率よく管理されています おまけ:他にもさまざまな用途で Bazel が使われています 17

Slide 18

Slide 18 text

おしまい