仕組みから学ぶ Web

トピック一覧

順番に読む必要はありません。今困っていることに近いものから開いてください。 前提記事がある場合は記事の先頭に出ます。

カテゴリ
難易度
読了
タグ

78 / 78 件

ネットワーク / Web基礎12分

DNS — 名前からIPアドレスにたどり着くまで

ブラウザが example.com を数字の住所に変換する経路と、その途中に置かれたキャッシュがなぜ事故の原因になるのか。

TTL を確認せずにサーバーを切り替え、旧サーバーに丸一日アクセスが流れ続けた

ネットワーク / Web基礎14分

TCP/IP — データが相手に届くまでの4層

アプリが送った1行の文字列が、どう包まれて、どう運ばれ、どう元に戻るのか。障害の切り分けはこの層の把握から始まる。

「サーバーが落ちている」と報告したが、実際は SYN が返らないだけでプロセスは生きていた

ネットワーク / Web応用14分

HTTP/1.1 → 2 → 3 — 何が遅くて、何を直したのか

バージョンが上がるたびに解かれてきたのは「待ち」の問題。どの待ちがどこで消えたかを知らないと、HTTP/2 にしても速くならない。

HTTP/2 対応したのに表示が速くならず、ドメイン分割の設定がそのまま残っていたのが原因だった

ネットワーク / Web応用14分

TLS — 盗聴・改ざん・なりすましを同時に防ぐ

HTTPS の鍵マークが保証しているのは3つ。何を保証していて、何を保証していないのかを分けて理解する。

証明書の期限切れで全社のサービスが停止。監視していたのは死活だけで、有効期限は誰も見ていなかった

ネットワーク / Web応用13分

CDN — 利用者の近くに置いて、オリジンを守る

配信を速くする仕組みであると同時に、オリジンへのアクセスを減らす仕組みでもある。キャッシュキーの設計を誤ると、どちらも機能しない。

CDN が Cookie をキャッシュキーに含めておらず、他人のログイン後の画面が配信された

ネットワーク / Web応用15分

キャッシュ戦略 — いつ捨てるかを設計する

キャッシュを置くのは簡単で、正しく捨てるのが難しい。max-age・ETag・stale-while-revalidate の使い分けを判断軸から組み立てる。

緊急修正をデプロイしたのに、1年キャッシュされた JS のせいで利用者に届かなかった

ネットワーク / Web応用15分

ロードバランサ — 間に入った箱が、何を書き換えているか

ロードバランサを入れた翌日、レート制限が全利用者をまとめて弾いた。ログの送信元も全部同じ。間に入る箱は接続を終端し、元の情報はヘッダーに移る。

ロードバランサを入れた翌日、IP ごとのレート制限が全利用者をまとめて弾いた

ネットワーク / Web応用15分

ポーリングと SSE と WebSocket — どこまで双方向が要るか

5秒ごとの更新確認を入れた翌週、DB の接続が枯れた。1000人が5秒ごとに聞きに来れば毎秒200回。要るのは本当に双方向か、それとも「届く」だけか。

5秒ごとの更新確認を全画面に入れたら、DB の接続が枯れてサイト全体が落ちた

ネットワーク / Web応用15分

メールが届かない — 「送れた」と「届いた」は別の話

送信サービスはすべて「成功」を返していた。それでも会員登録の確認メールの 3 割が、迷惑メールのフォルダに入るか、どこにも届いていなかった。受け取る側は、差出人が本物かどうかを DNS で確かめている。

送信サービスは全件「成功」だったのに、会員登録の確認メールの 3 割が迷惑メールに入るか届かず、登録の完了率が落ちた

ブラウザ応用13分

レンダリングパイプライン — どのCSSが重いかは工程で決まる

ブラウザが HTML を受け取ってから画面を描くまでの工程。どのプロパティを触ると、どの工程からやり直しになるのか。

スクロール連動アニメーションで top を毎フレーム書き換え、スマホで完全に固まった

ブラウザ応用14分

イベントループ — 1本のスレッドで待たずに捌く

JavaScript が1スレッドなのに、なぜ複数の処理を同時に進められるのか。そして、なぜ「重い処理」が画面ごと止めるのか。

10万件の配列を同期でループし、その間ボタンもスクロールも一切反応しなくなった

ブラウザ基礎12分

同一オリジンポリシー — ブラウザが最初から持っている壁

なぜ他のサイトの JavaScript から自分のページのデータを読めないのか。この制約がなければ Web はどうなっていたか。

iframe で埋めた別ドメインの画面を JS から操作しようとして、原因不明のエラーで1日溶かした

ブラウザ応用14分

CORS — 壁に穴を開けるのは「読まれる側」

プリフライトはなぜ飛ぶのか。ワイルドカードと Cookie が同時に使えないのはなぜか。エラーメッセージから原因を逆算する。

CORS エラーを直そうとフロント側の fetch オプションを1日いじり続けた

ブラウザ応用14分

ブラウザのストレージ — 読めるか、と、送られるかは別の話

Cookie / localStorage / sessionStorage / IndexedDB を容量ではなく「誰が読めて、いつ送られるか」で分ける。認証情報の置き場所を決めるための判断軸。

アクセストークンを localStorage に置き、外部スクリプト経由で持ち出されて8時間なりすまされた

ブラウザ応用14分

Core Web Vitals — 数字を上げるのではなく、何が遅いかを特定する

LCP・INP・CLS は原因ではなく症状の分類。3つが何の代理指標なのかを知ると、直す場所が工程の中で決まる。

LCP の数字だけを追って画像を軽くしたが、遅さの原因は別の工程にあった

ブラウザ応用15分

Service Worker — 直したのに、利用者の画面だけ古い

修正をデプロイしたのに、一部の利用者だけ古い画面のまま壊れた API を叩き続ける。ブラウザとネットワークの間に、自分で書いたプロキシがもう1枚挟まっている。

修正をデプロイしたのに、一部の利用者だけ3日間、古い画面のまま消えた API を叩き続けた

ブラウザ応用15分

画像と動画の配信 — 軽くしたはずの画像が、ページを遅くしている

全部の画像を WebP にして遅延読み込みを付けたら、LCP が悪化した。効くのは形式より画素数で、遅延読み込みは付ける場所を間違えると逆に遅くする。

画像を全部 WebP にして遅延読み込みを付けたら、商品ページの LCP が 2.1秒から 3.4秒に悪化した

ブラウザ応用15分

アクセシビリティ — div にクリックを付けた日から、誰かが使えなくなる

見た目は完璧なボタンを作った。キーボードでは押せず、読み上げでは「何か」としか読まれない。button と書けば全部付いてきたものを、自分で捨てていた。

div で作ったボタンが、キーボードでも読み上げでも操作できなかった

ブラウザ発展16分

描画をどこでするか — HTML を作る時と場所を、データごとに選ぶ

初回の表示が遅いので、全ページをサーバーで描画するようにした。セールの日、1 日 1 回しか変わらない商品説明を、アクセスのたびに描き直してサーバーが落ちた。方式はアプリ単位ではなく、データの鮮度と、誰のものかで決まる。

初回表示の遅さを直すため全ページをサーバー描画にしたら、セールの日に 1 日 1 回しか変わらないページまで毎回描き直してサーバーが落ちた

ブラウザ発展15分

再描画はなぜ起きるか — 1 文字打つたびに、表ぜんぶが描き直されていた

検索欄に 1 文字打つたびに、画面が 0.4 秒固まった。メモ化を全部の部品に付けても変わらなかった。描き直される範囲は、状態を持つ場所で決まる。

検索欄に 1 文字打つたびに 5,000 行の表が描き直され、入力が 0.4 秒ずつ遅れた。メモ化を全部に付けても直らなかった

ブラウザ発展15分

データをどこで取るか — 取得が一列に並ぶと、画面は足し算で遅くなる

注文の詳細画面が 2.4 秒かかっていた。API はどれも 0.8 秒で返っていた。部品がそれぞれ、自分が描かれてからデータを取りに行っていたので、3 回の待ちが順番に並んでいた。

3 つの API はどれも 0.8 秒で返るのに、部品ごとに順番に取りに行っていたため、注文の詳細画面が 2.4 秒かかった

ブラウザ応用15分

フォームと入力の検証 — 画面の検証は親切、サーバーの検証は守り

申し込みフォームで、送信ボタンを 2 回押した人に申し込みが 2 件でき、エラーで戻った人の入力は全部消えていた。画面の検証を足しても、サーバーを通る値は守れない。役割の違う 2 つの検証を、別のものとして設計する。

申し込みフォームで二重送信の申し込みが月 40 件でき、エラーで戻ると入力がすべて消えていた。画面の検証をすり抜けた不正な値も DB に入っていた

認証 / セキュリティ基礎14分

Cookie とセッション — 状態を持たない HTTP に記憶を持たせる

サーバーが覚えるか、利用者に持たせるか。この選択が、ログアウトの実装可能性とスケール特性をすべて決める。

Secure 属性を付け忘れたセッション Cookie が、社内 Wi-Fi の平文通信で盗まれた

認証 / セキュリティ応用14分

JWT — 取り消せない代わりに、問い合わせが要らない

署名付きトークンが解いた問題と、その代償。「ステートレスだからスケールする」の裏で何を諦めているのか。

退会したユーザーが、24時間有効な JWT でその後もAPIを叩き続けられた

認証 / セキュリティ発展16分

OAuth 2.0 と OIDC — 「代理で使わせる」と「誰かを証明する」は別物

認可と認証を混同すると穴が開く。認可コードフローがなぜ遠回りに見える手順を踏むのか、一歩ずつ理由がある。

アクセストークンでログイン判定を実装し、他サービスのトークンで別人になりすまされた

認証 / セキュリティ応用16分

XSS・CSRF・SQLi — データとコードの境界が壊れる

3つの代表的な脆弱性は、どれも「データとして扱うべきものが命令として解釈される」という同じ形をしている。

検索キーワードをそのまま画面に出す実装で、管理者のセッションが盗まれた

認証 / セキュリティ応用14分

認可 — ログインしている人が、そのデータを触ってよいとは限らない

URL の注文番号を1つ変えるだけで、他人の注文と住所が見えた。ログインを確かめることと、そのデータを触ってよいかを確かめることは、別の仕事。

URL の注文番号を1つ変えるだけで、他人の注文と住所が見えた。3週間で8万件が取得されていた

認証 / セキュリティ応用14分

パスワードの保存 — 漏れたあとに、何日持ちこたえられるか

「パスワードはハッシュ化していたので安全」と発表した数日後、大半が元に戻され、他のサービスで不正ログインが続いた。速いハッシュは、漏れた瞬間から総当たりの的になる。

「ハッシュ化していたので安全」と発表した数日後、流出したパスワードの大半が元に戻された

認証 / セキュリティ応用15分

依存パッケージ — 自分が書いていないコードが、本番で動く

直接入れたのは40個。実際に入っていたのは900個。そのうち1つのメンテナのアカウントが乗っ取られ、CI の資格情報が外部へ送られた。

小さなユーティリティのパッチ版が乗っ取られ、CI のデプロイ用の資格情報が外部へ送られた

認証 / セキュリティ応用15分

監査ログ — 「誰がやったか」を、あとから言えるか

顧客データが 3 万件持ち出された。管理画面のログはあった。しかし誰がどのデータを見たかは、どこにも残っていなかった。

顧客データの持ち出しが疑われたが、誰が何を見たかを示す記録がどこにも無かった

認証 / セキュリティ応用15分

セキュリティヘッダ — 最後の1枚を、ブラウザに張らせる

XSS は塞いだつもりだった。広告タグの1つが改ざんされ、そこから入力欄の値が外部へ送られた。自前のコードは1行も侵されていない。

外部の広告タグが改ざんされ、決済フォームの入力値が第三者へ送信された

認証 / セキュリティ応用16分

プロンプトインジェクション — 読ませた文章が、命令に変わる

LLM には、データと命令を分ける仕組みがない。SQL のプレースホルダにあたるものが存在しない以上、守りは「騙されない」ではなく「騙されても被害が出ない」側に置くしかない。

社内 AI アシスタントに Web ページを要約させたら、社内文書の中身が外部へ送られた

認証 / セキュリティ発展16分

AI エージェントの権限 — 道具を持たせた瞬間に、認可の問題になる

エージェントは、誰かの権限を借りて動く。その権限が仕事に対して広すぎると、読ませた文章 1 つで、持ち主が意図しない操作が正規の権限のまま実行される。

Issue を直させたコーディングエージェントが、非公開リポジトリの中身を公開の場所に書き込んだ

認証 / セキュリティ応用14分

AI に送ったデータの行方 — 預け先より、手元のログのほうが長く残る

提供元が学習に使わないことは確かめた。けれどプロンプトは、送る前に自分のアプリのログ・監視・エラー通知を通っている。削除の依頼が来たとき、消せないのはそちらだった。

LLM の提供元は学習に使わない契約だったが、プロンプト全文が自社のログに 2 年残っていた

データ / DB 設計基礎14分

正規化 — 同じ事実を2か所に書かない

正規化は理論ではなく「更新時に矛盾が起きない形」を作る作業。どこまで正規化し、どこで意図的に崩すか。

商品名を注文テーブルにも持たせた結果、同じ商品なのに表記が3種類に分裂した

データ / DB 設計応用16分

インデックス — 読む行を減らすための索引

B-tree が何をしているかと、複合インデックスの列順がなぜ効くのか。張れば速くなるものではない。

遅いクエリに片っ端からインデックスを張り、書き込みが3倍遅くなった

データ / DB 設計発展16分

トランザクションと分離レベル — 同時に動く処理が互いをどこまで見てよいか

在庫が二重に引かれる、残高がずれる。同時実行の事故は、分離レベルの選択と設計の両方で決まる。

在庫チェックと在庫更新の間に別の注文が入り、在庫1個の商品が2人に売れた

データ / DB 設計応用13分

N+1 問題 — 1回で済むはずの問い合わせが100回になる

ORM の便利さが隠してしまう問い合わせ回数。発見の仕方と、対処の選択肢を使い分ける。

1件あたり2msのクエリが200回走り、一覧ページの表示に4秒かかっていた

データ / DB 設計発展15分

実行計画 — DB が何をしようとしているかを読む

推測でチューニングしない。EXPLAIN の読み方と、見積もりと実測のズレが何を意味するか。

統計情報が古く、インデックスがあるのにフルスキャンが選ばれ続けていた

データ / DB 設計応用15分

RDB と NoSQL — 問い合わせの形を、いつ決めるか

性能の比較ではなく「アクセスパターンがもう固まっているか、まだ動くか」で選ぶ。後から取り方を増やしたくなったとき、何が起きるかの違い。

取り方が固まる前に NoSQL を選び、後から来た検索要件が全件走査になった

データ / DB 設計応用15分

マイグレーション — 流した瞬間に、書き込みが全部待つ

列を1つ足すだけの変更が、本番で11分サイトを止める。行数ではなく、同時に走っているトランザクションの長さが効く。

列を1つ足すだけの変更で、書き込みが11分間詰まってサイトが止まった

データ / DB 設計応用14分

論理削除と物理削除 — 「消した」を、すべてのクエリが覚えていられるか

退会した会員にキャンペーンメールが届いた。論理削除は、削除を DB の操作から、すべてのクエリが守る約束に変える。

退会したはずの会員4,000人に、キャンペーンメールが届いた

データ / DB 設計応用15分

コネクションプール — 増やしたら、もっと詰まった

DB の接続が足りないと言われてプールを増やしたら、さらに詰まった。接続の総数は「1台あたり × 台数」で、サーバーレスでは台数が勝手に増える。

キャンペーン開始直後に DB の接続が上限に達し、プールを倍にしたらさらに悪化した

データ / DB 設計応用15分

ID の設計 — 連番を外に出した日から、数えられてしまう

注文番号を連番にしていた。競合が毎日1件注文して番号の差を見れば、1日の注文数が分かる。URL に出す ID は、内部の事情を外に漏らす。

注文番号が連番だったため、競合に1日の注文件数を数えられていた

データ / DB 設計応用15分

全文検索 — LIKE '%...%' が効かなくなる日

商品が5万件を超えたあたりから、検索が3秒かかるようになった。インデックスは張ってある。しかし前方一致でない検索には、効かない。

商品が5万件を超えたら検索が3秒かかるようになった。インデックスは張ってあった

設計 / アーキテクチャ基礎14分

凝集度と結合度 — 変更したとき何ファイル触るか

良い設計は「動くか」では測れない。測れるのは、仕様変更が来たときの影響範囲。それを制御する2つの語彙。

「共通化」したユーティリティに分岐が増え続け、1箇所の修正が3画面を壊した

設計 / アーキテクチャ応用15分

SOLID — 5つの原則が守ろうとしている1つのこと

暗記する対象ではなく、判断の道具として使う。それぞれが「どういう変更に備えているか」から理解する。

決済手段を1つ追加するのに、既存の分岐を12箇所書き換えることになった

設計 / アーキテクチャ応用15分

レイヤードアーキテクチャ — 依存の向きを一方向に揃える

層に分けること自体に価値はない。価値があるのは、依存が一方向であることと、業務ロジックが技術から独立すること。

DB のカラム名を変えたら、画面のテンプレートが壊れた

設計 / アーキテクチャ発展16分

ドメインモデリング — 業務の言葉をコードの形にする

テーブル設計から始めると、業務ルールの置き場所がなくなる。何が概念で、何が制約かを見つける作業。

金額を number で持ち回り、税込と税抜が混ざった状態で合計されていた

設計 / アーキテクチャ発展16分

モノリスとマイクロサービス — 分けた境界の数だけ、失敗の仕方が増える

速く開発するために8つのサービスに分けたら、項目を1つ足すのに4つのサービスを順番にデプロイするようになった。分けることで得られるのは独立性で、境界を間違えると独立性は得られず、費用だけが残る。

6人のチームが8つのサービスに分けたら、項目を1つ足すのに4サービスの順番デプロイが要り、ポイントの付与漏れが続いた

設計 / アーキテクチャ応用14分

時刻とタイムゾーン — 保存した「0時」は、どこの0時か

毎日0時から9時までの注文が、前日の売上に計上されていた。時刻には「瞬間」「壁の時計の時刻」「日付」の3種類があり、混ぜた瞬間に9時間ずれる。

毎日0時から9時までの注文が前日の売上に入り、月末の締めの数字が経理の集計と合わなかった

設計 / アーキテクチャ応用16分

I/O と並行処理 — 待っている間に、何をするか

サムネイル生成を1本足しただけで、無関係な API まで全部遅くなった。待ち時間の処理と、計算そのものは、同じ場所に置いてはいけない。

サムネイル生成を API に足したら、DB もネットワークも暇なのに、無関係な API まで応答が4秒になった

設計 / アーキテクチャ応用15分

文字コードと正規化 — 同じに見える文字が、一致しない

「ガ」で検索しても出てこない。目で見ると同じ文字。バイト列は違う。長さも、比較も、見た目とはずれる。

Mac から登録された「ガ」が、Windows から検索しても一致しなかった

設計 / アーキテクチャ応用15分

状態をどこに置くか — URL に無いものは、共有できない

絞り込んだ一覧を同僚に送ったら、何も絞られていない画面が開いた。状態をどこに置くかは、何ができて何ができないかを決める。

絞り込んだ一覧の URL を共有したら、相手の画面では何も絞られていなかった

設計 / アーキテクチャ応用15分

トレードオフの決め方 — 正解を探すのをやめて、払うものを選ぶ

3 年前に選んだ DB の理由を、誰も覚えていなかった。得るものは覚えていても、払うものは書いていなかった。設計判断に正解は無く、あるのは「この制約なら、これを払う」という選択だけ。

3 年前に「スケールするから」と選んだ DB の理由を誰も覚えておらず、集計のたびに全件を読み、同じ議論を 2 週間繰り返した

設計 / アーキテクチャ応用15分

コンポーネントをどう分けるか — 見た目が同じでも、変わる理由が違えば別の部品

共通の商品カードは、1 年で引数が 23 個になった。ある画面の修正で、別の画面のカードが崩れた。似ているものをまとめた部品は、変わる理由の数だけ分岐を抱える。

共通の商品カードが 1 年で引数 23 個になり、セール画面の修正でお気に入り画面のカードが崩れた

API 設計応用14分

リソース設計 — 一度公開したら変えられない契約

URL は動詞ではなく名詞で切る、の理由。そして「きれいな REST」に収まらない操作をどう扱うか。

レスポンスの1フィールドを削除したら、把握していなかった3つのクライアントが壊れた

API 設計応用14分

冪等性 — 同じリクエストが2回届く前提で設計する

ネットワークがある限り、再送は異常ではなく正常系。2回実行されても壊れない形をどう作るか。

決済 API のタイムアウト後にリトライし、同じ注文で2回課金された

API 設計応用13分

エラー設計 — 呼び出し側が正しく振る舞える情報を返す

エラーは失敗の通知ではなく、次に何をすべきかの指示。リトライしてよいか、直せば通るかを伝える。

すべてのエラーを 200 + { success: false } で返し、クライアントが一時障害を延々とリトライした

API 設計発展15分

REST と GraphQL — 何を楽にして、何を難しくするか

過不足のない取得という利点の裏で、キャッシュ・認可・負荷制御がクライアント任せから自分の責任に移る。

GraphQL 導入後、CDN キャッシュが一切効かなくなり、オリジンの負荷が10倍になった

API 設計応用14分

ページネーション — 数えて飛ばすか、続きから取るか

offset は「ページ番号」という画面の都合から来ている。件数が増えると遅くなり、データが動くと境界がずれる。カーソル方式が何を解いて、何を捨てるのか。

offset で一覧を書き出すバッチが、毎回数件ずつ静かに取りこぼしていた

API 設計応用15分

リトライとタイムアウト — 助けるつもりの再試行が、障害を大きくする

決済サービスは2分で直ったのに、全体は40分止まった。層ごとのリトライは掛け算になり、揃っていないタイムアウトは誰も待っていない仕事を増やす。

決済サービスが2分遅くなっただけで、3層のリトライが呼び出しを27倍にし、全体が40分止まった

API 設計応用15分

非同期処理とキュー — 「受け付けました」のあとで、何が起きているか

メール送信をキューに移したら、同じメールが4通届く人と、1通も届かない人が出た。キューは「必ず1回」を約束しない。重複と消失は、処理を書く側が引き受ける。

メール送信をキューに移したら、注文確認メールが4通届く人と、1通も届かない人が出た

API 設計応用14分

レート制限 — 誰を、どの単位で、どこで止めるか

ログインに IP ごとの制限をかけたら、同じ会社の社員がまとめて締め出され、数千の IP に散らばった攻撃は素通りした。制限の強さより先に、何を1人と数えるかを決める。

IP ごとのログイン制限で、同じ会社の社員がまとめて締め出され、分散した攻撃は素通りした

API 設計応用15分

API のバージョニング — 変えられないものを、どう変えるか

レスポンスから使っていないフィールドを1つ消した。翌日、古いアプリが全部落ちた。自分が使っていないことと、誰も使っていないことは違う。

使っていないフィールドを消したら、更新していない利用者のアプリが全部落ちた

API 設計応用15分

ファイルのアップロード — サーバーを通すか、通さないか

動画の投稿を許したら、アプリのメモリが枯れて全機能が落ちた。1人が 800MB を送っただけだった。受け取り方を決める前に、どこを通すかを決める。

動画の投稿を許した日、1人が 800MB を送ってアプリ全体がメモリ不足で落ちた

API 設計発展16分

2 つのシステムに書く — 片方だけ成功した状態を、先に設計しておく

決済は成功した。自社の DB には「未払い」と残った。利用者はお金を払ったのに使えなかった。自社の DB と外部のサービスは、1 つのトランザクションにならない。だから、途中で止まったときにどちらへ倒れるかを、先に決めておく。

決済は成功したのに、直後のデプロイで処理が止まり、自社の DB には「未払い」が残った。37 人が、払ったのに使えなかった

運用 / 開発プロセス応用14分

CI/CD — 壊れていることに、人間より先に気づく

自動化そのものが目的ではない。「壊れた変更が本番に届かない」ことと「いつでも戻せる」ことを仕組みで保証する。

CI が落ちたまま3週間放置され、誰も赤信号を見なくなっていた

運用 / 開発プロセス応用14分

コンテナ — 「手元では動く」を構造的に潰す

仮想マシンとの違いはどこか。イメージが層でできていることが、ビルド時間とデプロイの両方を決める。

latest タグを使い続け、ロールバックしたら別のバージョンが起動した

運用 / 開発プロセス応用14分

ログと監視 — 誰より先に、壊れていることに気づく

ログは調査のため、メトリクスは検知のため、トレースは特定のため。3つの役割を分けて設計する。

アラートが1日200件届き、本物の障害通知が埋もれて3時間気づかなかった

運用 / 開発プロセス応用15分

テスト戦略 — どこに何枚の網を張るか

テストは多いほど良いわけではない。壊れやすさ・実行時間・書く手間のバランスをどこで取るか。

E2E テストを増やした結果、CI が40分かかり、落ちても誰も原因を調べなくなった

運用 / 開発プロセス応用15分

インシデント対応 — 直すのが先か、分かるのが先か

原因が分からないまま戻すのは怖い。その感覚が復旧を遅らせる。止血と原因究明の順序、記録の残し方、そして再発防止に「気をつける」と書かないこと。

原因を突き止めてから直そうとして、復旧が3時間遅れた

運用 / 開発プロセス応用14分

秘密情報の扱い — 消したコミットの中に、鍵はまだ残っている

誤ってコミットしたアクセスキーを次のコミットで消した。半年後にリポジトリを公開した数時間後、そのキーで高額なサーバーが大量に立ち上がった。漏れた鍵に効くのは削除ではなく、無効化。

消したはずのアクセスキーが Git の履歴に残っていて、リポジトリを公開した数時間後に悪用された

運用 / 開発プロセス応用14分

フィーチャーフラグ — 消し忘れたスイッチが、本番を壊す

使われていないフラグの名前を再利用したら、デプロイに失敗していた1台だけが3年前のコードを動かした。フラグはデプロイと公開を分ける道具で、分けたぶんだけ本番の状態の数が増える。

使われていないフラグの名前を再利用したら、1台だけが3年前の機能を動かし、誤った価格の注文が2時間続いた

運用 / 開発プロセス応用15分

バックアップと復旧 — 取れていることと、戻せることは別

毎日バックアップを取っていた。3年間、一度も失敗していなかった。いざ戻そうとしたら、復旧に11時間かかると分かった。

毎日のバックアップは3年間成功していた。戻す段になって、11時間かかると分かった

運用 / 開発プロセス応用15分

設定の管理 — 環境ごとに違う値を、どこに置くか

検証環境のつもりで流したバッチが、本番の顧客にメールを送った。設定が欠けたとき、安全側に倒れるか危険側に倒れるかで結果が変わる。

検証環境で流したバッチが、本番のメール配信サービスを叩いて顧客に届いた

運用 / 開発プロセス応用15分

バッチと定期ジョブ — 途中で落ちたとき、もう一度流して大丈夫か

夜間の請求バッチが 3,200 件目で止まった。朝、担当者が最初から流し直した。最初の 3,200 人に、請求が 2 回届いた。バッチは必ず途中で止まる。だから、どこからでも流し直せる形にしておく。

夜間の請求バッチが 3,200 件目で止まり、朝に最初から流し直したため、3,200 人に請求が 2 回届いた

運用 / 開発プロセス発展16分

SLO とエラーバジェット — どこまで壊れてよいかを、先に数字で決める

アラームは 1 日 80 件鳴っていた。当番は見なくなり、決済の 5% が失敗していた 2 時間に誰も気づかなかった。鳴らすべきは「何かがおかしい」ではなく、「利用者との約束を、このままだと守れない」とき。

アラームが 1 日 80 件鳴り続けて当番が見なくなり、決済の 5% が失敗していた 2 時間に誰も気づかなかった