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

エンジニアがドメインロジックに 集中するためのコアパッケージ整備 / freee prepare a core package for microservice

Makoto Shiga
January 21, 2020

エンジニアがドメインロジックに 集中するためのコアパッケージ整備 / freee prepare a core package for microservice

Makoto Shiga

January 21, 2020
Tweet

More Decks by Makoto Shiga

Other Decks in Technology

Transcript

  1. freee 株式会社

    エンジニアがドメインロジックに

    集中するためのコアパッケージ整備

    2020.01.21

    View full-size slide

  2. ● 新卒はソシャゲバックエンド ( Perl )

    ● 2社目アニメ関係の会社でレガシーシステムの
    AWS移管など

    ● 2017年8月 freeeにjoin

    ○ サービス基盤チーム

    ○ スピード改善と負債返却が好き

    ○ 最近はデッドコードを殲滅させる方法を考えて
    る


    Shiga Makoto / @MacoTasu
    志賀 誠

    freee株式会社 / サービス基盤 / エンジニア

    2

    View full-size slide

  3. 3
    コアパッケージが指すもの

    ● 今回の話では各サービスで共通して使われるパッケージのこと

    ○ e.g. logger, error, security周りの対応 etc...

    View full-size slide

  4. 4
    話すこと

     03 コアパッケージ導入

     02 コアパッケージ仕様策定・作成

     01 コアパッケージ作成に至る背景

     04 振り返り・まとめ


    View full-size slide

  5. 01 コアパッケージを作成にいたる背景

    5
    Section

    View full-size slide

  6. freeeにおけるサービスの変化


    View full-size slide

  7. 8
    これまでのfreeeのサービス

    ● 主要なサービスは大体がRails

    ● RailsなのでComponent周りは大体同じ構成

    ● Componentで足りないものは、社内のgem等を利用

    ● Railにのっているので、improvementやbugfixなどの恩恵にあやかれて
    いた


    View full-size slide

  8. 2018年

    フィーチャーリリース数


    278件



    リリースカテゴリ

    既存機能の改善・拡充

    78.8%
    新機能リリース

    15.8%

    その他(セキュリティ強化等) 

    5. 4%


    View full-size slide

  9. 10
    ファットになったRailsサービス

    ● Deployに時間がかかる

    ● コード全体の見通しが悪くなった

    ○ 設計の問題でもある
    ● プロダクトに関わる人が増え、機能の責任の境界が不明瞭

    ● etc...


    View full-size slide

  10. 11
    2018年はマイクロサービス開発が進む

    ● モノリシックから分離できる機能のマイクロサービス化

    ○ メモリフットプリント、学習のしやすさなどからGoが多い
    ● Kubernetesを使ったマイクロサービスの基盤が整う

    ● 2019年も続々とマイクロサービス誕生


    View full-size slide

  11. 12
    マイクロサービスの数


    View full-size slide

  12. 13
    誕生したGoのマイクロサービス

    独自実装 A
    Aをベースにし
    た独自実装 etc ...
    ※図はイメージ


    View full-size slide

  13. 14
    マイクロサービス化を経て

    ● Pros

    ○ モノリシックな開発のときに抱えていた問題が解決
    ○ 同時並行で複数のマイクロサービスの開発が進み、それぞれで知
    見が溜まった
    ● Cons

    ○ 各チーム間でノウハウの共有がうまくいかずに、ミドルウェア周りの
    整備の工数が増えていた
    ○ 微妙に構成が違うサービスが生まれた

    View full-size slide

  14. 15
    本来あるべき姿

    ● エンジニアの多くはユーザに届けたい価値があって開発している

    ○ loggerやerrorなどの機能も必要だが、各サービス単位で作り込ま
    なきゃいけない状況は本質ではない
    サービス基盤が共通で必要なパッケージを作成

    各エンジニアはドメインロジックに集中できるようにする


    View full-size slide

  15. 16
    コアパッケージを使えば

    マイクロサービスを簡単に作成でき

    利用者はドメインロジックのみを作り込め
    ばいい状態を目指す

    目指すべきゴール


    View full-size slide

  16. 02 コアパッケージを仕様策定・実装

    17
    Section

    View full-size slide

  17. どんなパッケージを作るべきか


    View full-size slide

  18. 19
    ターゲットになる範囲


    View full-size slide

  19. 20
    共通部分の洗い出し

    ● やったこと

    ○ 全マイクロサービスのコードを読んで、機能を洗い出す
    ○ 使用感をGoogleDocs上で、各サービス担当者にヒアリング
    ○ 愚直に調べた

    View full-size slide

  20. 21
    調査段階で気にした点

    ● 外部パッケージはGoらしい作りになっているか

    ○ contextを受け取れる場合、中継し後ろに渡している
    ○ 異常系のときはerrorを返す、panicは致命的な問題だけ
    ○ goroutine safeな作りになっているか
    ○ goのエコシステムを利用しているか
    ■ golint, go vet…
    ● 開発がアクティブであるか、スター数、今後の展望など


    View full-size slide

  21. コアパッケージ作成


    View full-size slide

  22. 23
    パッケージ作成で気にしたポイント

    ● デファクトとしてのパッケージを作る

    ● 拡張性

    ● 簡単に組み込める


    View full-size slide

  23. 24
    パッケージ作成で気にしたポイント

    ● デファクトとしてのパッケージを作る

    ● 拡張性

    ● 簡単に組み込める


    View full-size slide

  24. 25
    デファクトとしてのパッケージを作る

    ● 提供するパッケージは使えば、品質の保証と改修の恩恵を受けれる
    という意味でのデファクト

    ● 強制して使ってくれというものではない

    ○ ※ セキュリティ関連の対応は除く
    ● 利用者の技術選定の余地は残す


    View full-size slide

  25. 26
    パッケージ作成で気にしたポイント

    ● デファクトとしてのパッケージを作る

    ● 拡張性

    ● 簡単に組み込める


    View full-size slide

  26. 27
    拡張性

    ● 利用者側の様々なユースケースで使えるように拡張性をもたせる

    ● 詳細な振る舞いなど、外から渡したいであろうものはinterfaceを用い
    たダッグタイピングを使う

    ● 実装は go-cloudを参考


    View full-size slide

  27. 28
    拡張性: HealthCheck pkgの例

    // Checker wraps the CheckHealth method.
    type Checker interface {
    CheckHealth(strict bool) error
    }
    type entry struct {
    checker Checker
    }
    // Service provides health check HTTP handlers.
    type Service struct {
    entries []entry
    }
    // Add appends for Checker.
    func (s *Service) Add(name string, c Checker) {
    // … appends Checker into entries.
    }

    // CheckReadiness returns error if any checker is
    unhealthy.
    func (s *Service) CheckReadiness(strict bool) error
    {
    for _, e := range s.entries {
    if err := e.checker.CheckHealth(strict); err
    != nil {
    ...
    }
    }
    return nil
    }


    View full-size slide

  28. 29
    パッケージ作成で気にしたポイント

    ● デファクトとしてのパッケージを作る

    ● 拡張性

    ● 簡単に組み込める


    View full-size slide

  29. 30
    簡単に組み込める

    ● 利用されてこそ価値があるので簡単に組み込めることは重要

    ● パッケージ導入にあたって依存関係にある箇所の解決は面倒

    ● Googleが作っているwireというパッケージを使う


    View full-size slide

  30. wireとは

    ● wireは静的DI(Dependency Injection)ツール

    ○ パッケージから設定の値など依存に当たる部分を別に切り出して、
    注入という形で後から読み込むことで疎なパッケージを実現できる
    ● wireはシンプルにいうとProviderとInjectorの2つの概念がある

    31

    View full-size slide

  31. Provider

    32
    DB
    package
    ● 特定の型を返すために必要な引数(dependency)を受け取り、返り値
    として特定の型を返す

    DB
    接続情報
    接続情報を受け取り

    sql.DBを返す関数

    依存にあたる引数


    View full-size slide

  32. Injector

    33
    DB
    package
    ● Providerを組み合わせて依存関係を解決し、特定の型を返す

    Injector.go
    config
    package
    接続情報
    DBを使う
    Server
    package
    Providerを並べる


    View full-size slide

  33. Injector

    34
    DB
    package
    ● Providerを組み合わせて依存関係を解決し、特定の型を返す

    Injector.go
    config
    package
    接続情報
    DBを使う
    Server
    package
    wire_gen.go
    Providerを並べる

    wire genコマンド実行

    DBコネクションを持つServer
    のオブジェクト生成するコード
    を生成


    View full-size slide

  34. 35
    コアパッケージ作成の改善点

    ● 作成段階でユーザにとってあるべき、使いやすいパッケージとはにつ
    いて議論することに時間を要しすぎた

    ○ 実際に使われていないものの最適解を見つけること難しい
    ○ 2人の間での理想が見えたら、迷わず作りきってフィードバックをも
    らうことが最短ルートだった

    View full-size slide

  35. 03 コアパッケージ導入

    36
    Section

    View full-size slide

  36. 37
    ドッグフーディングしてもらう


    View full-size slide

  37. 38
    アナウンス

    ● 社内のQiitaに使い方を書く

    ● 社内のSlack #go などに告知を流す

    ● コアパッケージを使ったチュートリアルを作成

    ○ claatというツールを使い、markdownからCodelabs形式の画面
    を作成

    View full-size slide

  38. 39
    作成したチュートリアル


    View full-size slide

  39. 40
    社内のGo大好きな一部の人は使っ
    てくれた


    View full-size slide

  40. 41
    まだ全体で見たら使われてない状況 


    View full-size slide

  41. 42
    課題を整理

    ● パッケージが多すぎてイマイチ何があるかわからない

    ● 使うとどういう利点があるか伝えれてきれていない

    ● 使われる物を作れていなかった可能性もある?



    View full-size slide

  42. 43
    対応

    ● エンジニアに親しみがあるGodocをちゃんと整備する

    ● 社内のエンジニア皆が集まる場で宣伝しより認知度あげる

    ● マイクロサービス委員会をつくる

    ● 各チームの目標にのせる


    View full-size slide

  43. 44
    対応

    ● エンジニアに親しみがあるGodocをちゃんと整備する

    ● 社内のエンジニア皆が集まる場で宣伝しより認知度あげる

    ● マイクロサービス委員会をつくる

    ● 各チームの目標にのせる


    View full-size slide

  44. 45
    委員会とは

    ● 弊社独自の文化(呼び方)

    ● ○○委員会は、○○について興味・一家言ある人達が有志で集まっ
    て○○について話し合い、時には社内のデファクトを定義したりする 

    ● マイクロサービス委員会、フロントエンド委員会 etc...


    View full-size slide

  45. 46
    マイクロサービス委員会

    ● マイクロサービスのデファクトとは何かついて話し合う場

    ● 参加者

    ○ マイクロサービス開発に関わってるメンバー
    ● コアパッケージを利用した感想やほしい機能などのを話し合い、方針
    を決めていく

    ○ 決まった方針をサービス基盤チームでパッケージに反映
    ○ この場から各機能のデファクト方針ドキュメントが作成された

    View full-size slide

  46. 47
    例: エラー通知

    ● エラーはBugsnagに通知する

    ● projectは基本各サービス単位

    ● 環境がわかるようにステージを作成する

    ○ 検証環境のみタグ名で判別する
    ● severityを適切に設定する

    ● 発生したら通知を受けて即対応、平常時は0

    ● サービスに関するmetadataの情報と、追加の情報を設定できるように
    する

    ● WARN, ERRORはSlackなどに通知すること


    View full-size slide

  47. 48
    対応

    ● エンジニアに親しみがあるGodocをちゃんと整備する

    ● 社内のエンジニア皆が集まる場で宣伝しより認知度あげる

    ● マイクロサービス委員会というマイクロサービス関係者が集まる場を
    用意する

    ● 各チームの目標にのせる


    View full-size slide

  48. 49
    各チームの目標にのせる

    ● freeeでは3ヶ月ごとにチームで取り組む目標を決めており、そこにの
    せてもらうと導入も捗る

    ○ 各プロダクトの責任ある人に依頼し、チームの目標に乗せてもらい
    導入進めている

    View full-size slide

  49. 50
    経過

    Goのマイクロサービス系で

    ほぼ導入の目処は経ってきた


    View full-size slide

  50. 51
    コアパッケージ関連のPR数遷移


    View full-size slide

  51. 04 振り返り・まとめ

    52
    Section

    View full-size slide

  52. 53
    コアパッケージ整備を進めてみて

    ● 散らばっていたノウハウを吸い上げ、デファクトについて言語化、共通
    認識を作れた

    ● 既存サービスの基底部分を見直し・改善が進んだ

    ● 爆速でマイクロサービスを立ち上げられる基盤ができた


    View full-size slide

  53. 54
    まとめ

    ● 整備のタイミングはノウハウがたまり、サービスが増え始める前のタイ
    ミングが効果的

    ● 共通して使われるパッケージの作り方はgo-cloudがかなり参考になる

    ● 整備、導入をする際は会社としてちゃんとリソース割くこと大事


    View full-size slide

  54. スモールビジネスを、

    世界の主役に。

    View full-size slide

  55. 56
    参考リンク

    ● freeeのマイクロサービス基盤とWire導入

    ● wireやhealthパッケージを作成する際に参考

    ○ github.com/google/go-cloud

    View full-size slide