仕組みから学ぶ Web

トピック一覧

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

カテゴリ
難易度
読了
タグ

37 / 37

ネットワーク / 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 のせいで利用者に届かなかった

ブラウザ応用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 の数字だけを追って画像を軽くしたが、遅さの原因は別の工程にあった

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

データ / 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分間詰まってサイトが止まった

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 で一覧を書き出すバッチが、毎回数件ずつ静かに取りこぼしていた

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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