という
概念が存在しない
退屈な
失敗
Web開
発2016/12/19 ShippaiNight
おーはら @ohrdev
発表の趣旨
• (私の)失敗に対する考え方
• (私の失敗)事例紹介
• 知見共有
発表の趣旨
• (私の)失敗に対する考え方
• (私の失敗)事例紹介
• 知見共有
• ローストビーフ
Agenda
• 自己紹介
• 失敗とは
• 失敗時の対応
• 失敗の防止
• 事例紹介
• まとめ
自己紹介
• おーはら @ohrdev
• 株式会社ドリコム
– 基盤技術部/広告チーム
– サーバーサイド/AD/スペシャリスト
– Elixir/Phoenix, Erlang, Ruby/Rails, Lisp, etc
– 仏像制作/広告配信/全社基盤システムのお世話
• tokyo.ex, ElixirConf, VRTech.tokyoの主催運営
• #仏像, #寺社仏閣, #写経, #丸太, #VR, #LEGO,
#丸太収集
事故紹介
宣伝(1)
• 株式会社ドリコム
– エンジニアを絶賛募集中です
– http://www.drecom.co.jp/recruit/
– TechBlog始めました
– https://tech.drecom.co.jp/
宣伝(2)
• SoftwareDesign 2016/11, 12月号
– [次世代言語] Elixirの実力を知る
– http://gihyo.jp/magazine/SD/archive/2016/20161
1
– http://gihyo.jp/magazine/SD/archive/2016/20161
2
失敗とは
• 人は必ず失敗する
– 失敗しないxxxはない
• 失敗のサイクル
– 挑戦 -> 失敗 -> 発展 -> 挑戦 -> 失敗 -> 発展 -> …
• 成長の裏には失敗がある
本当に役にたつ「失敗学」 より
失敗とは
• Web開発における失敗分類
– 組織/チームの失敗
– サービスの失敗
– テクノロジーの失敗
– アーキテクチャの失敗
– ソフトウェアの失敗
– オペレーションの失敗
失敗とは
• 失敗 == 間違い ではない
– (webサービス開発の文脈では)フェーズによって、
最適解が異なる
– ex) テストを書かない
• プロトタイピング、α版
– ex) マイクロサービスvsモノシリック
• サービスの規模による
• 障害/Bug ⊂ 失敗
– 本発表では障害/Bugは失敗に含めます
失敗とは
• 失敗(障害)原因の階層
件数
重
大
度
個々人が原因
未知なる原因
社会が原因
組織が原因
チームが原因
トランプが戦争起こした
大地震が起きた
AWS/GCPの障害
取引先が倒産した
長期間続く高稼働状態
適切な人員配置ができていない
レビュー体制が無い
テスト/CIが無い
引き継ぎが無い
考慮不足
うっかり
確認漏れ
無知
勉強不足
失敗時の対応
• チーム/組織としてどうすべきか
• 放置しない
• 助ける/られる
失敗時の対応
• チーム/組織としてどうすべきか
失敗
組織長
組織
チーム
上司
教育者
先輩
同僚
致命的な事故を防止する
(失敗した者の)成長を考える
重大な事故を予防する
(失敗した者の)成長を考える
小さな失敗をさせる
失敗の後始末を手伝う
失敗者を助けて自分も学ぶ
失敗時の対応
• 放置しない
– 失敗を放置すると失敗が成長(拡大)する
• テストコード不足、コードメトリクス
• チーム文化
• スロークエリ、N+1問題
• データ量(ログのローテート忘れ)
• ログのとりわすれ
– 割れ窓を防ぐ
– 大きな失敗/障害/Bugの原因になる
失敗時の対応
• 助ける/られる
– 失敗時は周りに助けを求めるべき
• 責任感の強い人ほど自分でなんとかしようとする
• 自分ではどうしようも無い場合は詰む
– 日頃から助けを求められるパスを作っておく
• 普段から周りを助けておかないと、いざという時に助け
てもらえない(助ける:助けられる=5:1 くらい)
– 仕組みが無いと辛い(組織として取り組む)
• エンジニア間のつながり
• 助け合える文化、失敗を許容する文化
• 空気
失敗時の対応
• 助けられる
失敗時の対応(空気)
社内コミュニケーションにおけるunkの可能性
http://onk.bz/data/2008-02-24/1000speakers2.html
失敗時の対応(空気)
失敗時の対応(空気)
失敗時の対応(空気)
失敗時の対応(空気)
失敗時の対応(空気)
失敗時の対応(空気)
• 助け合える文化、助け合える空気
• 失敗を許容する文化、失敗を許容する空気
• ミスを憎んで人を憎まず
失敗の対策
• 知見を貯める
• 情報の残し方
• トップダウンで
失敗の対策
• 知見を貯める
– 客観的な失敗情報(だけ)は役に立たない
– 当事者の心理状態、行動、考えが重要
失敗 記述 記録 伝達知見化
背景
心理状態
経緯
原因
対応
総括
連鎖の防止共通認識
仕組み・
system
失敗の対策
• マニュアル
– 失敗しない手順しかない
– マニュアルにない手順を行うとどうなるかが無い
– 想定外の事態が発生するとどうにもならない
• 失敗時の記録/知見が重要
– どう失敗したか
– どうして失敗したか
– どうすれば回避できたか
失敗時の対策(情報の残し方)
マニュアル
S
G
想定外のケースに対処できない
失敗時の対策(情報の残し方)
べからず
想定外のケースに対処できない
失敗時の対策(情報の残し方)
失敗事例
想定外のケースに対処できない
失敗時の対策(情報の残し方)
知識・知見
どんな失敗、どうして失敗、どう回避するか
失敗の対策
• トップダウンで
– ボトムアップではぬるい対策になりがち
– トップが率先してやる
– 個人努力ではなく、仕組み・ルールとして実行し
ないと中途半端になる
• ルール・プラクティスの導入
• Spec/lint/CIの強制実行など
– 痛み(心理的障害)が発生するので、ある程度
の強制力があるとスムーズに導入できる
事例紹介(組織/チーム)
• 職種間(営業/企画/開発/運用)の断絶
– 開発だから〜まで、営業だから〜まで
– ⇨お見合い状態からの情報落ち
– ⇨音頭取り不在によるサイクルスピード低下
– スクラム/1チーム感の醸成(空気)
• 教育としての失敗(どう失敗経験をさせるか)
– ペアプロ, コードレビュー
– 検証環境へのリリース&ストレステスト
事例紹介(テクノロジー)
• ライブラリ・ミドルウェアのバージョン
– 後回しにすればするほど、バージョンアップコスト
が増大する
– ⇨Ruby1系、Rails2系バージョンのシステム
– ⇨セキュリティ対応ができなく,自力でやらないと
いけなくなる(パッチが出ない)
– レガシーバージョンのシステムのメンテコストが非
常に大きい
– お金を稼いでいるのであれば、レジェンドコード
事例紹介(アーキテクチャ)
• 自動化(CIによる自動deploy/operation)
– 初期フェーズから導入しないと高いコストが必要
になる
– ⇨初期から導入していないとDeploy周りの操作は
心理的ハードルが高い
• AWSのサービス管理: Terraformから
ServerlessFrameworkへの移行
– 仮想化は初期フェーズから入れておかないと導
入するのが難しい/ハードルが高くなる
事例紹介(アーキテクチャ)
• 失敗に強いアーキテクチャ
– 耐障害、監視機構、etc
– 負荷分散、スケールアウト/アップ
– マイクロサービス
• リアーキテクチャ、サービスの入れ替えetc
事例紹介(プログラミング)
• Lint/自動テスト/CI
– 開発初期にLint/自動テスト/CIを導入していな
かった
– ⇨ある程度開発が進んだ状態で導入した時に
ワーニングが大量に出て導入コストが増大
– ⇨(知見)初期フェーズに必ず入れるべき
– ⇨(知見)失敗を放置してはいけない
– テストが無い状態からテスト導入(80%程度のカバ
レッジ)まで年単位のコストを支払った
事例紹介(プラクティス)
• 変更に対する恐怖と戦う
– リファクタリング
– リアーキテクチャ
– 変更に対する恐怖とどう戦うか
• テスト
• 検知
• マイクロサービス化
– ⇨小さな変更を多く繰り返す
まとめ
• 失敗に対して正しいアクションを
• 失敗を成長の糧に
• 失敗を怖がらない
という
概念が存在しない
退屈な
失敗
Web開
発
という
概念が存在するからこそ
退屈せずに楽しめる
失敗
Web開
参考文献
• 「使える失敗学」
• 「図解 使える失敗学」
• 「Code Simplicity」
• 私のチームのRedmine/Wiki
• OSSのissueリスト
• etc

失敗という概念が存在しない退屈なweb開発