January 23, 2020

DMM.go #1

DMM さんの Go の勉強会に行ってきたので、その時のメモ。

https://dmm.connpass.com/event/157222/

適宜、スライド追記されたら更新する予定。

タイムスケジュール

dmm_go_01

c.f. DMM.go #1 (スクショがダメだったら、削除します。)

内容

オープニング・開催趣旨 @i35_267

Cloud Native な時代に考える monorepo @y_matsuwitter

Cloud Native 時代の開発と現状

  • マイクロサービスが前提になってきている
  • 組織戦略とも絡んでくるよね。ってなって monorepo をテーマにしようと思った。

改めて、Cloud Native とは

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 のキャッシュディレクトリで実施する必要がある。

PRACTICAL DISTRIBUTED TRACING @HatsuneMiku3939

PRACTICAL DISTRIBUTED TRACING

マイクロサービスで出てくる。分散トレーシングの話。

  • 分散アプリの性能を計測する仕組み。
  • 従来の 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…

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
      • コピペで行ける
  • 大規模なら Agent あり
    • 各 instance に OpenCensus Agent を用意して、各種サービスから Agent に送る
      • Kubernetes なら、daemonset で用意する。
    • 一度 Agent が受けて、その後、backend に送れば ok.

最後に

  • ただ、OpenCensus は OpenTracing と統合されて、OpenTelementary になる。

VCR in Go:モック自動生成で楽しちゃう話 @yyh_gl

はじめに

  • 皆さんテスト書いてますか?
  • 外部システムをモック化したい
  • モック管理あるある
    • ただ、「モックだから動けばいっか?」みたいなことが多いはず。
  • モックを手動で作成する時点でもうきつい。
  • なので、モックコードを自動生成する
    • OpenAPI(Swagger)
    • Video Cassette Recorder

VCR

  • 大事なのは、確実に、実際のレスポンスをモック化できること
  • 紹介するのは、dnaeon/go-vcr
基本的な要素は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

参考

(C) Jun Kitamura 2020