DMM さんの Go の勉強会に行ってきたので、その時のメモ。
https://dmm.connpass.com/event/157222/
適宜、スライド追記されたら更新する予定。
タイムスケジュール
c.f. DMM.go #1 (スクショがダメだったら、削除します。)
内容
オープニング・開催趣旨 @i35_267
Cloud Native な時代に考える monorepo @y_matsuwitter
Cloud Native 時代の開発と現状
- マイクロサービスが前提になってきている
- 組織戦略とも絡んでくるよね。ってなって monorepo をテーマにしようと思った。
改めて、Cloud Native とは
- CNCF が出している Cloud Native の定義の紹介
- Cloud の利点を適切に理解して、使う必要があるよね。
Cloud Native 時代の基盤の選択肢
- Kubernetes
- Container as a Service
- FaaS
- Managed Service
- とかとか、いろいろなユースケースがあって
- アーキテクチャは、チームと寄り添いながら、運営していく必要がある。
そこで、なんで monorepo なのか?
- アプリケーションが色々散らばっている。
- かつ、そのプロトコルも複数ある。
- 特に Managed Service は、プロトコルが決まっていて、それぞれ使わないといけないプロトコルが決まっていたりする。
- monorepo という選択肢がいいんじゃないか。
monorepo とは?
- Package 間の interface を一括管理できる
なぜ monorepo?
- パッケージ間の interface を 1 つのリポジトリに集約する
- 仕組みの共有が容易。
Go と bazel で Cloud Native な monorepo 運用
課題
- 全サービスのソースコードが集まる
- 全体をビルドしテストするコストは、サービスが拡大するごとに増える
- ビルド方法の多様化
- 様々な基盤に合わせたツールが必要になる
対策
- 賢いビルドツール
- 依存関係の解析
- 依存グラフから再ビルド・再テスト
そこで、bazelの登場
特徴
- 依存関係に応じて、影響する部分を特定ビルド
- ビルド結果のキャッシュにより、不要なビルドを行わない
- キャッシュはローカルだけではなく、リモート環境も指定可能。
- 様々な言語に対応している。
Go と bazel で monorepo
Gazelle
- ビルド対象・依存関係を細かく指定する必要がない。
- 依存関係を自動生成してくれる。
- bazel を運用するには、ほぼ必須(?)
bazel の課題
- 依存関係を全て記述する必要がある
- 各言語
- bazel 自体の機能が豊富すぎる
- 学習コストが高め
- bazel の面倒をみる。DevOps 的なチームが必要。
各ツールとの組み合わせ
- protobuf との相性
- bazel 側機能を利用すると都度 go コードを生成してしまう。
- 生成結果もコミットしたい場合は、bazel を使わない必要がある?
- bazel 側機能を利用すると都度 go コードを生成してしまう。
- ほとんどの生成過程を bazel のキャッシュディレクトリで実施する必要がある。
PRACTICAL DISTRIBUTED TRACING @HatsuneMiku3939
マイクロサービスで出てくる。分散トレーシングの話。
- 分散アプリの性能を計測する仕組み。
- 従来の APM と何が違う?
- 1 リクエスト(従来の APM) -> 複数バックエンド(分散トレーシング)
- 個々のサービスを測定(従来の APM) -> 全体は把握できない。(分散トレーシング)
- リクエスト全体の「処理の流れ」を把握するモノ。
- 処理の単位は、Trace と Span に分かれている
Trace
- システムを貫通するリクエストの集合体
Span
- 作業の単位
- 1 Trace は 1 以上の Span で構成される
- 前後がわかるように親子関係を持っている
基本は、「あるサービスの Outbound は、他のサービスの Inbound。」
Inbound するとき
- とりあえず、新しい Span を生成
- 親子関係を作成する
- TraceID がなかったら、作る
Outbound するとき
- Span ID 伝搬する。
- 基本は Header。(ダメなら、body?)
- gRPC, kafka etc…
- 基本は Header。(ダメなら、body?)
OpenCensus
OpenCensus とは。
- 問題は、ソリューションがいっぱいあって、SDK がそれぞれ異なるが、これを選んだ。
- 一番しっかりできていると思っている。
- いろいろな機能があるが、主な目的は、分散トレーシング。
- StackDriver とか X-ray とかにも export することができる。
やるべき 3 つのこと
- Exporter の初期化
- Jaeger の例を出してますが、ほぼコピペで行ける。
- Inbound トレーシング
- Outbound トレーシング
基本的にこれだけ。
他にも機能がいっぱい!
- gRPC tracing
- Server Clent metric
- DB Integration etc…
実戦運用
- 小規模なら Agent なし
- 直接 backend に送れば ok! e.g. X-ray, Datadog
- コピペで行ける
- 直接 backend に送れば ok! e.g. X-ray, Datadog
- 大規模なら Agent あり
- 各 instance に OpenCensus Agent を用意して、各種サービスから Agent に送る
- Kubernetes なら、daemonset で用意する。
- 一度 Agent が受けて、その後、backend に送れば ok.
- 各 instance に OpenCensus Agent を用意して、各種サービスから Agent に送る
最後に
- ただ、OpenCensus は OpenTracing と統合されて、OpenTelementary になる。
VCR in Go:モック自動生成で楽しちゃう話 @yyh_gl
はじめに
- 皆さんテスト書いてますか?
- 外部システムをモック化したい
- モック管理あるある
- ただ、「モックだから動けばいっか?」みたいなことが多いはず。
- モックを手動で作成する時点でもうきつい。
- なので、モックコードを自動生成する
- OpenAPI(Swagger)
- Video Cassette Recorder
VCR
- 大事なのは、確実に、実際のレスポンスをモック化できること
- 紹介するのは、dnaeon/go-vcr
- vcr/vcrの Go バージョン
基本的な要素は2つ
Recorder
- レスポンスを記録するやつ
- 実態は、構造体
Casete
- 保存したレスポンス
- yaml
特徴と運用方法
- リクエストの同一性について
- デフォルトでは、下記パラメータが同じであれば、同一リクエストとして判定
- 保存内容を修正したいときは、cassette を消せば ok!
- yaml を直接修正は、おすすめしない。
- 運用方法
- STG 環境のレスポンスを保存
- テスト関数ごとにカセットを用意
メリット・デメリット
- メリット
- モックと実システム間の仕様のズレがなくなり。
- HTTP ではなく、ファイルの読み込みでよくなって、早くなる。
- 「ローカルでは動いたのに、、、」が減る!
- デメリット
- アクセストークンの再取得
- カセット単位でレスポンス
チャット小説アプリ TELLER を支える GAE/Go @tomoemon
はじめに
- Go よりかは、プロダクト寄りの話多め。
- チャット型小説アプリ TELLER の紹介
- パッケージ依存関係 CI
- クリーンアーキテクチャに変えてみたが、どこからどこへ依存して良いのか、何をどこに書くべきかわからないメンバーもいた。
- Golang のパッケージ依存関係チェックツールを作って、CI
DI 自動化したい
- DI 自動化したい。wire入れよう!
- 後々ジョインするメンバーの参入障壁があがる?
- 詳細的に言語機能との差異が生まれて負債にならないか?
課題と対策
- 広告で見たストーリーを見つけられない
- 2 年前は検索機能がなかった。
- 色々検索サービスを検討した
- Elasticsearch
- GAE Search
- Algolia
- 機能の学習コスト等の観点から、結局、Algolia にした
- Algolia
- ソートの癖がすごい。
- 料金プランが 1 年スパンでどんどん変わる
- 使い始めて、1 年後には、無料だったものに、従量課金されてた。
- インデックスしたはずが Algolia 上にない
- 問い合わせたら、再インデックスしてくれと言われる
- Redis でランキング集計つらい
- Redis -> BigQuery に変えた。
- ストーリー更新をトリガーにして色々したい
- イベント駆動にした。Cloud Tasks を使って解決できた。
- アダルト画像を上げまくるユーザーをどうにかしたい。
- CGMあるある。
- 元々は、外注して、人力目視チェック。
- Cloud Vision APIを使えばよくね?
- サツマイモの画像でも、Violence な画像と判定されてしまうなどの精度の問題があった。
- 最終的には、一次切り分けとして Cloud Vision API を利用することとした。
- ユーザ権限管理
- Role interface を実装 e.g. func CanXXXX() bool