Laravel - 未経験から実務レベルへ|PHP初心者向け実践学習ブログ https://phpl4b.com Thu, 26 Mar 2026 00:26:00 +0000 ja hourly 1 https://wordpress.org/?v=6.9.4 https://phpl4b.com/wp-content/uploads/2026/04/cropped-スクリーンショット-2026-04-16-22.09.40-32x32.png Laravel - 未経験から実務レベルへ|PHP初心者向け実践学習ブログ https://phpl4b.com 32 32 第36回: 本番運用チェックリスト(Laravel版) — リリース前の確認、属人化していませんか? https://phpl4b.com/426/?utm_source=rss&utm_medium=rss&utm_campaign=36_%25e6%259c%25ac%25e7%2595%25aa%25e9%2581%258b%25e7%2594%25a8%25e3%2583%2581%25e3%2582%25a7%25e3%2583%2583%25e3%2582%25af%25e3%2583%25aa%25e3%2582%25b9%25e3%2583%2588laravel%25e7%2589%2588 Thu, 26 Mar 2026 00:00:00 +0000 https://phpl4b.com/426/ 経験豊富なエンジニアでも、リリース前の確認を頭の中だけで管理していると、プレッシャーや疲労で抜けが発生します。「APPDEBUG=true のまま本番デプロイ」「監視通知先の疎通未確認」——こうしたミスは、チェックリストがあれば防げます。

The post 第36回: 本番運用チェックリスト(Laravel版) — リリース前の確認、属人化していませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第36回: 本番運用チェックリスト(Laravel版) — リリース前の確認、属人化していませんか?

章: 第8章: パフォーマンスと本番運用実践

「毎回同じ確認をしているのに、毎回何かが抜ける」

経験豊富なエンジニアでも、リリース前の確認を頭の中だけで管理していると、プレッシャーや疲労で抜けが発生します。「APP_DEBUG=true のまま本番デプロイ」「監視通知先の疎通未確認」——こうしたミスは、チェックリストがあれば防げます。

本番運用チェックリストは、品質を担当者の記憶力に依存させないための仕組みです。

問題の本質と解決策

問題: 確認項目が人の頭の中にあると、担当者が変わるたびに漏れが発生します。また「いつもやっている」という慣れが注意散漫を招きます。

解決策: リリース前に必ず確認する項目をチェックリスト化し、毎回同じ順番で実行します。チェック済みかどうかを記録に残すことで、確認済みの根拠が残ります。

チェックリストなし vs あり 比較

観点 チェックリストなし チェックリストあり
確認の漏れ 担当者の記憶に依存 項目が固定で漏れにくい
属人化 経験者がいないと不安 誰でも同じ品質で確認可能
確認の根拠 記録が残らない チェック済み記録が残る
改善のしやすさ 問題が起きても振り返りにくい 未チェック項目が一目でわかる

チェックポイント: チェックリストを「毎回同じ順番で確認する」ルールになっていますか?順番に意味がある場合(依存関係がある確認など)は、順序を変えると抜け漏れが増えます。

リリース前チェックサンプル


# リリース前チェック
# - [ ] APP_DEBUG=false
# - [ ] Queue/Horizonが正常
# - [ ] 主要Featureテストが成功
# - [ ] 監視通知先の疎通確認
# - [ ] ロールバック手順の確認

まとめ & 次のステップ

  • 本番運用チェックリストは品質を担当者の記憶力に依存させないための仕組みです
  • 毎回同じ順番で確認し、差分が出た箇所だけ深掘りする運用が効果的です
  • APP_DEBUG=false・Queue正常・テスト成功・監視疎通・ロールバック確認が最小5項目です
  • チェックリストはリリースのたびに見直し、新しい確認項目を追加していきましょう
  • このシリーズ(Laravel上級編)はここで完走です!学んだ内容を実務に活かしてください

Laravel上級編の全36回、お疲れさまでした! キャッシュ・監視・ログ・認証・デプロイ・DB運用まで、実務で使える知識を網羅しました。次はこれらの知識を自分のプロジェクトに1つずつ適用してみましょう。

The post 第36回: 本番運用チェックリスト(Laravel版) — リリース前の確認、属人化していませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第35回: 障害対応ランブック作成 — 障害のたびに「どうすればいいか」を考えていませんか? https://phpl4b.com/424/?utm_source=rss&utm_medium=rss&utm_campaign=35_%25e9%259a%259c%25e5%25ae%25b3%25e5%25af%25be%25e5%25bf%259c%25e3%2583%25a9%25e3%2583%25b3%25e3%2583%2596%25e3%2583%2583%25e3%2582%25af%25e4%25bd%259c%25e6%2588%2590 Wed, 25 Mar 2026 00:00:00 +0000 https://phpl4b.com/424/ アラートが飛んできたとき、「まず何を確認すればいいか」「誰に連絡するか」「どこまで判断していいか」——これらが頭の中だけにある状態では、対応者によって復旧時間に大きな差が出ます。

The post 第35回: 障害対応ランブック作成 — 障害のたびに「どうすればいいか」を考えていませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第35回: 障害対応ランブック作成 — 障害のたびに「どうすればいいか」を考えていませんか?

章: 第8章: パフォーマンスと本番運用実践

深夜2時に障害が起きたとき、あなたのチームは動けますか?

アラートが飛んできたとき、「まず何を確認すればいいか」「誰に連絡するか」「どこまで判断していいか」——これらが頭の中だけにある状態では、対応者によって復旧時間に大きな差が出ます。

ランブック(Runbook) は障害対応の手順書です。事前に整備しておくことで、初動の判断を標準化し、誰が対応しても同じ品質で動けるようになります。

問題の本質と解決策

問題: 手順が担当者の頭の中にあると、担当者不在時の対応品質が下がり、復旧に時間がかかります。また、対応中に「何をやったか」が記録されず、後から再発防止が難しくなります。

解決策: 「検知条件・影響範囲の確認・一時対応・恒久対応・エスカレーション先」の5項目を最小構成として、頻度の高い障害から手順化します。まず1件作ることで、チームで改善を積み重ねられます。

ランブックなし vs あり 比較

観点 ランブックなし ランブックあり
対応者による品質差 大きい 最小限に抑えられる
初動の速さ 判断に時間がかかる 手順通りに即動ける
対応内容の記録 残らないことが多い ランブックに追記できる
再発防止への活用 難しい 手順の振り返りが容易

チェックポイント: ランブックに「エスカレーション先と条件」は明記されていますか?「誰に・何が起きたら・どのように連絡するか」が書かれていないと、判断が止まります。

ランブック最小構成サンプル


# ランブックの最小構成
# - 検知条件
# - 影響範囲の確認方法
# - 一時対応手順
# - 恒久対応の記録欄
# - エスカレーション先

まとめ & 次のステップ

  • ランブックは「検知・確認・一時対応・恒久対応・エスカレーション」の5項目が最小構成です
  • 担当者によらず同品質の対応ができることが、ランブックの最大の価値です
  • まず頻度の高い障害1件から手順化するのがスタートとして最適です
  • 障害対応のたびにランブックを更新して精度を上げていく運用が重要です
  • 月1回の見直しタイミングを設定すると更新が習慣化しやすくなります

次回は 本番運用チェックリスト(Laravel版) を学びます。リリース前の確認を標準化する実践的なチェックリストを解説します。

The post 第35回: 障害対応ランブック作成 — 障害のたびに「どうすればいいか」を考えていませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第34回: Queue監視とアラート設計 — 失敗件数だけ見ていて大丈夫ですか? https://phpl4b.com/422/?utm_source=rss&utm_medium=rss&utm_campaign=34_queue%25e7%259b%25a3%25e8%25a6%2596%25e3%2581%25a8%25e3%2582%25a2%25e3%2583%25a9%25e3%2583%25bc%25e3%2583%2588%25e8%25a8%25ad%25e8%25a8%2588 Tue, 24 Mar 2026 00:00:00 +0000 https://phpl4b.com/422/ Queue の失敗件数がゼロでも、処理が遅延していればユーザーへの影響は出ています。メール送信が1時間遅れる、決済処理が詰まっている——こうした「静かな障害」は失敗件数の監視だけでは検出できません。

The post 第34回: Queue監視とアラート設計 — 失敗件数だけ見ていて大丈夫ですか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第34回: Queue監視とアラート設計 — 失敗件数だけ見ていて大丈夫ですか?

章: 第8章: パフォーマンスと本番運用実践

ジョブが滞留していることに、いつ気づきますか?

Queue の失敗件数がゼロでも、処理が遅延していればユーザーへの影響は出ています。メール送信が1時間遅れる、決済処理が詰まっている——こうした「静かな障害」は失敗件数の監視だけでは検出できません。

遅延時間・失敗率・再試行回数の3点を定点観測することが、Queue運用の品質を保つ鍵です。

問題の本質と解決策

問題: 失敗件数のみを監視すると、ジョブが滞留して遅延が増加していても検出が遅れます。再試行が繰り返されている状態も「失敗」としてカウントされないことがあります。

解決策: Queue のラグ(遅延秒数)と失敗件数を組み合わせた閾値でアラートを設定します。Slack などの通知チャネルに自動送信することで、問題の早期検出が可能になります。

監視なし vs 監視あり 比較

観点 監視なし 遅延+失敗の複合監視
滞留の検出 ユーザー報告で気づく ラグ閾値超過で自動検出
失敗の検出 手動でログ確認 失敗件数閾値でアラート
再試行ループ 気づかずに放置 再試行回数で検出
対応までの時間 遅い(報告依存) 速い(自動通知)

チェックポイント: Queue の監視にラグ(遅延秒数)の閾値は設定されていますか?失敗件数だけでなくラグ監視を追加することで、「遅いが失敗していない」状態も検出できます。

実装サンプル


<?php
if ($failedJobs > 10 || $queueLagSeconds > 120) {
    Notification::route('slack', config('services.slack.webhook'))
        ->notify(new QueueAlertNotification($failedJobs, $queueLagSeconds));
}

まとめ & 次のステップ

  • Queue監視は遅延時間・失敗件数・再試行回数の3指標をセットで見ます
  • 失敗件数がゼロでも遅延増加は障害の予兆になります
  • 閾値は最初低めに設定し、誤検知を調整しながら適切な値に近づけます
  • Laravel Horizon を使うと Queue 監視ダッシュボードが簡単に構築できます
  • まずはラグ監視1つをSlack通知に連携するところから始めましょう

次回は 障害対応ランブック作成 を学びます。障害時の初動を標準化するための手順書の作り方を解説します。

The post 第34回: Queue監視とアラート設計 — 失敗件数だけ見ていて大丈夫ですか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第33回: 本番DBマイグレーション戦略 — テーブルロックでサービスを止めていませんか? https://phpl4b.com/420/?utm_source=rss&utm_medium=rss&utm_campaign=33_%25e6%259c%25ac%25e7%2595%25aadb%25e3%2583%259e%25e3%2582%25a4%25e3%2582%25b0%25e3%2583%25ac%25e3%2583%25bc%25e3%2582%25b7%25e3%2583%25a7%25e3%2583%25b3%25e6%2588%25a6%25e7%2595%25a5 Mon, 23 Mar 2026 00:00:00 +0000 https://phpl4b.com/420/ ALTER TABLE をそのまま実行すると、完了するまでテーブルがロックされます。数分間の書き込み停止が発生し、サービス障害として記録されます。

The post 第33回: 本番DBマイグレーション戦略 — テーブルロックでサービスを止めていませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第33回: 本番DBマイグレーション戦略 — テーブルロックでサービスを止めていませんか?

章: 第8章: パフォーマンスと本番運用実践

1000万件のテーブルにカラムを追加したら、何が起きますか?

ALTER TABLE をそのまま実行すると、完了するまでテーブルがロックされます。数分間の書き込み停止が発生し、サービス障害として記録されます。

本番DBへのマイグレーションは「速さ」より「テーブルロック時間の最小化」と「戻せること」を優先した設計が必要です。

問題の本質と解決策

問題: 巨大テーブルへの直接変更はロック時間が長く、その間のリクエストが詰まります。また、失敗時にロールバックが難しいケースもあります。

解決策: 「追加 → 移行 → 切替 → 削除」の4段階で変更を積み上げます。各ステップを別リリースとして実施することで、いつでもロールバックできる状態を保ちながら変更を完了できます。

一括変更 vs 段階変更 比較

観点 一括変更(ALTER直実行) 4段階の段階変更
テーブルロック時間 全データ件数に比例して長い 各ステップは短時間
サービスへの影響 書き込み停止が発生 各ステップで影響を最小化
ロールバック 難しいケースがある 各段階で戻せる
変更完了までの時間 短い(リスクは高い) 複数リリースをまたぐ

チェックポイント: 本番DBへの変更手順に「ロールバック条件と手順」が含まれていますか?手順書に「戻し方」が書かれていない変更は、障害時に判断が遅れます。

マイグレーション戦略サンプル


# 例: 段階移行
# 1) nullableな新カラム追加
# 2) バッチで既存データ移行
# 3) アプリを新カラム参照に切替
# 4) 旧カラム削除(別リリース)

まとめ & 次のステップ

  • 本番DBマイグレーションはロック時間の最小化と「戻せること」を優先します
  • 「追加→移行→切替→削除」の4段階を別リリースとして実施するのが安全策です
  • 大量データの移行はバッチで分割して実行し、長時間ロックを避けます
  • pt-online-schema-changegh-ost などのツールも選択肢に入れましょう
  • まずは本番DBへの変更に必ずロールバック手順を付ける習慣をつけましょう

次回は Queue監視とアラート設計 を学びます。ジョブの遅延と失敗を早期に検出するための監視設計を解説します。

The post 第33回: 本番DBマイグレーション戦略 — テーブルロックでサービスを止めていませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第32回: ゼロダウンタイムデプロイ基礎 — デプロイのたびにサービスを止めていませんか? https://phpl4b.com/418/?utm_source=rss&utm_medium=rss&utm_campaign=32_%25e3%2582%25bc%25e3%2583%25ad%25e3%2583%2580%25e3%2582%25a6%25e3%2583%25b3%25e3%2582%25bf%25e3%2582%25a4%25e3%2583%25a0%25e3%2583%2587%25e3%2583%2597%25e3%2583%25ad%25e3%2582%25a4%25e5%259f%25ba%25e7%25a4%258e Sun, 22 Mar 2026 00:00:00 +0000 https://phpl4b.com/418/ 「コードを更新してからマイグレーションを実行する」「マイグレーション後にコードを反映する」——どちらの順番を選ぶかで、デプロイ中の短時間障害が発生するかどうかが変わります。

The post 第32回: ゼロダウンタイムデプロイ基礎 — デプロイのたびにサービスを止めていませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第32回: ゼロダウンタイムデプロイ基礎 — デプロイのたびにサービスを止めていませんか?

章: 第8章: パフォーマンスと本番運用実践

アプリの更新とDB変更、どちらを先にやっていますか?

「コードを更新してからマイグレーションを実行する」「マイグレーション後にコードを反映する」——どちらの順番を選ぶかで、デプロイ中の短時間障害が発生するかどうかが変わります。

ゼロダウンタイムデプロイは「止めない」ための技術ではなく、互換性を保ちながら段階的に変更を積み上げる設計思想です。

問題の本質と解決策

問題: アプリコードとDB変更の順番が誤っていると、新旧コードが同時に走る瞬間に不整合が起き、エラーが発生します。また、マイグレーションとワーカー再起動のタイミングも重要です。

解決策: デプロイ手順を固定化し、互換性のある変更を小さく積み上げます。新コード配置 → マイグレーション → キャッシュ更新 → ワーカー再起動の順番を守ることが基本です。

デプロイ手順あり・なし 比較

観点 手順なし(その都度判断) 手順あり(順序固定)
デプロイ中のエラーリスク 手順ミスで頻発 互換性設計で最小化
ワーカーの不整合 古いコードのまま動き続ける queue:restart で確実に更新
ロールバック 手順が曖昧で時間がかかる 手順書通りに即時実行
属人化 担当者によって手順が変わる チーム全員が同じ手順

チェックポイント: デプロイ後に php artisan queue:restart を実行していますか?ワーカーは自動では再起動されないため、古いコードのまま動き続けることがあります。

デプロイ手順サンプル


# 例: デプロイ順序
# 1) 新コード配置
# 2) composer install --no-dev
# 3) php artisan migrate --force
# 4) php artisan config:cache && php artisan route:cache
# 5) ワーカー再起動
php artisan queue:restart

まとめ & 次のステップ

  • ゼロダウンタイムデプロイは互換性のある変更を小さく積み上げる設計思想です
  • デプロイ手順(コード→マイグレーション→キャッシュ→ワーカー再起動)を固定化します
  • DBとアプリコードの互換性を常に2バージョン分維持することが原則です
  • queue:restart はデプロイ後の必須手順として自動化に組み込みましょう
  • まずはデプロイ手順書を1つ作ることから始めましょう

次回は 本番DBマイグレーション戦略 を学びます。巨大テーブルへの変更をサービス影響なく行うための段階設計を解説します。

The post 第32回: ゼロダウンタイムデプロイ基礎 — デプロイのたびにサービスを止めていませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第31回: レート制限の高度化設計 — 全ユーザーに同じ制限をかけていませんか? https://phpl4b.com/416/?utm_source=rss&utm_medium=rss&utm_campaign=31_%25e3%2583%25ac%25e3%2583%25bc%25e3%2583%2588%25e5%2588%25b6%25e9%2599%2590%25e3%2581%25ae%25e9%25ab%2598%25e5%25ba%25a6%25e5%258c%2596%25e8%25a8%25ad%25e8%25a8%2588 Sat, 21 Mar 2026 00:00:00 +0000 https://phpl4b.com/416/ 未認証のスクレイパーも、プレミアムプランのユーザーも、同じ制限値が適用されている——こうした設計は、正規ユーザーの体験を損ないながら悪意ある攻撃には十分機能しないことがあります。

The post 第31回: レート制限の高度化設計 — 全ユーザーに同じ制限をかけていませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第31回: レート制限の高度化設計 — 全ユーザーに同じ制限をかけていませんか?

章: 第8章: パフォーマンスと本番運用実践

「一律60リクエスト/分」で本当に十分ですか?

未認証のスクレイパーも、プレミアムプランのユーザーも、同じ制限値が適用されている——こうした設計は、正規ユーザーの体験を損ないながら悪意ある攻撃には十分機能しないことがあります。

レート制限は「一律」から「属性別」に進化させることで、正規ユーザーへの影響を最小化しながら、不正アクセスを効果的に遮断できます。

問題の本質と解決策

問題: 全ユーザーに同じ制限を適用すると、APIをヘビーに使う正規ユーザーがブロックされる一方、認証情報を持つ攻撃者には制限が緩すぎる場合があります。

解決策: RateLimiter::for() でユーザーの認証状態やプラン属性に応じて制限値を分岐します。未認証はIPアドレスで厳しく制限し、認証済みはユーザーIDで緩やかに制限するのが基本パターンです。

一律制限 vs 属性別制限 比較

観点 一律制限 属性別制限(認証状態・プラン別)
正規ユーザーへの影響 ヘビーユーザーがブロックされやすい プランに応じた適切な制限
攻撃者への制限 認証済み攻撃者に緩い 未認証は厳しくIPで制限
実装の柔軟性 固定値のみ 動的に計算可能
運用のしやすさ シンプル 分岐が明確で変更しやすい

チェックポイント: 未認証ユーザーと認証済みユーザーで制限値を分けていますか?同一値を設定しているなら、まずここから見直しましょう。

実装サンプル


<?php
RateLimiter::for('api', function (Request $request) {
    if ($request->user()) {
        return Limit::perMinute(120)->by('user:' . $request->user()->id);
    }
    return Limit::perMinute(30)->by('ip:' . $request->ip());
});

まとめ & 次のステップ

  • レート制限はユーザー属性(認証状態・プラン)ごとに分けることで実用性が上がります
  • 未認証はIPベース・認証済みはユーザーIDベースで制限するのが基本パターンです
  • 制限超過時のレスポンス(429)には Retry-After ヘッダを付けてUXを改善します
  • まずは未認証と認証済みを分けるだけでも大きな効果があります
  • 導入後は制限ヒット率を監視して閾値を調整していきましょう

次回は ゼロダウンタイムデプロイ基礎 を学びます。サービスを止めずにデプロイするための順序設計を解説します。

The post 第31回: レート制限の高度化設計 — 全ユーザーに同じ制限をかけていませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第30回: 認証強化(2FA/セッション管理) — パスワードだけで守れていると思っていませんか? https://phpl4b.com/414/?utm_source=rss&utm_medium=rss&utm_campaign=30_%25e8%25aa%258d%25e8%25a8%25bc%25e5%25bc%25b7%25e5%258c%25962fa-%25e3%2582%25bb%25e3%2583%2583%25e3%2582%25b7%25e3%2583%25a7%25e3%2583%25b3%25e7%25ae%25a1%25e7%2590%2586 Fri, 20 Mar 2026 00:00:00 +0000 https://phpl4b.com/414/ パスワードの使い回しや情報流出は日常的に起きています。「パスワードを設定している」だけでは、現代の認証基準を満たしているとは言えません。

The post 第30回: 認証強化(2FA/セッション管理) — パスワードだけで守れていると思っていませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第30回: 認証強化(2FA/セッション管理) — パスワードだけで守れていると思っていませんか?

章: 第8章: パフォーマンスと本番運用実践

パスワードが漏れたとき、あなたのアプリは大丈夫ですか?

パスワードの使い回しや情報流出は日常的に起きています。「パスワードを設定している」だけでは、現代の認証基準を満たしているとは言えません。

2要素認証(2FA)とセッション管理を組み合わせることで、パスワードが漏えいした場合でも不正ログインを防ぐ防御層を追加できます。

問題の本質と解決策

問題: パスワード認証だけでは、認証情報の漏えいや推測攻撃に対して脆弱です。セッションの固定化攻撃(Session Fixation)のリスクもあります。

解決策: ログイン成功後に session()->regenerate() でセッションIDを再生成します。さらに2FAコードの確認を追加することで、認証要素を「知識」+「所持」の2層にします。管理者アカウントから段階的に導入するのが現実的な進め方です。

1段階認証 vs 2FA+セッション管理 比較

観点 パスワードのみ 2FA+セッション再生成
パスワード漏えい時 即座に不正ログイン可能 2FAコードがなければログイン不可
セッション固定攻撃 脆弱 regenerate() で無効化
UXへの影響 なし 2FAステップが追加される
導入の優先度 基本 管理者・機密操作から優先

チェックポイント: Auth::login() の後に $request->session()->regenerate() を呼んでいますか?セッションIDを再生成しないと固定化攻撃のリスクが残ります。

実装サンプル


<?php
// ログイン成功後に2FA状態を確認
if ($user->two_factor_secret) {
    session(['2fa:user:id' => $user->id]);
    return redirect()->route('2fa.challenge');
}

Auth::login($user);
$request->session()->regenerate();

まとめ & 次のステップ

  • パスワード漏えい前提で防御層を追加することが現代の認証設計の基本です
  • ログイン後は必ず session()->regenerate() でセッションIDを再生成します
  • 2FAは管理者アカウントから段階的に導入するのが現実的です
  • Laravel Fortify を使うと2FAの実装基盤をすぐに用意できます
  • まずは管理画面だけでも2FAを有効にするところから始めましょう

次回は レート制限の高度化設計 を学びます。ユーザー属性に応じた柔軟なアクセス制限の設計方法を解説します。

The post 第30回: 認証強化(2FA/セッション管理) — パスワードだけで守れていると思っていませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第29回: S3ストレージ設計の基本 — 「とりあえず公開バケット」で大丈夫ですか? https://phpl4b.com/412/?utm_source=rss&utm_medium=rss&utm_campaign=29_s3%25e3%2582%25b9%25e3%2583%2588%25e3%2583%25ac%25e3%2583%25bc%25e3%2582%25b8%25e8%25a8%25ad%25e8%25a8%2588%25e3%2581%25ae%25e5%259f%25ba%25e6%259c%25ac Thu, 19 Mar 2026 00:00:00 +0000 https://phpl4b.com/412/ 「とりあえず公開バケットにアップロード」——この判断が、後から情報漏えいのリスクを生む原因になります。

The post 第29回: S3ストレージ設計の基本 — 「とりあえず公開バケット」で大丈夫ですか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第29回: S3ストレージ設計の基本 — 「とりあえず公開バケット」で大丈夫ですか?

章: 第8章: パフォーマンスと本番運用実践

ファイルの公開範囲、きちんと設計されていますか?

「とりあえず公開バケットにアップロード」——この判断が、後から情報漏えいのリスクを生む原因になります。

請求書・個人情報・契約書などの機密ファイルが、URLさえ知っていれば誰でも閲覧できる状態になっていませんか?S3の権限設計とURL発行方針は、アーキテクチャ設計の最初に決める必要があります。

問題の本質と解決策

問題: 公開バケットに機密ファイルを置くと、URLが漏れた瞬間にアクセスが可能になります。また、非公開バケットの設計を後から変えるのは影響範囲が大きくなりがちです。

解決策: 機密ファイルは非公開バケットに置き、アクセス時は temporaryUrl() で期限付き署名URLを発行します。公開ファイル(アイコン・サムネイル等)とは明確にバケットを分けて管理します。

公開バケット vs 非公開バケット 比較

観点 公開バケット 非公開バケット + temporaryUrl
アクセス制御 URLを知れば誰でもアクセス可 期限付きURLのみアクセス可
機密ファイルへの適性 ✗ 不適切 ◎ 適切
実装コスト 低い 低〜中(数行で実装可能)
URL漏えい時のリスク 恒久的なアクセス可能 URL期限切れで無効化

チェックポイント: アップロード先のバケットは「公開情報用」と「機密情報用」で分けていますか?同一バケットに混在させると権限管理が複雑になります。

実装サンプル


<?php
// 保存
$path = Storage::disk('s3')->putFile('invoices', $request->file('pdf'));

// 一時URL(非公開ファイル)
$url = Storage::disk('s3')->temporaryUrl($path, now()->addMinutes(10));

return response()->json(['url' => $url]);

まとめ & 次のステップ

  • 機密ファイルは非公開バケットに置き、temporaryUrl() で期限付きURLを発行します
  • 公開ファイルと機密ファイルはバケットを分けて管理することが基本設計です
  • temporaryUrl() の有効期限は用途に応じて数分〜数十分で設定します
  • バケットのアクセスポリシーは最小権限の原則(Least Privilege)で設定しましょう
  • まず「このファイルは公開していい情報か」を設計段階で問いかける習慣をつけましょう

次回は 認証強化(2FA/セッション管理) を学びます。パスワード漏えい前提で守りを固める認証設計を解説します。

The post 第29回: S3ストレージ設計の基本 — 「とりあえず公開バケット」で大丈夫ですか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第28回: バッチ処理の分割と再開戦略 — 「途中で止まったバッチ」をゼロから再実行していませんか? https://phpl4b.com/410/?utm_source=rss&utm_medium=rss&utm_campaign=28_%25e3%2583%2590%25e3%2583%2583%25e3%2583%2581%25e5%2587%25a6%25e7%2590%2586%25e3%2581%25ae%25e5%2588%2586%25e5%2589%25b2%25e3%2581%25a8%25e5%2586%258d%25e9%2596%258b%25e6%2588%25a6%25e7%2595%25a5 Wed, 18 Mar 2026 00:00:00 +0000 https://phpl4b.com/410/ 100万件のデータを処理するバッチが、90万件まで進んだところでメモリエラーで止まった——残り10万件のためにゼロから再実行するのは、時間もコストもかかります。

The post 第28回: バッチ処理の分割と再開戦略 — 「途中で止まったバッチ」をゼロから再実行していませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第28回: バッチ処理の分割と再開戦略 — 「途中で止まったバッチ」をゼロから再実行していませんか?

章: 第8章: パフォーマンスと本番運用実践

数時間かけたバッチが途中で失敗したら、どうしますか?

100万件のデータを処理するバッチが、90万件まで進んだところでメモリエラーで止まった——残り10万件のためにゼロから再実行するのは、時間もコストもかかります。

バッチを小さく分割し、途中から再開できる設計にしておけば、失敗時のダメージを最小限に抑えられます。Laravelの chunkById と Queue を組み合わせた設計が、この問題の現実的な解決策です。

問題の本質と解決策

問題: 一括処理は途中失敗時の再実行コストが高く、メモリ消費も大きくなります。また、処理が長時間にわたるとタイムアウトやロック競合のリスクも増えます。

解決策: chunkById() でデータを小分けにし、各チャンクをジョブとしてQueueに積みます。ジョブ単位で成否が管理されるため、失敗したチャンクだけを再試行でき、処理の再開が容易になります。

一括処理 vs 分割処理 比較

観点 一括処理 chunkById + Queue分割
失敗時の影響 全件やり直し 失敗チャンクだけ再試行
メモリ消費 全件分確保が必要 チャンクサイズ分のみ
タイムアウトリスク 高い 低い(小単位で完結)
進捗の可視化 難しい ジョブ完了数で把握可能

チェックポイント: chunk() ではなく chunkById() を使っていますか?chunk() はオフセットで取得するため、処理中にレコードが削除されると取りこぼしが発生します。chunkById() は主キーで範囲を絞るため安全です。

実装サンプル


<?php
User::query()->where('active', 1)->chunkById(500, function ($users) {
    foreach ($users as $user) {
        dispatch(new SyncUserReportJob($user->id));
    }
});

まとめ & 次のステップ

  • 大きなバッチは小さく分割し、各単位をQueueジョブとして扱うことで安全に処理できます
  • chunkById() は主キーで絞り込むため、処理中のレコード変動に強いです
  • ジョブ単位で失敗管理ができるため、途中再開のコストが大幅に下がります
  • チャンクサイズは500〜1000件を目安にメモリとスループットのバランスを調整します
  • まずは最も件数が多いバッチ処理1つを chunkById に切り替えるところから始めましょう

次回は S3ストレージ設計の基本 を学びます。ファイルの公開範囲と署名付きURLの使い方を解説します。

The post 第28回: バッチ処理の分割と再開戦略 — 「途中で止まったバッチ」をゼロから再実行していませんか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第27回: スケジューラ設計と再実行耐性 — 「2回実行されても大丈夫」な設計になっていますか? https://phpl4b.com/408/?utm_source=rss&utm_medium=rss&utm_campaign=27_%25e3%2582%25b9%25e3%2582%25b1%25e3%2582%25b8%25e3%2583%25a5%25e3%2583%25bc%25e3%2583%25a9%25e8%25a8%25ad%25e8%25a8%2588%25e3%2581%25a8%25e5%2586%258d%25e5%25ae%259f%25e8%25a1%258c%25e8%2580%2590%25e6%2580%25a7 Tue, 17 Mar 2026 00:00:00 +0000 https://phpl4b.com/408/ 定期バッチが何らかの理由で二重起動された場合——同じデータが2回送信される、請求が重複する、集計値がずれる——こうした事故が起きた経験はありませんか?

The post 第27回: スケジューラ設計と再実行耐性 — 「2回実行されても大丈夫」な設計になっていますか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>
第27回: スケジューラ設計と再実行耐性 — 「2回実行されても大丈夫」な設計になっていますか?

章: 第8章: パフォーマンスと本番運用実践

スケジュールジョブが2回実行されたら、何が起きますか?

定期バッチが何らかの理由で二重起動された場合——同じデータが2回送信される、請求が重複する、集計値がずれる——こうした事故が起きた経験はありませんか?

cronは「必ず1回だけ実行される」保証がありません。ネットワーク障害・サーバー再起動・デプロイのタイミングによって、同じジョブが複数回起動するケースは現実に起こります。idempotent(冪等)な実装重複実行防止がスケジューラ設計の核心です。

問題の本質と解決策

問題: 重複実行を前提としない設計では、2回目の実行が副作用をもたらします。また、複数サーバーでそれぞれがスケジュールを起動すると、さらに複雑な問題が生じます。

解決策: withoutOverlapping() で同じジョブの並行実行を防ぎ、onOneServer() で複数サーバーでも1台のみ実行されるよう制御します。処理そのものも「何度実行しても同じ結果になる」設計にします。

重複実行対策あり・なし 比較

観点 対策なし 対策あり
前回の実行中に次回が起動 並行実行され二重処理が発生 withoutOverlapping() でスキップ
複数サーバーで起動 台数分のジョブが走る onOneServer() で1台に限定
データの冪等性 二重INSERT・二重送信が起きうる 実行済みフラグや upsert で防ぐ
障害時の再試行 手作業で判断 安全に再実行できる

チェックポイント: スケジュールジョブに withoutOverlapping()onOneServer() を付けていますか?どちらか一方だけでは不完全です。キャッシュドライバが database または redis であることも確認しましょう。

実装サンプル


<?php
// app/Console/Kernel.php
protected function schedule(Schedule $schedule): void
{
    $schedule->command('reports:daily')
        ->dailyAt('01:00')
        ->withoutOverlapping()
        ->onOneServer();
}

まとめ & 次のステップ

  • cronは「必ず1回だけ実行される」保証がないため、冪等な設計が前提です
  • withoutOverlapping() で並行実行を防ぎ、onOneServer() で複数サーバーに対応します
  • 処理自体も「何度実行しても同じ結果」になるよう upsert や実行済みフラグで設計します
  • onOneServer() はキャッシュドライバが database または redis である必要があります
  • まずは最も重要なバッチジョブ1つに両メソッドを付けるところから始めましょう

次回は バッチ処理の分割と再開戦略 を学びます。大量データを安全に処理するための分割設計を解説します。

The post 第27回: スケジューラ設計と再実行耐性 — 「2回実行されても大丈夫」な設計になっていますか? first appeared on 未経験から実務レベルへ|PHP初心者向け実践学習ブログ.

]]>