Slide 1

Slide 1 text

freee 株式会社
 エンジニアがドメインロジックに
 集中するためのコアパッケージ整備
 2020.01.21

Slide 2

Slide 2 text

● 新卒はソシャゲバックエンド ( Perl )
 ● 2社目アニメ関係の会社でレガシーシステムの AWS移管など
 ● 2017年8月 freeeにjoin
 ○ サービス基盤チーム
 ○ スピード改善と負債返却が好き
 ○ 最近はデッドコードを殲滅させる方法を考えて る
 
 Shiga Makoto / @MacoTasu 志賀 誠
 freee株式会社 / サービス基盤 / エンジニア
 2

Slide 3

Slide 3 text

3 コアパッケージが指すもの
 ● 今回の話では各サービスで共通して使われるパッケージのこと
 ○ e.g. logger, error, security周りの対応 etc...

Slide 4

Slide 4 text

4 話すこと
  03 コアパッケージ導入
  02 コアパッケージ仕様策定・作成
  01 コアパッケージ作成に至る背景
  04 振り返り・まとめ


Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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


Slide 7

Slide 7 text


 PRODUCTS

Slide 8

Slide 8 text

8 これまでのfreeeのサービス
 ● 主要なサービスは大体がRails
 ● RailsなのでComponent周りは大体同じ構成
 ● Componentで足りないものは、社内のgem等を利用
 ● Railにのっているので、improvementやbugfixなどの恩恵にあやかれて いた


Slide 9

Slide 9 text

2018年
 フィーチャーリリース数
 
 278件
 
 
 リリースカテゴリ
 既存機能の改善・拡充
 78.8% 新機能リリース
 15.8%
 その他(セキュリティ強化等) 
 5. 4%


Slide 10

Slide 10 text

10 ファットになったRailsサービス
 ● Deployに時間がかかる
 ● コード全体の見通しが悪くなった
 ○ 設計の問題でもある ● プロダクトに関わる人が増え、機能の責任の境界が不明瞭
 ● etc...


Slide 11

Slide 11 text

11 2018年はマイクロサービス開発が進む
 ● モノリシックから分離できる機能のマイクロサービス化
 ○ メモリフットプリント、学習のしやすさなどからGoが多い ● Kubernetesを使ったマイクロサービスの基盤が整う
 ● 2019年も続々とマイクロサービス誕生


Slide 12

Slide 12 text

12 マイクロサービスの数


Slide 13

Slide 13 text

13 誕生したGoのマイクロサービス
 独自実装 A Aをベースにし た独自実装 etc ... ※図はイメージ


Slide 14

Slide 14 text

14 マイクロサービス化を経て
 ● Pros
 ○ モノリシックな開発のときに抱えていた問題が解決 ○ 同時並行で複数のマイクロサービスの開発が進み、それぞれで知 見が溜まった ● Cons
 ○ 各チーム間でノウハウの共有がうまくいかずに、ミドルウェア周りの 整備の工数が増えていた ○ 微妙に構成が違うサービスが生まれた

Slide 15

Slide 15 text

15 本来あるべき姿
 ● エンジニアの多くはユーザに届けたい価値があって開発している
 ○ loggerやerrorなどの機能も必要だが、各サービス単位で作り込ま なきゃいけない状況は本質ではない サービス基盤が共通で必要なパッケージを作成
 各エンジニアはドメインロジックに集中できるようにする


Slide 16

Slide 16 text

16 コアパッケージを使えば
 マイクロサービスを簡単に作成でき
 利用者はドメインロジックのみを作り込め ばいい状態を目指す
 目指すべきゴール


Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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


Slide 19

Slide 19 text

19 ターゲットになる範囲


Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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


Slide 22

Slide 22 text

コアパッケージ作成


Slide 23

Slide 23 text

23 パッケージ作成で気にしたポイント
 ● デファクトとしてのパッケージを作る
 ● 拡張性
 ● 簡単に組み込める


Slide 24

Slide 24 text

24 パッケージ作成で気にしたポイント
 ● デファクトとしてのパッケージを作る
 ● 拡張性
 ● 簡単に組み込める


Slide 25

Slide 25 text

25 デファクトとしてのパッケージを作る
 ● 提供するパッケージは使えば、品質の保証と改修の恩恵を受けれる という意味でのデファクト
 ● 強制して使ってくれというものではない
 ○ ※ セキュリティ関連の対応は除く ● 利用者の技術選定の余地は残す


Slide 26

Slide 26 text

26 パッケージ作成で気にしたポイント
 ● デファクトとしてのパッケージを作る
 ● 拡張性
 ● 簡単に組み込める


Slide 27

Slide 27 text

27 拡張性
 ● 利用者側の様々なユースケースで使えるように拡張性をもたせる
 ● 詳細な振る舞いなど、外から渡したいであろうものはinterfaceを用い たダッグタイピングを使う
 ● 実装は go-cloudを参考


Slide 28

Slide 28 text

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 } 
 


Slide 29

Slide 29 text

29 パッケージ作成で気にしたポイント
 ● デファクトとしてのパッケージを作る
 ● 拡張性
 ● 簡単に組み込める


Slide 30

Slide 30 text

30 簡単に組み込める
 ● 利用されてこそ価値があるので簡単に組み込めることは重要
 ● パッケージ導入にあたって依存関係にある箇所の解決は面倒
 ● Googleが作っているwireというパッケージを使う
 


Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

Provider
 32 DB package ● 特定の型を返すために必要な引数(dependency)を受け取り、返り値 として特定の型を返す
 DB 接続情報 接続情報を受け取り
 sql.DBを返す関数
 依存にあたる引数


Slide 33

Slide 33 text

Injector
 33 DB package ● Providerを組み合わせて依存関係を解決し、特定の型を返す
 Injector.go config package 接続情報 DBを使う Server package Providerを並べる


Slide 34

Slide 34 text

Injector
 34 DB package ● Providerを組み合わせて依存関係を解決し、特定の型を返す
 Injector.go config package 接続情報 DBを使う Server package wire_gen.go Providerを並べる
 wire genコマンド実行
 DBコネクションを持つServer のオブジェクト生成するコード を生成


Slide 35

Slide 35 text

35 コアパッケージ作成の改善点
 ● 作成段階でユーザにとってあるべき、使いやすいパッケージとはにつ いて議論することに時間を要しすぎた
 ○ 実際に使われていないものの最適解を見つけること難しい ○ 2人の間での理想が見えたら、迷わず作りきってフィードバックをも らうことが最短ルートだった

Slide 36

Slide 36 text

03 コアパッケージ導入
 36 Section

Slide 37

Slide 37 text

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


Slide 38

Slide 38 text

38 アナウンス
 ● 社内のQiitaに使い方を書く
 ● 社内のSlack #go などに告知を流す
 ● コアパッケージを使ったチュートリアルを作成
 ○ claatというツールを使い、markdownからCodelabs形式の画面 を作成

Slide 39

Slide 39 text

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


Slide 40

Slide 40 text

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


Slide 41

Slide 41 text

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


Slide 42

Slide 42 text

42 課題を整理
 ● パッケージが多すぎてイマイチ何があるかわからない
 ● 使うとどういう利点があるか伝えれてきれていない
 ● 使われる物を作れていなかった可能性もある?
 
 


Slide 43

Slide 43 text

43 対応
 ● エンジニアに親しみがあるGodocをちゃんと整備する
 ● 社内のエンジニア皆が集まる場で宣伝しより認知度あげる
 ● マイクロサービス委員会をつくる
 ● 各チームの目標にのせる


Slide 44

Slide 44 text

44 対応
 ● エンジニアに親しみがあるGodocをちゃんと整備する
 ● 社内のエンジニア皆が集まる場で宣伝しより認知度あげる
 ● マイクロサービス委員会をつくる
 ● 各チームの目標にのせる


Slide 45

Slide 45 text

45 委員会とは
 ● 弊社独自の文化(呼び方)
 ● ○○委員会は、○○について興味・一家言ある人達が有志で集まっ て○○について話し合い、時には社内のデファクトを定義したりする 
 ● マイクロサービス委員会、フロントエンド委員会 etc...


Slide 46

Slide 46 text

46 マイクロサービス委員会
 ● マイクロサービスのデファクトとは何かついて話し合う場
 ● 参加者
 ○ マイクロサービス開発に関わってるメンバー ● コアパッケージを利用した感想やほしい機能などのを話し合い、方針 を決めていく
 ○ 決まった方針をサービス基盤チームでパッケージに反映 ○ この場から各機能のデファクト方針ドキュメントが作成された

Slide 47

Slide 47 text

47 例: エラー通知
 ● エラーはBugsnagに通知する
 ● projectは基本各サービス単位
 ● 環境がわかるようにステージを作成する
 ○ 検証環境のみタグ名で判別する ● severityを適切に設定する
 ● 発生したら通知を受けて即対応、平常時は0
 ● サービスに関するmetadataの情報と、追加の情報を設定できるように する
 ● WARN, ERRORはSlackなどに通知すること


Slide 48

Slide 48 text

48 対応
 ● エンジニアに親しみがあるGodocをちゃんと整備する
 ● 社内のエンジニア皆が集まる場で宣伝しより認知度あげる
 ● マイクロサービス委員会というマイクロサービス関係者が集まる場を 用意する
 ● 各チームの目標にのせる


Slide 49

Slide 49 text

49 各チームの目標にのせる
 ● freeeでは3ヶ月ごとにチームで取り組む目標を決めており、そこにの せてもらうと導入も捗る
 ○ 各プロダクトの責任ある人に依頼し、チームの目標に乗せてもらい 導入進めている

Slide 50

Slide 50 text

50 経過
 Goのマイクロサービス系で
 ほぼ導入の目処は経ってきた


Slide 51

Slide 51 text

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


Slide 52

Slide 52 text

04 振り返り・まとめ
 52 Section

Slide 53

Slide 53 text

53 コアパッケージ整備を進めてみて
 ● 散らばっていたノウハウを吸い上げ、デファクトについて言語化、共通 認識を作れた
 ● 既存サービスの基底部分を見直し・改善が進んだ
 ● 爆速でマイクロサービスを立ち上げられる基盤ができた


Slide 54

Slide 54 text

54 まとめ
 ● 整備のタイミングはノウハウがたまり、サービスが増え始める前のタイ ミングが効果的
 ● 共通して使われるパッケージの作り方はgo-cloudがかなり参考になる
 ● 整備、導入をする際は会社としてちゃんとリソース割くこと大事


Slide 55

Slide 55 text

スモールビジネスを、
 世界の主役に。

Slide 56

Slide 56 text

56 参考リンク
 ● freeeのマイクロサービス基盤とWire導入
 ● wireやhealthパッケージを作成する際に参考
 ○ github.com/google/go-cloud