Slide 1

Slide 1 text

サービス開発速度に着目した ソフトウェアアーキテクチャ 成田 一生
 クックパッド株式会社 執行役 CTO 2018/06/15 ϝσΟΞίϯςϯπಛผߨٛ*

Slide 2

Slide 2 text

੒ాҰੜ ͳΔ͍͍ͨͬͤ !NJSBLVJ ΫοΫύουגࣜձࣾࣥߦ໾$50 ೥ੜ·Ε Ѫ஌ݝग़਎

Slide 3

Slide 3 text

4/4 ࡱӨ ˞ൃදࢿྉ͸ࣄޙެ։͠·͢ γϟολʔԻ ✔ ✔ ✗ ͝͸Μ ✔

Slide 4

Slide 4 text

今日話すこと • サービスを素早く開発し、
 長く運用するということ • サービスや組織の成長に合わせて
 どのような技術投資をしてきたか

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

毎日の料理を楽しみにする Make everyday cooking fun ! Since 1997

Slide 7

Slide 7 text

ྉཧϨγϐ౤ߘɾݕࡧαʔϏε

Slide 8

Slide 8 text

શੈք
 ݄ؒར༻ऀ਺໿ઍສ ༗ྉձһ໿ສਓҎ্ ˞೥݄࣌఺ !" # ! શੈք໿ສϨγϐ

Slide 9

Slide 9 text

会員事業 広告事業 Revenue sources (ユーザー向け:月額280円) (クライアント向け) ˞੫ൈ͖

Slide 10

Slide 10 text

100ヶ国でNo.1を目指して

Slide 11

Slide 11 text

英語

Slide 12

Slide 12 text

インドネシア語

Slide 13

Slide 13 text

スペイン語

Slide 14

Slide 14 text

アラビア語

Slide 15

Slide 15 text

食文化の数=言語の数?

Slide 16

Slide 16 text

スペイン語が公用語 25%以上の割合で話されている 10 - 20%の割合で話されている 5 - 9.9%の割合で話されている スペイン

Slide 17

Slide 17 text

食文化の数≠言語の数 • 国や地域が異なれば
 気候 / 食材 / 味の好み / 信仰
 などが異なる

Slide 18

Slide 18 text

23言語 / 68か国 対応 ※2018年6月時点

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

歴史

Slide 21

Slide 21 text

Slide 22

Slide 22 text

Slide 23

Slide 23 text

Slide 24

Slide 24 text

Slide 25

Slide 25 text

%$

Slide 26

Slide 26 text

ΤϯδχΞ਺ͷมભ # ######## ######## ### ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ਓ ਓ͘Β͍ ਓ͘Β͍

Slide 27

Slide 27 text

Japan Indonesia Lebanon Hungary Spain US Cookpad Developers are in: UK Taiwan and more… Greece India Russia ೥݄࣌఺

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

೥ೖࣾ౰࣌ɺ ΤϯδχΞ͸ਓఔ౓

Slide 30

Slide 30 text

μΠχϯάςʔϒϧͰશһू·ΕΔ

Slide 31

Slide 31 text

ࠓ ਓఔ౓
 ʢܙൺणΦϑΟεʣ

Slide 32

Slide 32 text

શһ෼ͷ੮͸ͳ͍

Slide 33

Slide 33 text

Slide 34

Slide 34 text

શੈք໿ઍສϢʔβ݄

Slide 35

Slide 35 text

組織・サービスの成長と 技術の関係?

Slide 36

Slide 36 text

「開発しやすさ」 への投資

Slide 37

Slide 37 text

初期から
 「素早い開発サイクル」を
 経営レベルで重視していた →なぜ?

Slide 38

Slide 38 text

サービス開発は
 難しい

Slide 39

Slide 39 text

サービス開発は とにかく難しい

Slide 40

Slide 40 text

サービス開発の難しさ ゴールが分からない Ϣʔβͷཉٻ͸ຊਓΛؚΊͯ୭ʹ΋Θ͔Βͳ͍ Ϣʔβͷཉٻ͸࣌ؒͱͱ΋ʹมΘ͍ͬͯ͘ 今いる場所がわからない ։ൃऀ͸ࣗ෼ͷαʔϏεΛਖ਼͘͠ཧղͰ͖ͳ͍

Slide 41

Slide 41 text

ΰʔϧ͕نఆͰ͖Δ ੡඼ઃܭ ΰʔϧ͕نఆͰ͖ͳ͍ αʔϏε։ൃ

Slide 42

Slide 42 text

Measure Learn product idea data Build 仮説から
 プロダクトに プロダクト
 からデータに データから 仮説に BML ループ

Slide 43

Slide 43 text

サービス開発の必殺技は無いけど、
 学びのサイクルを仕組みにすることは
 できる →いかに高速に失敗できるか

Slide 44

Slide 44 text

技術選定

Slide 45

Slide 45 text

サービス開発と技術選定(1) 早く作って早くリリースできること 実際のユーザに当てない事には、 仮説の価値は分からない

Slide 46

Slide 46 text

サービス開発と技術選定(2) コードの寿命が長い 作って終わりではなく、長い改善の道 環境の変化への追従(技術、人) 技術的負債になりにくくするには?

Slide 47

Slide 47 text

サービス開発と技術選定(3) 組織・事業継続性 来年もその技術って存在するの? エンジニアに嫌われる技術を選ぶことの意味

Slide 48

Slide 48 text

サービス開発に必要な技術 速く書けて、みんなが読めて、
 長期間のメンテがしやすい言語/フレームワーク

Slide 49

Slide 49 text

そんなのあるのか

Slide 50

Slide 50 text

Ruby on Rails はギリギリそう

Slide 51

Slide 51 text

Slide 52

Slide 52 text

Rails? 当時は事例も少なく、
 そこまで流行っているわけではなかったが… 記述量が少なく、可読性が高い
 アジャイル開発に向いているとされていた 現在ではコミュニティが成熟し、定番に

Slide 53

Slide 53 text

「レールに乗る」

Slide 54

Slide 54 text

IUUQTCBTFDBNQDPN

Slide 55

Slide 55 text

IUUQTTQFBLFSEFDLDPNB@NBUTVEBUIFSFDJQFGPSUIFXPSMETMBSHFTUSBJMTNPOPMJUI

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

恒例の rake stats ൛ +----------------------+-------+-------+---------+---------+-----+-------+ | Name | Lines | LOC | Classes | Methods | M/C | LOC/M | +----------------------+-------+-------+---------+---------+-----+-------+ | Controllers | 32806 | 26480 | 311 | 2746 | 8 | 7 | | Helpers | 13384 | 10888 | 17 | 1234 | 72 | 6 | | Models | 74920 | 59022 | 1303 | 6642 | 5 | 6 | | Mailers | 1727 | 1389 | 40 | 170 | 4 | 6 | | Workers | 0 | 0 | 0 | 0 | 0 | 0 | | Chanko units | 6401 | 5333 | 2 | 160 | 80 | 31 | | Libraries | 33764 | 28140 | 381 | 2463 | 6 | 9 | | Feature specs | 44276 | 35545 | 0 | 177 | 0 | 198 | | Request specs | 781 | 615 | 0 | 0 | 0 | 0 | | Routing specs | 406 | 328 | 0 | 0 | 0 | 0 | | Controller specs | 49339 | 40751 | 6 | 77 | 12 | 527 | | Helper specs | 4152 | 3431 | 0 | 9 | 0 | 379 | | Model specs | 65320 | 53596 | 2 | 55 | 27 | 972 | | Worker specs | 0 | 0 | 0 | 0 | 0 | 0 | | Chanko unit specs | 3012 | 2400 | 0 | 1 | 0 | 2398 | | Library specs | 16327 | 13544 | 17 | 78 | 4 | 171 | +----------------------+-------+-------+---------+---------+-----+-------+ | Total |346615 |281462 | 2079 | 13812 | 6 | 18 | +----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: 131252 Test LOC: 150210 Code to Test Ratio: 1:1.1

Slide 58

Slide 58 text

1,300 models

Slide 59

Slide 59 text

でかいと何が起こるのか 起動に時間がかかる テストに時間がかかる 静的解析系ツールが動かない ライブラリが動かない デプロイが大変 レールに乗れない

Slide 60

Slide 60 text

コードや環境の老朽化

Slide 61

Slide 61 text

ͳͥਓ͸ 全部書き直しͨ͘ ͳΔͷ͔

Slide 62

Slide 62 text

2010頃 全リニューアル計画

Slide 63

Slide 63 text

リニューアル計画 (2010) • エンジニア15人くらい • コードが巨大・複雑すぎて、新機能の実装が困難 • そもそも今のサービスはこれでいいのだろうか? • コードもサービスも理想的な状態にした、
 俺たちの考えた最高のクックパッドにしよう w Α͠ϑϧεΫϥονͰॻͧ͘

Slide 64

Slide 64 text

リニューアル大失敗

Slide 65

Slide 65 text

何が起こったのか 「サービスのコアバリューを抽出する」 「綺麗なコードでイチから書き直す」 の両方を同時にやろうとした ˠ͍ͭ·Ͱܦͬͯ΋࣮૷͕ऴΘΒͳ͍

Slide 66

Slide 66 text

仕様の整理と リファクタリングを 同時にやらない方がいい ֶͼ

Slide 67

Slide 67 text

手遅れになってから やらない ֶͼ

Slide 68

Slide 68 text

2007年の Rails 移行は
 なぜうまくいったのか エンジニア5人 Rails に詳しい社員 0人 それほど日本で流行ってない

Slide 69

Slide 69 text

当時の関係者の証言 • サービスの機能がまだ少なかった • すでにぼろぼろだったから、
 それ以上失敗しようがなかった • そもそもそんなに成功していなかった ‣ (移行はしたが、当初かなり不安定だった) • 若かった

Slide 70

Slide 70 text

ではどうすればいいのか

Slide 71

Slide 71 text

本当に欲しいものは
 何だったのか?

Slide 72

Slide 72 text

なぜ書き直したかったのか • サービスの継続的な改善がしたかった ‣ 謎の複雑なレガシーコードが多すぎて
 機能の改善や追加が困難

Slide 73

Slide 73 text

ϨΨγʔίʔυΛ
 શ෦ॻ͖௚͞ͳͯ͘΋
 ։ൃ଎౓Λམͱͣ͞
 ܧଓతͳվળ͕Ͱ͖ΔΑ͏ʹ ͢Ε͹͍͍ͷͰ͸

Slide 74

Slide 74 text

ϦχϡʔΞϧࣦഊ͕ੜΈग़ͨ͠ Chanko

Slide 75

Slide 75 text

Chanko 本番環境でのトライ&エラーを
 支援する Rails 用 gem Unit という単位で既存コードへのパッチを記述 IUUQTHJUIVCDPNDPPLQBEDIBOLP

Slide 76

Slide 76 text

৽σβΠϯ

Slide 77

Slide 77 text

既存コードの書き換え • レガシーコードをいじるリスク • 雑に書くと予期しないエラーになる場 合があるかも • 新デザインを気軽に検証したいだけな のに!

Slide 78

Slide 78 text

" # 既存のコード A を、スタッフユーザのみに対して ベータ版のコード B に置き換えたい ただし、B は冒険的な実装なので、例外が発生するかもしれない 既存の Controller のコード ベータ版のコード

Slide 79

Slide 79 text

ελοϑͳΒ# #Ͱྫ֎͕ى͖ͨΒ" ελοϑҎ֎ͳΒ" ϑϥάͰ෼ذ͍ͤͯ͘͞ͱίʔυ͕ԚΕ͍ͯ͘

Slide 80

Slide 80 text

ベータ機能の Unit 既存の Controller のコード " # Chanko では、Unit というファイルにベータ機能のロジックを記述する invoke 条件を満たした場合に、既存ロジック (A) の代わりに Unit (B) が実行される B が例外を起こした場合は、元の A が実行されるため、ユーザにはエラーが返らない JOWPLF৚݅

Slide 81

Slide 81 text

無事に価値が認められたら 本番の品質のコードに仕上げる 既存コードを書き換え、Unit ファイルを消す
 (通称 Un-chanko)

Slide 82

Slide 82 text

Chanko • 既存のコードをほぼ汚さずに機能の置 き換え実験ができる(Chanko Unit) • もし Unit 内で例外が起きたら、既存の コードが実行される • Chanko Unit は汚く書いてもいいけ ど、Un-chanko 時にはリファクタリン グしようね、という運用

Slide 83

Slide 83 text

Measure Learn product idea data Build プロダクト
 からデータに データから 仮説に BML ループ 仮説から
 プロダクトに

Slide 84

Slide 84 text

Chanko で実現したこと • 本番環境をステージングのように
 使えるようになった • 本物のデータ、本物のユーザ • 「スタッフ限定」「10%限定」で
 サービスの価値検証

Slide 85

Slide 85 text

すばやく開発しつつ すぐに本番で検証 しかもコードは汚れにくい (消しやすい)

Slide 86

Slide 86 text

コード品質

Slide 87

Slide 87 text

コード品質はビジネスに 影響するか?

Slide 88

Slide 88 text

クックパッドの答え: YES

Slide 89

Slide 89 text

コードの品質 • 可読性 • メンテナンス性 • バグの有無 • セキュリティ

Slide 90

Slide 90 text

コードの品質が影響するもの • 開発効率 • 属人性 w ίʔυͷण໋

Slide 91

Slide 91 text

どこまでやるべきか? やりすぎない 「綺麗なコード」を書くこと自体が目的ではない 事業フェーズにとって必要な品質までを目指す

Slide 92

Slide 92 text

コードレビュー 質の高いコードレビューがコード品質を ある程度担保する 負の遺産を残しにくくなる

Slide 93

Slide 93 text

コードレビューアンチパターン • 些細な文法の好みで揉める ‣ インデント、括弧など ‣ とにかく不毛

Slide 94

Slide 94 text

コード規約があると コードレビューの効率が 良くなる ֶͼ

Slide 95

Slide 95 text

IUUQTHJUIVCDPNDPPLQBETUZMFHVJEF

Slide 96

Slide 96 text

No content

Slide 97

Slide 97 text

特徴 そんなんどっちでも いいだろというのも 結構決めてる

Slide 98

Slide 98 text

3年くらい運用してみて • 最初は反対意見も多かった(僕も) • ビジネスのコードレビューなのに文法の しょうもない論争が展開される、
 みたいなのを見かけなくなった ‣ 文法の論争はスタイルガイドの方で
 やればよい • あってよかったスタイルガイド

Slide 99

Slide 99 text

J04"OESPJEͰ͸ࣗಈίʔυϨϏϡʔCPU %BOHFS Λར༻ IUUQEBOHFSTZTUFNT

Slide 100

Slide 100 text

自動レビューbot • コーディングスタイルの Lint • 静的解析によるバグ検知 • OSSライセンス情報のチェック • アプリのビルド • deploygate 等への配信

Slide 101

Slide 101 text

˞೥݄࣌఺ ࠓिͷϨϏϡʔίϝϯτ਺ ࠓिͷ13਺

Slide 102

Slide 102 text

コードレビューの
 生産性は
 開発効率において
 死活問題

Slide 103

Slide 103 text

効率よく開発しつつ メンテナンス性を保てる ようにするための工夫

Slide 104

Slide 104 text

マイクロサービス

Slide 105

Slide 105 text

IUUQTTQFBLFSEFDLDPNB@NBUTVEBUIFSFDJQFGPSUIFXPSMETMBSHFTUSBJMTNPOPMJUI

Slide 106

Slide 106 text

「モノリシック」な
 サービス

Slide 107

Slide 107 text

No content

Slide 108

Slide 108 text

No content

Slide 109

Slide 109 text

サービス分割のイメージ API

Slide 110

Slide 110 text

API 認証 ユーザ 基盤

Slide 111

Slide 111 text

API 認証 ユーザ基盤 決済

Slide 112

Slide 112 text

API 認証 ユーザ基盤 決済 動画基盤 レシピデータ

Slide 113

Slide 113 text

API 認証 ユーザ基盤 決済 動画基盤 レシピデータ Web

Slide 114

Slide 114 text

マイクロサービス # # 決済 動画基盤 Web ## # # # αʔϏεΛҙຯͷ͋Δ୯ҐͰ෼ׂ͢Δ͜ͱͰ ҰͭҰͭ͸খ͘͞ɺ։ൃ͠΍͘͢ͳΔ

Slide 115

Slide 115 text

メリット • 小さなアプリケーションとして
 開発できる • メンテナンスしやすい • 責任感が持ちやすい • 組織のスケーラビリティ

Slide 116

Slide 116 text

デメリット • 結合テストが困難 • システム全体が爆発的に複雑に ‣ 障害の伝播問題 ‣ 管理の困難さ ‣ 監視、可視化

Slide 117

Slide 117 text

API 認証 ユーザ基盤 決済 動画基盤 レシピデータ Web

Slide 118

Slide 118 text

API 認証 ユーザ基盤 決済 動画基盤 レシピデータ Web

Slide 119

Slide 119 text

API 認証 ユーザ基盤 決済 動画基盤 レシピデータ Web

Slide 120

Slide 120 text

API 認証 ユーザ基盤 決済 動画基盤 レシピデータ Web

Slide 121

Slide 121 text

No content

Slide 122

Slide 122 text

世の中の流れは マイクロサービスへ • Docker を中心としたエコシステムが 急速に発達 • 技術的な「定石」ができつつある

Slide 123

Slide 123 text

サービスメッシュ • マイクロサービス同士を
 適切に連携させて、
 うまく制御する技術

Slide 124

Slide 124 text

&$4UBTL LTQPE サービスA サービスB サービスC αʔϏε͝ͱʹϓϩτίϧΛ࣮૷͢Δඞཁ͕͋ͬͨ ίϯςφ

Slide 125

Slide 125 text

αΠυΧʔͱͯ͠ಈ࡞ͤ͞Δɺ
 ϚΠΫϩαʔϏε޲͚ϓϩΩγ

Slide 126

Slide 126 text

&OWPZͰαʔϏεؒͷ௨৴Λந৅Խ ɾαʔΩοτϒϨʔΧʔ ɾϩΪϯάɺ؂ࢹ౳ͷڞ௨Խ サービスA サービスB サービスC

Slide 127

Slide 127 text

1SPNFUIFVTQSPNWJ[ʹΑΔαʔϏεؒ௨৴ͷՄࢹԽ ʢ࣌ؒʹ༨༟͕͋Ε͹σϞʣ

Slide 128

Slide 128 text

進捗

Slide 129

Slide 129 text

rake stats +----------------------+-------+-------+---------+---------+-----+-------+ | Name | Lines | LOC | Classes | Methods | M/C | LOC/M | +----------------------+-------+-------+---------+---------+-----+-------+ | Controllers | 53487 | 43106 | 578 | 4326 | 7 | 7 | | Helpers | 16467 | 13482 | 19 | 1544 | 81 | 6 | | Models |109238 | 86118 | 1938 | 9700 | 5 | 6 | | Mailers | 2259 | 1821 | 47 | 209 | 4 | 6 | | Workers | 797 | 678 | 23 | 38 | 1 | 15 | | Chanko units | 12737 | 10967 | 20 | 373 | 18 | 27 | | Libraries | 52295 | 43235 | 649 | 3954 | 6 | 8 | | Feature specs | 56569 | 45583 | 0 | 192 | 0 | 235 | | Request specs | 46276 | 39906 | 0 | 18 | 0 | 2215 | | Routing specs | 614 | 495 | 0 | 0 | 0 | 0 | | Controller specs | 64188 | 53000 | 6 | 128 | 21 | 412 | | Helper specs | 84918 | 70300 | 3 | 71 | 23 | 988 | | Model specs |163524 |135337 | 5 | 130 | 26 | 1039 | | Worker specs | 1156 | 959 | 0 | 1 | 0 | 957 | | Chanko unit specs | 9214 | 7596 | 0 | 11 | 0 | 688 | | Library specs | 26054 | 21809 | 25 | 125 | 5 | 172 | +----------------------+-------+-------+---------+---------+-----+-------+ | Total |699793 |574392 | 3313 | 20820 | 6 | 25 | +----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: 199407 Test LOC: 374985 Code to Test Ratio: 1:1.9

Slide 130

Slide 130 text

rake stats +----------------------+-------+-------+---------+---------+-----+-------+ | Name | Lines | LOC | Classes | Methods | M/C | LOC/M | +----------------------+-------+-------+---------+---------+-----+-------+ | Controllers | 32806 | 26480 | 311 | 2746 | 8 | 7 | | Helpers | 13384 | 10888 | 17 | 1234 | 72 | 6 | | Models | 74920 | 59022 | 1303 | 6642 | 5 | 6 | | Mailers | 1727 | 1389 | 40 | 170 | 4 | 6 | | Workers | 0 | 0 | 0 | 0 | 0 | 0 | | Chanko units | 6401 | 5333 | 2 | 160 | 80 | 31 | | Libraries | 33764 | 28140 | 381 | 2463 | 6 | 9 | | Feature specs | 44276 | 35545 | 0 | 177 | 0 | 198 | | Request specs | 781 | 615 | 0 | 0 | 0 | 0 | | Routing specs | 406 | 328 | 0 | 0 | 0 | 0 | | Controller specs | 49339 | 40751 | 6 | 77 | 12 | 527 | | Helper specs | 4152 | 3431 | 0 | 9 | 0 | 379 | | Model specs | 65320 | 53596 | 2 | 55 | 27 | 972 | | Worker specs | 0 | 0 | 0 | 0 | 0 | 0 | | Chanko unit specs | 3012 | 2400 | 0 | 1 | 0 | 2398 | | Library specs | 16327 | 13544 | 17 | 78 | 4 | 171 | +----------------------+-------+-------+---------+---------+-----+-------+ | Total |346615 |281462 | 2079 | 13812 | 6 | 18 | +----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: 131252 Test LOC: 150210 Code to Test Ratio: 1:1.1

Slide 131

Slide 131 text

NPEFMT NPEFMT

Slide 132

Slide 132 text

分割方針 • 開発が活発な部分を切り出す • サービスとして再利用性が高い部分を 切り出す • チームの境界で切り出す • 完璧より実利を目指す

Slide 133

Slide 133 text

おわりに

Slide 134

Slide 134 text

おわりに (1/5) • 開発効率への技術的投資を
 クックパッドは
 組織的・戦略的に行ってきた • (ただし失敗もある)

Slide 135

Slide 135 text

おわりに (2/5) • クックパッドは「毎日の料理を楽しみ にする」サービス開発の会社 • サービス開発はめちゃくちゃ難しい • 最高の道具を使ってやっと
 打席に立てる程度

Slide 136

Slide 136 text

おわりに (3/5) • サービスに「完成」はなく、
 事業が続く限り
 ずっと開発し続けるものである ‣ BML ループ • そのために必要なことはなにか?

Slide 137

Slide 137 text

おわりに (4/5) • サービス開発の技術選定で大事な要素 ‣ 早く作って、早くリリースできる ‣ 捨てやすい ‣ スケーラビリティ
 (組織、トラフィック) ͓ΘΓ

Slide 138

Slide 138 text

おわりに (5/5) • マイクロサービス? ‣ 組織のスケーラビリティのために
 やむを得ない選択 ‣ 世の中のインフラがマイクロサービス
 前提になりつつあり、いいタイミング ͓ΘΓ

Slide 139

Slide 139 text

IUUQTUFDIMJGFDPPLQBEDPN

Slide 140

Slide 140 text

ԠืకΊ੾Γ ΫοΫύουɹΠϯλʔϯ