Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
サービス開発速度に着目したソフトウェアアーキテクチャ/Software architecture for effective service development at Cookpad
Issei Naruta
June 15, 2018
Technology
5
5.6k
サービス開発速度に着目したソフトウェアアーキテクチャ/Software architecture for effective service development at Cookpad
東京大学 メディアコンテンツ特別講義I
Issei Naruta
June 15, 2018
Tweet
Share
More Decks by Issei Naruta
See All by Issei Naruta
mirakui
0
280
mirakui
3
810
mirakui
1
900
mirakui
6
6.3k
mirakui
46
35k
mirakui
173
40k
mirakui
10
11k
mirakui
85
11k
mirakui
88
14k
Other Decks in Technology
See All in Technology
myhomenwlab
1
220
willnet
12
4k
gobeyond20xx
0
140
grapecity_dev
0
130
azara
1
810
nkjzm
0
550
eayedi
1
120
pohjus
0
3.3k
manuelmeyer
0
120
line_developers
PRO
0
170
yosuke_matsuura
PRO
0
170
karabish
0
180
Featured
See All Featured
trallard
13
710
caitiem20
308
17k
smashingmag
230
18k
lauravandoore
11
1.5k
shpigford
165
19k
chriscoyier
499
130k
qrush
285
19k
andyhume
64
3.7k
addyosmani
311
21k
lara
590
61k
skipperchong
8
710
sugarenia
233
850k
Transcript
サービス開発速度に着目した ソフトウェアアーキテクチャ 成田 一生 クックパッド株式会社 執行役 CTO 2018/06/15 ϝσΟΞίϯςϯπಛผߨٛ*
ాҰੜ ͳΔ͍͍ͨͬͤ !NJSBLVJ ΫοΫύουגࣜձࣾࣥߦ$50 ੜ·Ε Ѫݝग़
4/4 ࡱӨ ˞ൃදࢿྉࣄޙެ։͠·͢ γϟολʔԻ ✔ ✔ ✗ ͝Μ ✔
今日話すこと • サービスを素早く開発し、 長く運用するということ • サービスや組織の成長に合わせて どのような技術投資をしてきたか
None
毎日の料理を楽しみにする Make everyday cooking fun ! Since 1997
ྉཧϨγϐߘɾݕࡧαʔϏε
શੈք ݄ؒར༻ऀઍສ ༗ྉձһສਓҎ্ ˞݄࣌ !" # ! શੈքສϨγϐ
会員事業 広告事業 Revenue sources (ユーザー向け:月額280円) (クライアント向け) ˞੫ൈ͖
100ヶ国でNo.1を目指して
英語
インドネシア語
スペイン語
アラビア語
食文化の数=言語の数?
スペイン語が公用語 25%以上の割合で話されている 10 - 20%の割合で話されている 5 - 9.9%の割合で話されている スペイン
食文化の数≠言語の数 • 国や地域が異なれば 気候 / 食材 / 味の好み / 信仰
などが異なる
23言語 / 68か国 対応 ※2018年6月時点
None
歴史
%$
ΤϯδχΞͷมભ # ######## ######## ### ########## ########## ########## ########## ##########
########## ########## ########## ########## ########## ਓ ਓ͘Β͍ ਓ͘Β͍
Japan Indonesia Lebanon Hungary Spain US Cookpad Developers are in:
UK Taiwan and more… Greece India Russia ݄࣌
None
ೖࣾ࣌ɺ ΤϯδχΞਓఔ
μΠχϯάςʔϒϧͰશһू·ΕΔ
ࠓ ਓఔ ʢܙൺणΦϑΟεʣ
શһͷ੮ͳ͍
શੈքઍສϢʔβ݄
組織・サービスの成長と 技術の関係?
「開発しやすさ」 への投資
初期から 「素早い開発サイクル」を 経営レベルで重視していた →なぜ?
サービス開発は 難しい
サービス開発は とにかく難しい
サービス開発の難しさ ゴールが分からない ϢʔβͷཉٻຊਓΛؚΊͯ୭ʹΘ͔Βͳ͍ Ϣʔβͷཉٻ࣌ؒͱͱʹมΘ͍ͬͯ͘ 今いる場所がわからない ։ൃऀࣗͷαʔϏεΛਖ਼͘͠ཧղͰ͖ͳ͍
ΰʔϧ͕نఆͰ͖Δ ઃܭ ΰʔϧ͕نఆͰ͖ͳ͍ αʔϏε։ൃ
Measure Learn product idea data Build 仮説から プロダクトに プロダクト からデータに
データから 仮説に BML ループ
サービス開発の必殺技は無いけど、 学びのサイクルを仕組みにすることは できる →いかに高速に失敗できるか
技術選定
サービス開発と技術選定(1) 早く作って早くリリースできること 実際のユーザに当てない事には、 仮説の価値は分からない
サービス開発と技術選定(2) コードの寿命が長い 作って終わりではなく、長い改善の道 環境の変化への追従(技術、人) 技術的負債になりにくくするには?
サービス開発と技術選定(3) 組織・事業継続性 来年もその技術って存在するの? エンジニアに嫌われる技術を選ぶことの意味
サービス開発に必要な技術 速く書けて、みんなが読めて、 長期間のメンテがしやすい言語/フレームワーク
そんなのあるのか
Ruby on Rails はギリギリそう
Rails? 当時は事例も少なく、 そこまで流行っているわけではなかったが… 記述量が少なく、可読性が高い アジャイル開発に向いているとされていた 現在ではコミュニティが成熟し、定番に
「レールに乗る」
IUUQTCBTFDBNQDPN
IUUQTTQFBLFSEFDLDPNB@NBUTVEBUIFSFDJQFGPSUIFXPSMETMBSHFTUSBJMTNPOPMJUI
None
恒例の 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
1,300 models
でかいと何が起こるのか 起動に時間がかかる テストに時間がかかる 静的解析系ツールが動かない ライブラリが動かない デプロイが大変 レールに乗れない
コードや環境の老朽化
ͳͥਓ 全部書き直しͨ͘ ͳΔͷ͔
2010頃 全リニューアル計画
リニューアル計画 (2010) • エンジニア15人くらい • コードが巨大・複雑すぎて、新機能の実装が困難 • そもそも今のサービスはこれでいいのだろうか? • コードもサービスも理想的な状態にした、
俺たちの考えた最高のクックパッドにしよう w Α͠ϑϧεΫϥονͰॻͧ͘
リニューアル大失敗
何が起こったのか 「サービスのコアバリューを抽出する」 「綺麗なコードでイチから書き直す」 の両方を同時にやろうとした ˠ͍ͭ·Ͱܦ࣮͕ͬͯऴΘΒͳ͍
仕様の整理と リファクタリングを 同時にやらない方がいい ֶͼ
手遅れになってから やらない ֶͼ
2007年の Rails 移行は なぜうまくいったのか エンジニア5人 Rails に詳しい社員 0人 それほど日本で流行ってない
当時の関係者の証言 • サービスの機能がまだ少なかった • すでにぼろぼろだったから、 それ以上失敗しようがなかった • そもそもそんなに成功していなかった ‣ (移行はしたが、当初かなり不安定だった)
• 若かった
ではどうすればいいのか
本当に欲しいものは 何だったのか?
なぜ書き直したかったのか • サービスの継続的な改善がしたかった ‣ 謎の複雑なレガシーコードが多すぎて 機能の改善や追加が困難
ϨΨγʔίʔυΛ શ෦ॻ͖͞ͳͯ͘ ։ൃΛམͱͣ͞ ܧଓతͳվળ͕Ͱ͖ΔΑ͏ʹ ͢Ε͍͍ͷͰ
ϦχϡʔΞϧࣦഊ͕ੜΈग़ͨ͠ Chanko
Chanko 本番環境でのトライ&エラーを 支援する Rails 用 gem Unit という単位で既存コードへのパッチを記述 IUUQTHJUIVCDPNDPPLQBEDIBOLP
৽σβΠϯ
既存コードの書き換え • レガシーコードをいじるリスク • 雑に書くと予期しないエラーになる場 合があるかも • 新デザインを気軽に検証したいだけな のに!
" # 既存のコード A を、スタッフユーザのみに対して ベータ版のコード B に置き換えたい ただし、B は冒険的な実装なので、例外が発生するかもしれない
既存の Controller のコード ベータ版のコード
ελοϑͳΒ# #Ͱྫ֎͕ى͖ͨΒ" ελοϑҎ֎ͳΒ" ϑϥάͰذ͍ͤͯ͘͞ͱίʔυ͕ԚΕ͍ͯ͘
ベータ機能の Unit 既存の Controller のコード " # Chanko では、Unit というファイルにベータ機能のロジックを記述する
invoke 条件を満たした場合に、既存ロジック (A) の代わりに Unit (B) が実行される B が例外を起こした場合は、元の A が実行されるため、ユーザにはエラーが返らない JOWPLF݅
無事に価値が認められたら 本番の品質のコードに仕上げる 既存コードを書き換え、Unit ファイルを消す (通称 Un-chanko)
Chanko • 既存のコードをほぼ汚さずに機能の置 き換え実験ができる(Chanko Unit) • もし Unit 内で例外が起きたら、既存の コードが実行される
• Chanko Unit は汚く書いてもいいけ ど、Un-chanko 時にはリファクタリン グしようね、という運用
Measure Learn product idea data Build プロダクト からデータに データから 仮説に
BML ループ 仮説から プロダクトに
Chanko で実現したこと • 本番環境をステージングのように 使えるようになった • 本物のデータ、本物のユーザ • 「スタッフ限定」「10%限定」で サービスの価値検証
すばやく開発しつつ すぐに本番で検証 しかもコードは汚れにくい (消しやすい)
コード品質
コード品質はビジネスに 影響するか?
クックパッドの答え: YES
コードの品質 • 可読性 • メンテナンス性 • バグの有無 • セキュリティ
コードの品質が影響するもの • 開発効率 • 属人性 w ίʔυͷण໋
どこまでやるべきか? やりすぎない 「綺麗なコード」を書くこと自体が目的ではない 事業フェーズにとって必要な品質までを目指す
コードレビュー 質の高いコードレビューがコード品質を ある程度担保する 負の遺産を残しにくくなる
コードレビューアンチパターン • 些細な文法の好みで揉める ‣ インデント、括弧など ‣ とにかく不毛
コード規約があると コードレビューの効率が 良くなる ֶͼ
IUUQTHJUIVCDPNDPPLQBETUZMFHVJEF
None
特徴 そんなんどっちでも いいだろというのも 結構決めてる
3年くらい運用してみて • 最初は反対意見も多かった(僕も) • ビジネスのコードレビューなのに文法の しょうもない論争が展開される、 みたいなのを見かけなくなった ‣ 文法の論争はスタイルガイドの方で やればよい
• あってよかったスタイルガイド
J04"OESPJEͰࣗಈίʔυϨϏϡʔCPU %BOHFS Λར༻ IUUQEBOHFSTZTUFNT
自動レビューbot • コーディングスタイルの Lint • 静的解析によるバグ検知 • OSSライセンス情報のチェック • アプリのビルド
• deploygate 等への配信
˞݄࣌ ࠓिͷϨϏϡʔίϝϯτ ࠓिͷ13
コードレビューの 生産性は 開発効率において 死活問題
効率よく開発しつつ メンテナンス性を保てる ようにするための工夫
マイクロサービス
IUUQTTQFBLFSEFDLDPNB@NBUTVEBUIFSFDJQFGPSUIFXPSMETMBSHFTUSBJMTNPOPMJUI
「モノリシック」な サービス
None
None
サービス分割のイメージ API
API 認証 ユーザ 基盤
API 認証 ユーザ基盤 決済
API 認証 ユーザ基盤 決済 動画基盤 レシピデータ
API 認証 ユーザ基盤 決済 動画基盤 レシピデータ Web
マイクロサービス # # 決済 動画基盤 Web ## # # #
αʔϏεΛҙຯͷ͋Δ୯ҐͰׂ͢Δ͜ͱͰ ҰͭҰͭখ͘͞ɺ։ൃ͘͢͠ͳΔ
メリット • 小さなアプリケーションとして 開発できる • メンテナンスしやすい • 責任感が持ちやすい • 組織のスケーラビリティ
デメリット • 結合テストが困難 • システム全体が爆発的に複雑に ‣ 障害の伝播問題 ‣ 管理の困難さ ‣
監視、可視化
API 認証 ユーザ基盤 決済 動画基盤 レシピデータ Web
API 認証 ユーザ基盤 決済 動画基盤 レシピデータ Web
API 認証 ユーザ基盤 決済 動画基盤 レシピデータ Web
API 認証 ユーザ基盤 決済 動画基盤 レシピデータ Web
None
世の中の流れは マイクロサービスへ • Docker を中心としたエコシステムが 急速に発達 • 技術的な「定石」ができつつある
サービスメッシュ • マイクロサービス同士を 適切に連携させて、 うまく制御する技術
&$4UBTL LTQPE サービスA サービスB サービスC αʔϏε͝ͱʹϓϩτίϧΛ࣮͢Δඞཁ͕͋ͬͨ ίϯςφ
αΠυΧʔͱͯ͠ಈ࡞ͤ͞Δɺ ϚΠΫϩαʔϏε͚ϓϩΩγ
&OWPZͰαʔϏεؒͷ௨৴ΛநԽ ɾαʔΩοτϒϨʔΧʔ ɾϩΪϯάɺࢹͷڞ௨Խ サービスA サービスB サービスC
1SPNFUIFVT QSPNWJ[ʹΑΔαʔϏεؒ௨৴ͷՄࢹԽ ʢ࣌ؒʹ༨༟͕͋ΕσϞʣ
進捗
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
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
NPEFMT NPEFMT
分割方針 • 開発が活発な部分を切り出す • サービスとして再利用性が高い部分を 切り出す • チームの境界で切り出す • 完璧より実利を目指す
おわりに
おわりに (1/5) • 開発効率への技術的投資を クックパッドは 組織的・戦略的に行ってきた • (ただし失敗もある)
おわりに (2/5) • クックパッドは「毎日の料理を楽しみ にする」サービス開発の会社 • サービス開発はめちゃくちゃ難しい • 最高の道具を使ってやっと 打席に立てる程度
おわりに (3/5) • サービスに「完成」はなく、 事業が続く限り ずっと開発し続けるものである ‣ BML ループ •
そのために必要なことはなにか?
おわりに (4/5) • サービス開発の技術選定で大事な要素 ‣ 早く作って、早くリリースできる ‣ 捨てやすい ‣ スケーラビリティ
(組織、トラフィック) ͓ΘΓ
おわりに (5/5) • マイクロサービス? ‣ 組織のスケーラビリティのために やむを得ない選択 ‣ 世の中のインフラがマイクロサービス 前提になりつつあり、いいタイミング
͓ΘΓ
IUUQTUFDIMJGFDPPLQBEDPN
ԠืకΊΓ ΫοΫύουɹΠϯλʔϯ