<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>模組七：突發流量應對 on Tarragon</title><link>https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/</link><description>Recent content in 模組七：突發流量應對 on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Sat, 20 Jun 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/index.xml" rel="self" type="application/rss+xml"/><item><title>突發流量的分類</title><link>https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/burst-classification/</link><pubDate>Sat, 20 Jun 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/burst-classification/</guid><description>&lt;p>這篇把突發流量依能不能事前知道分成兩類，各列來源、流量倍率、持續時間與特徵。可預期的一類（行銷活動、新聞曝光）可以事前準備容量，這篇寫準備要從活動前多久開始由什麼決定，以及 collector 在活動前要準備的接收端台數與配額、寫入儲存層的壓測與 SDK 端的取樣設定；各項目排在活動前幾天的完整時程在 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="可預期峰值從 T-90 到 T-0 的準備時程：容量計畫、quota 申請、壓測、game day 與 pre-scaling 各排在事件前幾天、排在那裡的理由與項目之間的依賴，pre-scaling 的做法、watch room、event tier 分級與準備時間不夠時被壓縮的部分，以及事後 retro">9.11 高峰事件準備&lt;/a>。不可預期的一類（病毒傳播、error storm）靠架構設計吸收衝擊，這篇寫 collector 遇到 error storm 時保留哪些資料。&lt;/p>
&lt;h2 id="可預期突發">可預期突發&lt;/h2>
&lt;p>事前知道流量會增加，有時間準備。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>來源&lt;/th>
 &lt;th>流量倍率&lt;/th>
 &lt;th>持續時間&lt;/th>
 &lt;th>特徵&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>行銷活動（促銷、限時折扣）&lt;/td>
 &lt;td>5-50x&lt;/td>
 &lt;td>數小時～數天&lt;/td>
 &lt;td>流量集中在活動開始的前幾分鐘&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>新聞曝光（媒體報導、社群爆紅）&lt;/td>
 &lt;td>10-100x&lt;/td>
 &lt;td>數小時&lt;/td>
 &lt;td>不可控的流量曲線、峰值在發佈後 1-2 小時&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>定時推播（每日報表、週報）&lt;/td>
 &lt;td>2-10x&lt;/td>
 &lt;td>分鐘級&lt;/td>
 &lt;td>短暫但可精確預測時間&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>新版本推送（app store 更新）&lt;/td>
 &lt;td>3-10x&lt;/td>
 &lt;td>數天（逐漸擴散）&lt;/td>
 &lt;td>流量緩慢上升、峰值在推送後 24-48 小時&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>可預期突發的應對核心是&lt;strong>容量預備&lt;/strong> — 活動前擴容、活動後縮回。&lt;/p>
&lt;h3 id="容量預備的前置時間與-collector-在活動前要準備的項目">容量預備的前置時間與 collector 在活動前要準備的項目&lt;/h3>
&lt;p>可預期突發能事前準備，而準備要從活動前多久開始，由各準備項目的產出交給誰、它發現的狀況要多久修好決定。容量估算、配額申請、壓力測試（&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/load-test/" data-link-title="Load Test" data-link-desc="說明在預期流量下驗證容量、延遲與降級策略的測試">Load Test&lt;/a>）、故障演練（&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/game-day/" data-link-title="Game Day" data-link-desc="說明事故演練如何驗證流程、工具與團隊協作">Game Day&lt;/a>）與預先擴容各排在活動前幾天、為什麼排在那裡，以及準備時間不夠時被壓縮掉的是什麼，在 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="可預期峰值從 T-90 到 T-0 的準備時程：容量計畫、quota 申請、壓測、game day 與 pre-scaling 各排在事件前幾天、排在那裡的理由與項目之間的依賴，pre-scaling 的做法、watch room、event tier 分級與準備時間不夠時被壓縮的部分，以及事後 retro">9.11 高峰事件準備&lt;/a>〈T-90 → T-0 準備時程〉與〈Event tier 分級〉。容量估算有兩種算法：平常的流量乘上歷史倍率、再加安全係數，在 &lt;a href="https://tarrragon.github.io/blog/devops/operations/05-capacity-planning/peak-estimation/" data-link-title="峰值估算" data-link-desc="要估一個服務的峰值該準備多少時，先分清峰值屬於哪一種形狀、再用歷史倍率階梯與安全係數推算，並知道安全係數的數學根據在飽和曲線">峰值估算&lt;/a>〈用歷史倍率階梯推可預期峰值〉與〈安全係數的數學根據在飽和曲線〉；從業務預估經換算鏈與三點估計算出各層台數，連同活動的預算，在 &lt;a href="https://tarrragon.github.io/blog/devops/operations/05-capacity-planning/planned-peak-sizing-and-budget/" data-link-title="預知的大流量要加多大、編多少預算：從業務預估到擴容規格與費用區間的換算鏈、給決策者與會計的數字，以及每次活動之後的校準" data-link-desc="行銷活動、檔期這類事先知道的大流量，容量規劃怎麼從業務預估換算成峰值請求量、各層要開幾台與擴容的計費時數，再換算成費用區間；三點估計怎麼帶著預估的誤差，給決策者的選項要附規格、費用、不足時的後果與回退方式，給會計的預算要對齊增量與付款時點，以及每次活動之後校準換算係數、沒有歷史資料時怎麼起步">預知的大流量要加多大、編多少預算：從業務預估到擴容規格與費用區間的換算鏈、給決策者與會計的數字，以及每次活動之後的校準&lt;/a>〈從業務預估到台數：換算鏈、換算係數的來源與三點估計〉。&lt;/p>
&lt;p>套到 collector 上，活動前要準備的是三件事。接收端的台數與配額，從活動期間 SDK 送出的事件量估，事件量跟著使用者數與每人觸發的事件數變。壓力測試除了量接收端，也要量寫入儲存層的處理量：直接寫 PostgreSQL 的架構，背壓（&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="下游處理能力不足時向上游回傳「慢下來」訊號的流量控制機制 — 監控系統中 collector 用 HTTP 429 向 SDK 傳遞背壓">Backpressure&lt;/a>）常常先從寫入那一段出現（&lt;a href="https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/scale-tier-response/" data-link-title="規模分級應對表" data-link-desc="自用級 → 中型 → 大型 → 商業網站級的四級應對方案 — 每級的觸發條件、架構組成和成本">規模分級應對表&lt;/a>〈Tier 3：大型（10000-100000 events/sec）〉）。SDK 端的動態取樣與事件優先級，在活動前設好觸發條件並演練一次；SDK 從 collector 回傳的 429 判斷要不要降低取樣率（&lt;a href="https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/degradation-strategy/" data-link-title="降級策略" data-link-desc="系統超載時犧牲什麼保住什麼 — 動態取樣、事件優先級、功能降級、聚合前移四種策略">降級策略&lt;/a>〈觸發條件〉）。這一項的前置時間取決於設定怎麼送到客戶端：取樣設定由遠端設定下發時，活動前幾天改得到；編在 app 裡時，改設定要發新版，設定要比活動提早至少「發版審查加上使用者更新」所需的時間改好（新版本的流量峰值在推送後 24-48 小時，見上面〈可預期突發〉的來源表）。&lt;/p>
&lt;p>配額申請被拒、或壓測測出的寫入瓶頸在活動前修不完時，collector 有兩種處置。一是超出容量的事件量由 queue 先接住、事後追趕（&lt;a href="https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/queue-buffering/" data-link-title="Queue 緩衝" data-link-desc="在 ingestion 和 processing 之間加 message queue 做 burst 緩衝 — Kafka / NATS / Redis Streams 的選型和引入條件">Queue 緩衝&lt;/a>），代價是排在 queue 裡的事件在活動期間看不到；錯誤與延遲這類要即時看的事件，依事件優先級走不排隊的路徑。二是由 SDK 降低取樣率，減少送進來的事件。&lt;/p>
&lt;h2 id="不可預期突發">不可預期突發&lt;/h2>
&lt;p>事前不知道流量會增加，只能靠架構設計吸收。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>來源&lt;/th>
 &lt;th>流量倍率&lt;/th>
 &lt;th>持續時間&lt;/th>
 &lt;th>特徵&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>病毒傳播（社群分享爆量）&lt;/td>
 &lt;td>10-1000x&lt;/td>
 &lt;td>數小時&lt;/td>
 &lt;td>完全無法預測、可能超過任何預備容量&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DDoS 攻擊&lt;/td>
 &lt;td>100-10000x&lt;/td>
 &lt;td>不定&lt;/td>
 &lt;td>惡意流量、需要 WAF / CDN 擋在前面&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Error storm（app bug 觸發大量 error）&lt;/td>
 &lt;td>依 bug 影響範圍&lt;/td>
 &lt;td>直到 hotfix&lt;/td>
 &lt;td>每個受影響的使用者都在送 error 事件&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>外部依賴復原（積壓請求一次湧入）&lt;/td>
 &lt;td>2-5x&lt;/td>
 &lt;td>分鐘級&lt;/td>
 &lt;td>依賴恢復後積壓的 retry 一起到達&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>依賴恢復時積壓請求一起到達的第二波湧入，以及它轉成停在失效的條件，見 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/overload-outcomes/" data-link-title="9.16 負載超過容量時服務的表現：變慢、請求失敗、無回應、程序終止，尖峰過去或應對切換之後仍持續的停在失效、擺盪與第二波湧入，以及應對選出的降級回應，各自的判斷標準、成因、應對與看得到它的監控層" data-link-desc="負載超過容量（過載）時，服務呈現的結果分成變慢、請求失敗（抵達後被拒與根本沒有抵達）、無回應、程序終止，以及尖峰過去、依賴恢復或應對切換之後仍持續的停在失效、擺盪與第二波湧入；每一種的判斷標準、通常的成因與應對，哪一種先出現由先耗盡的資源與等待是否設有上限決定，影響範圍怎麼隨時間擴大，服務端監控的各層各自看得到哪一種，降級回應怎麼計數，過載在資料上造成的重複寫入、接受後遺失與讀到舊資料，以及描述一次過載要寫出的項目">9.16 負載超過容量時服務的表現&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>這篇把突發流量依能不能事前知道分成兩類，各列來源、流量倍率、持續時間與特徵。可預期的一類（行銷活動、新聞曝光）可以事前準備容量，這篇寫準備要從活動前多久開始由什麼決定，以及 collector 在活動前要準備的接收端台數與配額、寫入儲存層的壓測與 SDK 端的取樣設定；各項目排在活動前幾天的完整時程在 <a href="/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="可預期峰值從 T-90 到 T-0 的準備時程：容量計畫、quota 申請、壓測、game day 與 pre-scaling 各排在事件前幾天、排在那裡的理由與項目之間的依賴，pre-scaling 的做法、watch room、event tier 分級與準備時間不夠時被壓縮的部分，以及事後 retro">9.11 高峰事件準備</a>。不可預期的一類（病毒傳播、error storm）靠架構設計吸收衝擊，這篇寫 collector 遇到 error storm 時保留哪些資料。</p>
<h2 id="可預期突發">可預期突發</h2>
<p>事前知道流量會增加，有時間準備。</p>
<table>
  <thead>
      <tr>
          <th>來源</th>
          <th>流量倍率</th>
          <th>持續時間</th>
          <th>特徵</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>行銷活動（促銷、限時折扣）</td>
          <td>5-50x</td>
          <td>數小時～數天</td>
          <td>流量集中在活動開始的前幾分鐘</td>
      </tr>
      <tr>
          <td>新聞曝光（媒體報導、社群爆紅）</td>
          <td>10-100x</td>
          <td>數小時</td>
          <td>不可控的流量曲線、峰值在發佈後 1-2 小時</td>
      </tr>
      <tr>
          <td>定時推播（每日報表、週報）</td>
          <td>2-10x</td>
          <td>分鐘級</td>
          <td>短暫但可精確預測時間</td>
      </tr>
      <tr>
          <td>新版本推送（app store 更新）</td>
          <td>3-10x</td>
          <td>數天（逐漸擴散）</td>
          <td>流量緩慢上升、峰值在推送後 24-48 小時</td>
      </tr>
  </tbody>
</table>
<p>可預期突發的應對核心是<strong>容量預備</strong> — 活動前擴容、活動後縮回。</p>
<h3 id="容量預備的前置時間與-collector-在活動前要準備的項目">容量預備的前置時間與 collector 在活動前要準備的項目</h3>
<p>可預期突發能事前準備，而準備要從活動前多久開始，由各準備項目的產出交給誰、它發現的狀況要多久修好決定。容量估算、配額申請、壓力測試（<a href="/blog/backend/knowledge-cards/load-test/" data-link-title="Load Test" data-link-desc="說明在預期流量下驗證容量、延遲與降級策略的測試">Load Test</a>）、故障演練（<a href="/blog/backend/knowledge-cards/game-day/" data-link-title="Game Day" data-link-desc="說明事故演練如何驗證流程、工具與團隊協作">Game Day</a>）與預先擴容各排在活動前幾天、為什麼排在那裡，以及準備時間不夠時被壓縮掉的是什麼，在 <a href="/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="可預期峰值從 T-90 到 T-0 的準備時程：容量計畫、quota 申請、壓測、game day 與 pre-scaling 各排在事件前幾天、排在那裡的理由與項目之間的依賴，pre-scaling 的做法、watch room、event tier 分級與準備時間不夠時被壓縮的部分，以及事後 retro">9.11 高峰事件準備</a>〈T-90 → T-0 準備時程〉與〈Event tier 分級〉。容量估算有兩種算法：平常的流量乘上歷史倍率、再加安全係數，在 <a href="/blog/devops/operations/05-capacity-planning/peak-estimation/" data-link-title="峰值估算" data-link-desc="要估一個服務的峰值該準備多少時，先分清峰值屬於哪一種形狀、再用歷史倍率階梯與安全係數推算，並知道安全係數的數學根據在飽和曲線">峰值估算</a>〈用歷史倍率階梯推可預期峰值〉與〈安全係數的數學根據在飽和曲線〉；從業務預估經換算鏈與三點估計算出各層台數，連同活動的預算，在 <a href="/blog/devops/operations/05-capacity-planning/planned-peak-sizing-and-budget/" data-link-title="預知的大流量要加多大、編多少預算：從業務預估到擴容規格與費用區間的換算鏈、給決策者與會計的數字，以及每次活動之後的校準" data-link-desc="行銷活動、檔期這類事先知道的大流量，容量規劃怎麼從業務預估換算成峰值請求量、各層要開幾台與擴容的計費時數，再換算成費用區間；三點估計怎麼帶著預估的誤差，給決策者的選項要附規格、費用、不足時的後果與回退方式，給會計的預算要對齊增量與付款時點，以及每次活動之後校準換算係數、沒有歷史資料時怎麼起步">預知的大流量要加多大、編多少預算：從業務預估到擴容規格與費用區間的換算鏈、給決策者與會計的數字，以及每次活動之後的校準</a>〈從業務預估到台數：換算鏈、換算係數的來源與三點估計〉。</p>
<p>套到 collector 上，活動前要準備的是三件事。接收端的台數與配額，從活動期間 SDK 送出的事件量估，事件量跟著使用者數與每人觸發的事件數變。壓力測試除了量接收端，也要量寫入儲存層的處理量：直接寫 PostgreSQL 的架構，背壓（<a href="/blog/devops/monitoring/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="下游處理能力不足時向上游回傳「慢下來」訊號的流量控制機制 — 監控系統中 collector 用 HTTP 429 向 SDK 傳遞背壓">Backpressure</a>）常常先從寫入那一段出現（<a href="/blog/devops/operations/07-burst-traffic/scale-tier-response/" data-link-title="規模分級應對表" data-link-desc="自用級 → 中型 → 大型 → 商業網站級的四級應對方案 — 每級的觸發條件、架構組成和成本">規模分級應對表</a>〈Tier 3：大型（10000-100000 events/sec）〉）。SDK 端的動態取樣與事件優先級，在活動前設好觸發條件並演練一次；SDK 從 collector 回傳的 429 判斷要不要降低取樣率（<a href="/blog/devops/operations/07-burst-traffic/degradation-strategy/" data-link-title="降級策略" data-link-desc="系統超載時犧牲什麼保住什麼 — 動態取樣、事件優先級、功能降級、聚合前移四種策略">降級策略</a>〈觸發條件〉）。這一項的前置時間取決於設定怎麼送到客戶端：取樣設定由遠端設定下發時，活動前幾天改得到；編在 app 裡時，改設定要發新版，設定要比活動提早至少「發版審查加上使用者更新」所需的時間改好（新版本的流量峰值在推送後 24-48 小時，見上面〈可預期突發〉的來源表）。</p>
<p>配額申請被拒、或壓測測出的寫入瓶頸在活動前修不完時，collector 有兩種處置。一是超出容量的事件量由 queue 先接住、事後追趕（<a href="/blog/devops/operations/07-burst-traffic/queue-buffering/" data-link-title="Queue 緩衝" data-link-desc="在 ingestion 和 processing 之間加 message queue 做 burst 緩衝 — Kafka / NATS / Redis Streams 的選型和引入條件">Queue 緩衝</a>），代價是排在 queue 裡的事件在活動期間看不到；錯誤與延遲這類要即時看的事件，依事件優先級走不排隊的路徑。二是由 SDK 降低取樣率，減少送進來的事件。</p>
<h2 id="不可預期突發">不可預期突發</h2>
<p>事前不知道流量會增加，只能靠架構設計吸收。</p>
<table>
  <thead>
      <tr>
          <th>來源</th>
          <th>流量倍率</th>
          <th>持續時間</th>
          <th>特徵</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>病毒傳播（社群分享爆量）</td>
          <td>10-1000x</td>
          <td>數小時</td>
          <td>完全無法預測、可能超過任何預備容量</td>
      </tr>
      <tr>
          <td>DDoS 攻擊</td>
          <td>100-10000x</td>
          <td>不定</td>
          <td>惡意流量、需要 WAF / CDN 擋在前面</td>
      </tr>
      <tr>
          <td>Error storm（app bug 觸發大量 error）</td>
          <td>依 bug 影響範圍</td>
          <td>直到 hotfix</td>
          <td>每個受影響的使用者都在送 error 事件</td>
      </tr>
      <tr>
          <td>外部依賴復原（積壓請求一次湧入）</td>
          <td>2-5x</td>
          <td>分鐘級</td>
          <td>依賴恢復後積壓的 retry 一起到達</td>
      </tr>
  </tbody>
</table>
<p>依賴恢復時積壓請求一起到達的第二波湧入，以及它轉成停在失效的條件，見 <a href="/blog/backend/09-performance-capacity/overload-outcomes/" data-link-title="9.16 負載超過容量時服務的表現：變慢、請求失敗、無回應、程序終止，尖峰過去或應對切換之後仍持續的停在失效、擺盪與第二波湧入，以及應對選出的降級回應，各自的判斷標準、成因、應對與看得到它的監控層" data-link-desc="負載超過容量（過載）時，服務呈現的結果分成變慢、請求失敗（抵達後被拒與根本沒有抵達）、無回應、程序終止，以及尖峰過去、依賴恢復或應對切換之後仍持續的停在失效、擺盪與第二波湧入；每一種的判斷標準、通常的成因與應對，哪一種先出現由先耗盡的資源與等待是否設有上限決定，影響範圍怎麼隨時間擴大，服務端監控的各層各自看得到哪一種，降級回應怎麼計數，過載在資料上造成的重複寫入、接受後遺失與讀到舊資料，以及描述一次過載要寫出的項目">9.16 負載超過容量時服務的表現</a>。</p>
<p>不可預期突發的應對核心是<strong>降級</strong> — 系統在超載時自動犧牲非核心功能，保住核心功能。</p>
<h3 id="監控系統的-error-storm">監控系統的 error storm</h3>
<p>Error storm 是監控系統特有的突發場景：被監控的 app 出了 bug，每個受影響的使用者都在送 error 事件。如果有 10 萬使用者同時遇到同一個 bug，collector 瞬間收到 10 萬筆 error 事件。</p>
<p>Error storm 的矛盾：error 事件是 debug 最需要的資料，但 storm 時的大量 error 可能塞滿 collector 的接收佇列，collector 開始回 429 或丟掉資料。處理策略是<strong>保留前 N 筆完整 error（含 stack trace）、後續的 error 只計數不存原始資料</strong>。第一筆 error 的 stack trace 足夠 debug，後續的 10 萬筆只是確認影響範圍。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>突發時的降級策略 → <a href="/blog/devops/operations/07-burst-traffic/degradation-strategy/" data-link-title="降級策略" data-link-desc="系統超載時犧牲什麼保住什麼 — 動態取樣、事件優先級、功能降級、聚合前移四種策略">降級策略</a></li>
<li>不可預期突發依來源（真人需求、應用層濫用流量、體積型攻擊）分流的處置，以及負載卸除、等候室與流量清洗 → <a href="/blog/backend/09-performance-capacity/unplanned-traffic-surge/" data-link-title="9.15 無預警瞬時大流量：流量來源辨識、擴展緩衝、請求優先等級、准入控制、體積型攻擊與退路" data-link-desc="沒有準備窗口的瞬時大流量（突發流量、流量暴增）怎麼承接：依流量形狀分辨真人需求、應用層的濫用流量、體積型攻擊（DDoS），自動擴展的反應時間換算成緩衝，入口標記請求優先等級與負載卸除的順序，等候室與事前註冊這類准入控制，把體積型攻擊交給更大的邊緣網路，以及擴展跟不上時的退路">9.15 無預警瞬時大流量：流量來源辨識、擴展緩衝、請求優先等級、准入控制、體積型攻擊與退路</a></li>
<li>Queue 做 burst 緩衝 → <a href="/blog/devops/operations/07-burst-traffic/queue-buffering/" data-link-title="Queue 緩衝" data-link-desc="在 ingestion 和 processing 之間加 message queue 做 burst 緩衝 — Kafka / NATS / Redis Streams 的選型和引入條件">Queue 緩衝</a></li>
<li>可預期突發的擴容規格與預算怎麼從業務預估算出來、做成給決策者與會計的數字 → <a href="/blog/devops/operations/05-capacity-planning/planned-peak-sizing-and-budget/" data-link-title="預知的大流量要加多大、編多少預算：從業務預估到擴容規格與費用區間的換算鏈、給決策者與會計的數字，以及每次活動之後的校準" data-link-desc="行銷活動、檔期這類事先知道的大流量，容量規劃怎麼從業務預估換算成峰值請求量、各層要開幾台與擴容的計費時數，再換算成費用區間；三點估計怎麼帶著預估的誤差，給決策者的選項要附規格、費用、不足時的後果與回退方式，給會計的預算要對齊增量與付款時點，以及每次活動之後校準換算係數、沒有歷史資料時怎麼起步">預知的大流量要加多大、編多少預算：從業務預估到擴容規格與費用區間的換算鏈、給決策者與會計的數字，以及每次活動之後的校準</a></li>
<li>不同規模的應對方案 → <a href="/blog/devops/operations/07-burst-traffic/scale-tier-response/" data-link-title="規模分級應對表" data-link-desc="自用級 → 中型 → 大型 → 商業網站級的四級應對方案 — 每級的觸發條件、架構組成和成本">規模分級應對表</a></li>
</ul>
]]></content:encoded></item><item><title>降級策略</title><link>https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/degradation-strategy/</link><pubDate>Sat, 20 Jun 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/degradation-strategy/</guid><description>&lt;p>降級策略的核心決策是「超載時犧牲什麼保住什麼」。犧牲的是精度、延遲或非核心功能；保住的是核心功能的可用性。沒有降級策略的系統在超載時所有功能一起逾時或失敗，核心功能沒有被優先保住。&lt;/p>
&lt;h2 id="動態取樣">動態取樣&lt;/h2>
&lt;p>流量超過閾值時自動降低取樣率。平時 100% 收集、超載時降到 10% — 仍有資料可分析，只是精度下降。&lt;/p>
&lt;h3 id="觸發條件">觸發條件&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>訊號&lt;/th>
 &lt;th>動作&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Collector 回 429 次數 &amp;gt; N / 分鐘&lt;/td>
 &lt;td>SDK 降低取樣率 50%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>連續 429 超過 M 分鐘&lt;/td>
 &lt;td>SDK 再降到 10%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>429 消失且 buffer 清空&lt;/td>
 &lt;td>SDK 恢復 100%&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="取樣的公平性">取樣的公平性&lt;/h3>
&lt;p>動態取樣不應該只丟新事件保留舊事件（FIFO 丟棄）— 這會讓取樣偏向「burst 初期的事件」。更好的策略是隨機取樣（每個事件有 sampling_rate 的機率被保留），讓取樣後的資料仍然能代表整體分佈。&lt;/p>
&lt;p>取樣後的事件帶 &lt;code>_sampling_rate&lt;/code> 欄位，分析時用 &lt;code>1 / sampling_rate&lt;/code> 做加權還原。&lt;/p>
&lt;h2 id="事件優先級">事件優先級&lt;/h2>
&lt;p>不同事件類型的 debug 價值不同。超載時先丟價值低的，保留價值高的。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>優先級&lt;/th>
 &lt;th>事件類型&lt;/th>
 &lt;th>理由&lt;/th>
 &lt;th>超載時處理&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>最高&lt;/td>
 &lt;td>error&lt;/td>
 &lt;td>debug 核心 — 丟了就查不到問題&lt;/td>
 &lt;td>全部保留&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>高&lt;/td>
 &lt;td>lifecycle&lt;/td>
 &lt;td>session 邊界 — 影響 session 分析&lt;/td>
 &lt;td>全部保留&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>中&lt;/td>
 &lt;td>metric&lt;/td>
 &lt;td>趨勢可從取樣還原&lt;/td>
 &lt;td>降低取樣率&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>低&lt;/td>
 &lt;td>event&lt;/td>
 &lt;td>行為分析可接受精度損失&lt;/td>
 &lt;td>降低取樣率或暫停&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>優先級的判斷原則：「這個事件丟了、要花多少時間從其他來源補回相同資訊」。Error 的 stack trace 丟了幾乎不可能從其他來源補回；event 的 click 計數可以從後續資料的趨勢推測。&lt;/p>
&lt;h2 id="功能降級">功能降級&lt;/h2>
&lt;p>非核心功能暫時關閉或降低更新頻率，把資源留給核心功能。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>功能&lt;/th>
 &lt;th>正常模式&lt;/th>
 &lt;th>降級模式&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Dashboard 即時刷新&lt;/td>
 &lt;td>每秒查詢&lt;/td>
 &lt;td>每 30 秒查詢&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Rule engine 評估&lt;/td>
 &lt;td>每筆事件即時評估&lt;/td>
 &lt;td>累積 10 筆批次評估&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>JSONL 匯出&lt;/td>
 &lt;td>隨時可匯出&lt;/td>
 &lt;td>暫停（避免 I/O 競爭）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>降採樣 job&lt;/td>
 &lt;td>每小時跑&lt;/td>
 &lt;td>延後到流量恢復後補跑&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>降級的觸發和恢復應該自動化 — 用 collector 的內部 metric（goroutine pool 使用率、寫入延遲）作為訊號。&lt;/p>
&lt;h2 id="聚合前移">聚合前移&lt;/h2>
&lt;p>讓 SDK 端做預聚合，減少送到 collector 的事件數量。&lt;/p>
&lt;p>平時：每次 click 送一筆 &lt;code>button.clicked&lt;/code> 事件 → 100 次 click = 100 筆事件。
聚合前移：SDK 累積 10 秒內的 click → 送一筆 &lt;code>button.clicked&lt;/code> 帶 &lt;code>count: 17&lt;/code> → 100 次 click = ~10 筆事件。&lt;/p>
&lt;p>聚合前移犧牲的是事件粒度（失去每次 click 的精確時間戳），換取的是 10x 的事件量減少。適用於高頻但單筆資訊量低的事件（click、scroll、mousemove）。&lt;/p>
&lt;p>聚合前移的觸發也可以是動態的 — collector 回 429 時 SDK 自動啟用聚合前移，流量恢復後關閉。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;ul>
&lt;li>突發流量的分類 → &lt;a href="https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/burst-classification/" data-link-title="突發流量的分類" data-link-desc="突發流量依能不能事前知道分成兩類：各自的來源、倍率與持續時間，可預期突發的準備要提前多久由什麼決定、collector 在活動前要準備的項目，以及 collector 遇到 error storm 時的資料保留">突發流量的分類&lt;/a>&lt;/li>
&lt;li>Queue 做更大規模的緩衝 → &lt;a href="https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/queue-buffering/" data-link-title="Queue 緩衝" data-link-desc="在 ingestion 和 processing 之間加 message queue 做 burst 緩衝 — Kafka / NATS / Redis Streams 的選型和引入條件">Queue 緩衝&lt;/a>&lt;/li>
&lt;li>不同規模的應對方案 → &lt;a href="https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/scale-tier-response/" data-link-title="規模分級應對表" data-link-desc="自用級 → 中型 → 大型 → 商業網站級的四級應對方案 — 每級的觸發條件、架構組成和成本">規模分級應對表&lt;/a>&lt;/li>
&lt;li>背壓和 rate limit 的基礎 → &lt;a href="https://tarrragon.github.io/blog/devops/operations/03-traffic-management/" data-link-title="模組三：流量管控" data-link-desc="收到的流量超過處理能力時怎麼辦 — 背壓、rate limit、熔斷、bulkhead 四種防護機制">模組三 流量管控&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>降級策略的核心決策是「超載時犧牲什麼保住什麼」。犧牲的是精度、延遲或非核心功能；保住的是核心功能的可用性。沒有降級策略的系統在超載時所有功能一起逾時或失敗，核心功能沒有被優先保住。</p>
<h2 id="動態取樣">動態取樣</h2>
<p>流量超過閾值時自動降低取樣率。平時 100% 收集、超載時降到 10% — 仍有資料可分析，只是精度下降。</p>
<h3 id="觸發條件">觸發條件</h3>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>動作</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Collector 回 429 次數 &gt; N / 分鐘</td>
          <td>SDK 降低取樣率 50%</td>
      </tr>
      <tr>
          <td>連續 429 超過 M 分鐘</td>
          <td>SDK 再降到 10%</td>
      </tr>
      <tr>
          <td>429 消失且 buffer 清空</td>
          <td>SDK 恢復 100%</td>
      </tr>
  </tbody>
</table>
<h3 id="取樣的公平性">取樣的公平性</h3>
<p>動態取樣不應該只丟新事件保留舊事件（FIFO 丟棄）— 這會讓取樣偏向「burst 初期的事件」。更好的策略是隨機取樣（每個事件有 sampling_rate 的機率被保留），讓取樣後的資料仍然能代表整體分佈。</p>
<p>取樣後的事件帶 <code>_sampling_rate</code> 欄位，分析時用 <code>1 / sampling_rate</code> 做加權還原。</p>
<h2 id="事件優先級">事件優先級</h2>
<p>不同事件類型的 debug 價值不同。超載時先丟價值低的，保留價值高的。</p>
<table>
  <thead>
      <tr>
          <th>優先級</th>
          <th>事件類型</th>
          <th>理由</th>
          <th>超載時處理</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>最高</td>
          <td>error</td>
          <td>debug 核心 — 丟了就查不到問題</td>
          <td>全部保留</td>
      </tr>
      <tr>
          <td>高</td>
          <td>lifecycle</td>
          <td>session 邊界 — 影響 session 分析</td>
          <td>全部保留</td>
      </tr>
      <tr>
          <td>中</td>
          <td>metric</td>
          <td>趨勢可從取樣還原</td>
          <td>降低取樣率</td>
      </tr>
      <tr>
          <td>低</td>
          <td>event</td>
          <td>行為分析可接受精度損失</td>
          <td>降低取樣率或暫停</td>
      </tr>
  </tbody>
</table>
<p>優先級的判斷原則：「這個事件丟了、要花多少時間從其他來源補回相同資訊」。Error 的 stack trace 丟了幾乎不可能從其他來源補回；event 的 click 計數可以從後續資料的趨勢推測。</p>
<h2 id="功能降級">功能降級</h2>
<p>非核心功能暫時關閉或降低更新頻率，把資源留給核心功能。</p>
<table>
  <thead>
      <tr>
          <th>功能</th>
          <th>正常模式</th>
          <th>降級模式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Dashboard 即時刷新</td>
          <td>每秒查詢</td>
          <td>每 30 秒查詢</td>
      </tr>
      <tr>
          <td>Rule engine 評估</td>
          <td>每筆事件即時評估</td>
          <td>累積 10 筆批次評估</td>
      </tr>
      <tr>
          <td>JSONL 匯出</td>
          <td>隨時可匯出</td>
          <td>暫停（避免 I/O 競爭）</td>
      </tr>
      <tr>
          <td>降採樣 job</td>
          <td>每小時跑</td>
          <td>延後到流量恢復後補跑</td>
      </tr>
  </tbody>
</table>
<p>降級的觸發和恢復應該自動化 — 用 collector 的內部 metric（goroutine pool 使用率、寫入延遲）作為訊號。</p>
<h2 id="聚合前移">聚合前移</h2>
<p>讓 SDK 端做預聚合，減少送到 collector 的事件數量。</p>
<p>平時：每次 click 送一筆 <code>button.clicked</code> 事件 → 100 次 click = 100 筆事件。
聚合前移：SDK 累積 10 秒內的 click → 送一筆 <code>button.clicked</code> 帶 <code>count: 17</code> → 100 次 click = ~10 筆事件。</p>
<p>聚合前移犧牲的是事件粒度（失去每次 click 的精確時間戳），換取的是 10x 的事件量減少。適用於高頻但單筆資訊量低的事件（click、scroll、mousemove）。</p>
<p>聚合前移的觸發也可以是動態的 — collector 回 429 時 SDK 自動啟用聚合前移，流量恢復後關閉。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>突發流量的分類 → <a href="/blog/devops/operations/07-burst-traffic/burst-classification/" data-link-title="突發流量的分類" data-link-desc="突發流量依能不能事前知道分成兩類：各自的來源、倍率與持續時間，可預期突發的準備要提前多久由什麼決定、collector 在活動前要準備的項目，以及 collector 遇到 error storm 時的資料保留">突發流量的分類</a></li>
<li>Queue 做更大規模的緩衝 → <a href="/blog/devops/operations/07-burst-traffic/queue-buffering/" data-link-title="Queue 緩衝" data-link-desc="在 ingestion 和 processing 之間加 message queue 做 burst 緩衝 — Kafka / NATS / Redis Streams 的選型和引入條件">Queue 緩衝</a></li>
<li>不同規模的應對方案 → <a href="/blog/devops/operations/07-burst-traffic/scale-tier-response/" data-link-title="規模分級應對表" data-link-desc="自用級 → 中型 → 大型 → 商業網站級的四級應對方案 — 每級的觸發條件、架構組成和成本">規模分級應對表</a></li>
<li>背壓和 rate limit 的基礎 → <a href="/blog/devops/operations/03-traffic-management/" data-link-title="模組三：流量管控" data-link-desc="收到的流量超過處理能力時怎麼辦 — 背壓、rate limit、熔斷、bulkhead 四種防護機制">模組三 流量管控</a></li>
</ul>
]]></content:encoded></item><item><title>Queue 緩衝</title><link>https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/queue-buffering/</link><pubDate>Sat, 20 Jun 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/queue-buffering/</guid><description>&lt;p>Message queue 放在 ingestion（接收事件）和 processing（寫入 storage）之間，把兩者解耦。Ingestion 只負責驗證和寫入 queue，processing 按自己的速度從 queue 消費。Queue 做 burst 的時間緩衝 — 高峰時 queue 積壓、低峰時 worker 追上。&lt;/p>
&lt;h2 id="為什麼不直接寫-db">為什麼不直接寫 DB&lt;/h2>
&lt;p>直接寫 DB（SQLite / PostgreSQL）的問題是 ingestion 速度被 DB 寫入速度限制。DB 寫入慢（鎖定、WAL flush、索引更新）時，HTTP handler 的 goroutine 等在 &lt;code>Storage.Store()&lt;/code> 上 — goroutine 積壓 → 記憶體上升 → 最終 OOM 或 response timeout（記憶體先到上限是程序終止，用戶端的逾時先到是無回應，判斷標準與監控訊號見 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/overload-outcomes/" data-link-title="9.16 負載超過容量時服務的表現：變慢、請求失敗、無回應、程序終止，尖峰過去或應對切換之後仍持續的停在失效、擺盪與第二波湧入，以及應對選出的降級回應，各自的判斷標準、成因、應對與看得到它的監控層" data-link-desc="負載超過容量（過載）時，服務呈現的結果分成變慢、請求失敗（抵達後被拒與根本沒有抵達）、無回應、程序終止，以及尖峰過去、依賴恢復或應對切換之後仍持續的停在失效、擺盪與第二波湧入；每一種的判斷標準、通常的成因與應對，哪一種先出現由先耗盡的資源與等待是否設有上限決定，影響範圍怎麼隨時間擴大，服務端監控的各層各自看得到哪一種，降級回應怎麼計數，過載在資料上造成的重複寫入、接受後遺失與讀到舊資料，以及描述一次過載要寫出的項目">9.16 負載超過容量時服務的表現&lt;/a>）。&lt;/p>
&lt;p>Queue 的解決方式是把「接收」和「寫入」分開：接收端只做 JSON 驗證 + 寫入 queue（微秒級），處理端從 queue 讀取 + 寫入 DB（毫秒級）。接收端的吞吐量不再受 DB 限制。&lt;/p>
&lt;h3 id="取捨">取捨&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>直接寫 DB&lt;/th>
 &lt;th>經過 Queue&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>延遲&lt;/td>
 &lt;td>事件寫完 DB 即可查詢&lt;/td>
 &lt;td>事件要等 worker 消費後才可查詢&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>吞吐&lt;/td>
 &lt;td>受 DB 寫入速度限制&lt;/td>
 &lt;td>受 queue 寫入速度限制（通常遠高於 DB）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>複雜度&lt;/td>
 &lt;td>一個元件&lt;/td>
 &lt;td>三個元件（collector + queue + worker）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>故障模式&lt;/td>
 &lt;td>DB 掛了事件丟失（除非有背壓）&lt;/td>
 &lt;td>Queue 做持久化，DB 掛了事件在 queue 等待&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>自用工具場景不需要 queue — 單 collector + SQLite 的直接寫入足夠。Queue 的引入條件是「直接寫 DB 的背壓開始頻繁觸發」。&lt;/p>
&lt;h2 id="候選類型">候選類型&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Queue&lt;/th>
 &lt;th>特點&lt;/th>
 &lt;th>適用場景&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Kafka&lt;/strong>&lt;/td>
 &lt;td>高吞吐、持久化、消費者群組&lt;/td>
 &lt;td>大規模（&amp;gt; 10 萬 events/sec）、多消費者&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>NATS JetStream&lt;/strong>&lt;/td>
 &lt;td>輕量、低延遲、Go 原生&lt;/td>
 &lt;td>中型（千 ~ 萬 events/sec）、Go 生態&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Redis Streams&lt;/strong>&lt;/td>
 &lt;td>用既有 Redis、XADD/XREAD API&lt;/td>
 &lt;td>中型、已有 Redis 基礎設施&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="選型判斷">選型判斷&lt;/h3>
&lt;p>已有 Redis → 先用 Redis Streams（零新增元件）。Go 為主的技術棧 → NATS JetStream（Go 原生 client、單 binary 部署）。需要跨消費者群組或日誌級持久化 → Kafka。&lt;/p>
&lt;h3 id="引入條件">引入條件&lt;/h3>
&lt;p>Queue 的引入是架構複雜度的顯著上升（一個元件變三個）。明確的觸發條件：&lt;/p>
&lt;ul>
&lt;li>背壓（429 回應）頻繁觸發（每天 &amp;gt; 100 次）且持續（不只是瞬間 burst）&lt;/li>
&lt;li>寫入延遲的 P95 超過 500ms（DB 成為瓶頸）&lt;/li>
&lt;li>需要多個 consumer（同一批事件要送到不同的下游 — analytics DB、alert engine、archive）&lt;/li>
&lt;/ul>
&lt;h2 id="監控系統的-queue-架構">監控系統的 Queue 架構&lt;/h2>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">SDK ──→ Collector (ingestion only)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> ├─ 驗證 JSON Schema
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ├─ Redaction
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> └─ 寫入 Queue
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> ├── Worker A → PostgreSQL（主 storage）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl"> ├── Worker B → 降採樣 → Summary tables
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl"> └── Worker C → Rule engine → Alert&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Collector 瘦身為 ingestion-only — 只做接收、驗證、redaction 和寫入 queue。Storage 寫入、降採樣、rule engine 都移到 worker 群。Collector 的吞吐瓶頸從 DB 寫入變成 queue 寫入（queue 的寫入吞吐通常是 DB 的 10-100 倍）。&lt;/p></description><content:encoded><![CDATA[<p>Message queue 放在 ingestion（接收事件）和 processing（寫入 storage）之間，把兩者解耦。Ingestion 只負責驗證和寫入 queue，processing 按自己的速度從 queue 消費。Queue 做 burst 的時間緩衝 — 高峰時 queue 積壓、低峰時 worker 追上。</p>
<h2 id="為什麼不直接寫-db">為什麼不直接寫 DB</h2>
<p>直接寫 DB（SQLite / PostgreSQL）的問題是 ingestion 速度被 DB 寫入速度限制。DB 寫入慢（鎖定、WAL flush、索引更新）時，HTTP handler 的 goroutine 等在 <code>Storage.Store()</code> 上 — goroutine 積壓 → 記憶體上升 → 最終 OOM 或 response timeout（記憶體先到上限是程序終止，用戶端的逾時先到是無回應，判斷標準與監控訊號見 <a href="/blog/backend/09-performance-capacity/overload-outcomes/" data-link-title="9.16 負載超過容量時服務的表現：變慢、請求失敗、無回應、程序終止，尖峰過去或應對切換之後仍持續的停在失效、擺盪與第二波湧入，以及應對選出的降級回應，各自的判斷標準、成因、應對與看得到它的監控層" data-link-desc="負載超過容量（過載）時，服務呈現的結果分成變慢、請求失敗（抵達後被拒與根本沒有抵達）、無回應、程序終止，以及尖峰過去、依賴恢復或應對切換之後仍持續的停在失效、擺盪與第二波湧入；每一種的判斷標準、通常的成因與應對，哪一種先出現由先耗盡的資源與等待是否設有上限決定，影響範圍怎麼隨時間擴大，服務端監控的各層各自看得到哪一種，降級回應怎麼計數，過載在資料上造成的重複寫入、接受後遺失與讀到舊資料，以及描述一次過載要寫出的項目">9.16 負載超過容量時服務的表現</a>）。</p>
<p>Queue 的解決方式是把「接收」和「寫入」分開：接收端只做 JSON 驗證 + 寫入 queue（微秒級），處理端從 queue 讀取 + 寫入 DB（毫秒級）。接收端的吞吐量不再受 DB 限制。</p>
<h3 id="取捨">取捨</h3>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>直接寫 DB</th>
          <th>經過 Queue</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>延遲</td>
          <td>事件寫完 DB 即可查詢</td>
          <td>事件要等 worker 消費後才可查詢</td>
      </tr>
      <tr>
          <td>吞吐</td>
          <td>受 DB 寫入速度限制</td>
          <td>受 queue 寫入速度限制（通常遠高於 DB）</td>
      </tr>
      <tr>
          <td>複雜度</td>
          <td>一個元件</td>
          <td>三個元件（collector + queue + worker）</td>
      </tr>
      <tr>
          <td>故障模式</td>
          <td>DB 掛了事件丟失（除非有背壓）</td>
          <td>Queue 做持久化，DB 掛了事件在 queue 等待</td>
      </tr>
  </tbody>
</table>
<p>自用工具場景不需要 queue — 單 collector + SQLite 的直接寫入足夠。Queue 的引入條件是「直接寫 DB 的背壓開始頻繁觸發」。</p>
<h2 id="候選類型">候選類型</h2>
<table>
  <thead>
      <tr>
          <th>Queue</th>
          <th>特點</th>
          <th>適用場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Kafka</strong></td>
          <td>高吞吐、持久化、消費者群組</td>
          <td>大規模（&gt; 10 萬 events/sec）、多消費者</td>
      </tr>
      <tr>
          <td><strong>NATS JetStream</strong></td>
          <td>輕量、低延遲、Go 原生</td>
          <td>中型（千 ~ 萬 events/sec）、Go 生態</td>
      </tr>
      <tr>
          <td><strong>Redis Streams</strong></td>
          <td>用既有 Redis、XADD/XREAD API</td>
          <td>中型、已有 Redis 基礎設施</td>
      </tr>
  </tbody>
</table>
<h3 id="選型判斷">選型判斷</h3>
<p>已有 Redis → 先用 Redis Streams（零新增元件）。Go 為主的技術棧 → NATS JetStream（Go 原生 client、單 binary 部署）。需要跨消費者群組或日誌級持久化 → Kafka。</p>
<h3 id="引入條件">引入條件</h3>
<p>Queue 的引入是架構複雜度的顯著上升（一個元件變三個）。明確的觸發條件：</p>
<ul>
<li>背壓（429 回應）頻繁觸發（每天 &gt; 100 次）且持續（不只是瞬間 burst）</li>
<li>寫入延遲的 P95 超過 500ms（DB 成為瓶頸）</li>
<li>需要多個 consumer（同一批事件要送到不同的下游 — analytics DB、alert engine、archive）</li>
</ul>
<h2 id="監控系統的-queue-架構">監控系統的 Queue 架構</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">SDK ──→ Collector (ingestion only)
</span></span><span class="line"><span class="ln">2</span><span class="cl">           │
</span></span><span class="line"><span class="ln">3</span><span class="cl">           ├─ 驗證 JSON Schema
</span></span><span class="line"><span class="ln">4</span><span class="cl">           ├─ Redaction
</span></span><span class="line"><span class="ln">5</span><span class="cl">           └─ 寫入 Queue
</span></span><span class="line"><span class="ln">6</span><span class="cl">                 │
</span></span><span class="line"><span class="ln">7</span><span class="cl">                 ├── Worker A → PostgreSQL（主 storage）
</span></span><span class="line"><span class="ln">8</span><span class="cl">                 ├── Worker B → 降採樣 → Summary tables
</span></span><span class="line"><span class="ln">9</span><span class="cl">                 └── Worker C → Rule engine → Alert</span></span></code></pre></div><p>Collector 瘦身為 ingestion-only — 只做接收、驗證、redaction 和寫入 queue。Storage 寫入、降採樣、rule engine 都移到 worker 群。Collector 的吞吐瓶頸從 DB 寫入變成 queue 寫入（queue 的寫入吞吐通常是 DB 的 10-100 倍）。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>突發流量的分類 → <a href="/blog/devops/operations/07-burst-traffic/burst-classification/" data-link-title="突發流量的分類" data-link-desc="突發流量依能不能事前知道分成兩類：各自的來源、倍率與持續時間，可預期突發的準備要提前多久由什麼決定、collector 在活動前要準備的項目，以及 collector 遇到 error storm 時的資料保留">突發流量的分類</a></li>
<li>降級策略 → <a href="/blog/devops/operations/07-burst-traffic/degradation-strategy/" data-link-title="降級策略" data-link-desc="系統超載時犧牲什麼保住什麼 — 動態取樣、事件優先級、功能降級、聚合前移四種策略">降級策略</a></li>
<li>規模分級的完整應對 → <a href="/blog/devops/operations/07-burst-traffic/scale-tier-response/" data-link-title="規模分級應對表" data-link-desc="自用級 → 中型 → 大型 → 商業網站級的四級應對方案 — 每級的觸發條件、架構組成和成本">規模分級應對表</a></li>
<li>Queue 的選型和操作實務 → <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">backend 非同步佇列</a></li>
</ul>
]]></content:encoded></item><item><title>規模分級應對表</title><link>https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/scale-tier-response/</link><pubDate>Sat, 20 Jun 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/operations/07-burst-traffic/scale-tier-response/</guid><description>&lt;p>突發流量的應對方案隨服務規模分成四級。每一級在前一級的基礎上增加元件，複雜度和成本同步上升。選擇哪一級取決於「預期的峰值流量」和「可接受的降級程度」。&lt;/p>
&lt;h2 id="四級分級">四級分級&lt;/h2>
&lt;h3 id="tier-1自用級-100-eventssec">Tier 1：自用級（&amp;lt; 100 events/sec）&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">SDK ──→ Collector (單 binary + SQLite)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>設定&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>架構&lt;/td>
 &lt;td>單 Go binary、SQLite embedded&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>流量控制&lt;/td>
 &lt;td>背壓（channel buffer 10000 + 429）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>突發應對&lt;/td>
 &lt;td>SDK 離線 buffer 吸收短暫 burst&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>降級&lt;/td>
 &lt;td>無（流量不會到需要降級的程度）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>成本&lt;/td>
 &lt;td>零（自有主機、零外部依賴）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>適用&lt;/td>
 &lt;td>自用工具、開發期測試、小型團隊&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Tier 1 的假設是峰值流量不超過 SQLite WAL mode 的寫入能力（每秒數千筆）。自用場景下這個假設幾乎永遠成立。&lt;/p>
&lt;h3 id="tier-2中型100-10000-eventssec">Tier 2：中型（100-10000 events/sec）&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl"> ┌─ Collector A ──→ PostgreSQL
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">SDK ──→ LB ─┤
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> └─ Collector B ──→ PostgreSQL&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>設定&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>架構&lt;/td>
 &lt;td>多 collector + load balancer + PostgreSQL&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>流量控制&lt;/td>
 &lt;td>背壓 + per-SDK rate limit&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>突發應對&lt;/td>
 &lt;td>LB 分散流量 + collector 水平擴展&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>降級&lt;/td>
 &lt;td>動態取樣（超載時 SDK 降到 10%）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>成本&lt;/td>
 &lt;td>PostgreSQL + LB 的維護（可用 managed service 降低維護成本）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>適用&lt;/td>
 &lt;td>使用者數百到數千、有付費能力&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Tier 1 → Tier 2 的觸發：SQLite 的 &lt;code>database is locked&lt;/code> 頻繁出現，或 dashboard 的聚合查詢需要 PostgreSQL 的能力。&lt;/p>
&lt;h3 id="tier-3大型10000-100000-eventssec">Tier 3：大型（10000-100000 events/sec）&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl"> ┌─ Collector A ─┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">SDK ──→ LB ─┤ ├─→ Queue ──→ Worker 群 ──→ PostgreSQL
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> └─ Collector B ─┘&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>設定&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>架構&lt;/td>
 &lt;td>Collector 群 + queue（NATS / Kafka）+ worker 群 + PostgreSQL&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>流量控制&lt;/td>
 &lt;td>背壓 + rate limit + bulkhead&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>突發應對&lt;/td>
 &lt;td>Queue 做時間緩衝（積壓 → 追趕）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>降級&lt;/td>
 &lt;td>動態取樣 + 事件優先級 + 功能降級&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>成本&lt;/td>
 &lt;td>Queue + worker 的基礎設施（顯著上升）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>適用&lt;/td>
 &lt;td>中大型 SaaS、使用者數萬&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Tier 2 → Tier 3 的觸發：直接寫 PostgreSQL 的背壓頻繁觸發（即使有多個 collector 寫入）。&lt;/p>
&lt;h3 id="tier-4商業網站級-100000-eventssec">Tier 4：商業網站級（&amp;gt; 100000 events/sec）&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">SDK ──→ CDN/Edge ──→ LB ──→ Collector 群 ──→ Kafka ──→ Worker 群 ──→ 分層 DB
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ├─ 即時查詢 DB（ClickHouse / TimescaleDB）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> └─ 歸檔 DB（S3 + Athena）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>設定&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>架構&lt;/td>
 &lt;td>CDN edge 收集 + Kafka + 分層存儲&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>流量控制&lt;/td>
 &lt;td>CDN rate limit + 全鏈路背壓&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>突發應對&lt;/td>
 &lt;td>Kafka partition 水平擴展 + auto-scaling worker&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>降級&lt;/td>
 &lt;td>全套（動態取樣 + 優先級 + 聚合前移 + 功能降級）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>成本&lt;/td>
 &lt;td>基礎設施團隊級別的投入&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>適用&lt;/td>
 &lt;td>大型 SaaS、電商、社群平台&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Tier 3 → Tier 4 的觸發：Kafka 單 cluster 的吞吐不夠、或查詢需要跨日誌級的時間序列分析。&lt;/p></description><content:encoded><![CDATA[<p>突發流量的應對方案隨服務規模分成四級。每一級在前一級的基礎上增加元件，複雜度和成本同步上升。選擇哪一級取決於「預期的峰值流量」和「可接受的降級程度」。</p>
<h2 id="四級分級">四級分級</h2>
<h3 id="tier-1自用級-100-eventssec">Tier 1：自用級（&lt; 100 events/sec）</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">SDK ──→ Collector (單 binary + SQLite)</span></span></code></pre></div><table>
  <thead>
      <tr>
          <th>維度</th>
          <th>設定</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>架構</td>
          <td>單 Go binary、SQLite embedded</td>
      </tr>
      <tr>
          <td>流量控制</td>
          <td>背壓（channel buffer 10000 + 429）</td>
      </tr>
      <tr>
          <td>突發應對</td>
          <td>SDK 離線 buffer 吸收短暫 burst</td>
      </tr>
      <tr>
          <td>降級</td>
          <td>無（流量不會到需要降級的程度）</td>
      </tr>
      <tr>
          <td>成本</td>
          <td>零（自有主機、零外部依賴）</td>
      </tr>
      <tr>
          <td>適用</td>
          <td>自用工具、開發期測試、小型團隊</td>
      </tr>
  </tbody>
</table>
<p>Tier 1 的假設是峰值流量不超過 SQLite WAL mode 的寫入能力（每秒數千筆）。自用場景下這個假設幾乎永遠成立。</p>
<h3 id="tier-2中型100-10000-eventssec">Tier 2：中型（100-10000 events/sec）</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">         ┌─ Collector A ──→ PostgreSQL
</span></span><span class="line"><span class="ln">2</span><span class="cl">SDK ──→ LB ─┤
</span></span><span class="line"><span class="ln">3</span><span class="cl">         └─ Collector B ──→ PostgreSQL</span></span></code></pre></div><table>
  <thead>
      <tr>
          <th>維度</th>
          <th>設定</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>架構</td>
          <td>多 collector + load balancer + PostgreSQL</td>
      </tr>
      <tr>
          <td>流量控制</td>
          <td>背壓 + per-SDK rate limit</td>
      </tr>
      <tr>
          <td>突發應對</td>
          <td>LB 分散流量 + collector 水平擴展</td>
      </tr>
      <tr>
          <td>降級</td>
          <td>動態取樣（超載時 SDK 降到 10%）</td>
      </tr>
      <tr>
          <td>成本</td>
          <td>PostgreSQL + LB 的維護（可用 managed service 降低維護成本）</td>
      </tr>
      <tr>
          <td>適用</td>
          <td>使用者數百到數千、有付費能力</td>
      </tr>
  </tbody>
</table>
<p>Tier 1 → Tier 2 的觸發：SQLite 的 <code>database is locked</code> 頻繁出現，或 dashboard 的聚合查詢需要 PostgreSQL 的能力。</p>
<h3 id="tier-3大型10000-100000-eventssec">Tier 3：大型（10000-100000 events/sec）</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">         ┌─ Collector A ─┐
</span></span><span class="line"><span class="ln">2</span><span class="cl">SDK ──→ LB ─┤               ├─→ Queue ──→ Worker 群 ──→ PostgreSQL
</span></span><span class="line"><span class="ln">3</span><span class="cl">         └─ Collector B ─┘</span></span></code></pre></div><table>
  <thead>
      <tr>
          <th>維度</th>
          <th>設定</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>架構</td>
          <td>Collector 群 + queue（NATS / Kafka）+ worker 群 + PostgreSQL</td>
      </tr>
      <tr>
          <td>流量控制</td>
          <td>背壓 + rate limit + bulkhead</td>
      </tr>
      <tr>
          <td>突發應對</td>
          <td>Queue 做時間緩衝（積壓 → 追趕）</td>
      </tr>
      <tr>
          <td>降級</td>
          <td>動態取樣 + 事件優先級 + 功能降級</td>
      </tr>
      <tr>
          <td>成本</td>
          <td>Queue + worker 的基礎設施（顯著上升）</td>
      </tr>
      <tr>
          <td>適用</td>
          <td>中大型 SaaS、使用者數萬</td>
      </tr>
  </tbody>
</table>
<p>Tier 2 → Tier 3 的觸發：直接寫 PostgreSQL 的背壓頻繁觸發（即使有多個 collector 寫入）。</p>
<h3 id="tier-4商業網站級-100000-eventssec">Tier 4：商業網站級（&gt; 100000 events/sec）</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">SDK ──→ CDN/Edge ──→ LB ──→ Collector 群 ──→ Kafka ──→ Worker 群 ──→ 分層 DB
</span></span><span class="line"><span class="ln">2</span><span class="cl">                                                                      ├─ 即時查詢 DB（ClickHouse / TimescaleDB）
</span></span><span class="line"><span class="ln">3</span><span class="cl">                                                                      └─ 歸檔 DB（S3 + Athena）</span></span></code></pre></div><table>
  <thead>
      <tr>
          <th>維度</th>
          <th>設定</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>架構</td>
          <td>CDN edge 收集 + Kafka + 分層存儲</td>
      </tr>
      <tr>
          <td>流量控制</td>
          <td>CDN rate limit + 全鏈路背壓</td>
      </tr>
      <tr>
          <td>突發應對</td>
          <td>Kafka partition 水平擴展 + auto-scaling worker</td>
      </tr>
      <tr>
          <td>降級</td>
          <td>全套（動態取樣 + 優先級 + 聚合前移 + 功能降級）</td>
      </tr>
      <tr>
          <td>成本</td>
          <td>基礎設施團隊級別的投入</td>
      </tr>
      <tr>
          <td>適用</td>
          <td>大型 SaaS、電商、社群平台</td>
      </tr>
  </tbody>
</table>
<p>Tier 3 → Tier 4 的觸發：Kafka 單 cluster 的吞吐不夠、或查詢需要跨日誌級的時間序列分析。</p>
<p>多數自架開源工具不需要超過 Tier 2。Tier 3 和 Tier 4 是商業 SaaS 的領域。</p>
<h2 id="規模遷移路徑">規模遷移路徑</h2>
<table>
  <thead>
      <tr>
          <th>遷移</th>
          <th>改什麼</th>
          <th>停機</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Tier 1 → 2</td>
          <td>Storage backend 切 PostgreSQL + 加 LB + 加 collector</td>
          <td>config change + 資料遷移（分鐘級停機）</td>
      </tr>
      <tr>
          <td>Tier 2 → 3</td>
          <td>加 queue + 改 collector 為 ingestion-only + 加 worker</td>
          <td>架構重構（需要開發時間）</td>
      </tr>
      <tr>
          <td>Tier 3 → 4</td>
          <td>加 CDN edge + 分層 DB + auto-scaling</td>
          <td>基礎設施工程（需要專職團隊）</td>
      </tr>
  </tbody>
</table>
<p>每一級的遷移成本遞增。Tier 1 → 2 是 config change 級、Tier 2 → 3 是架構重構級、Tier 3 → 4 是團隊級。選擇起始 tier 時選最低的足夠 tier — 過早引入高 tier 的複雜度是浪費。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>流量管控的四種機制 → <a href="/blog/devops/operations/03-traffic-management/" data-link-title="模組三：流量管控" data-link-desc="收到的流量超過處理能力時怎麼辦 — 背壓、rate limit、熔斷、bulkhead 四種防護機制">模組三 流量管控</a></li>
<li>容量預備和壓力測試 → <a href="/blog/devops/operations/05-capacity-planning/" data-link-title="模組五：容量規劃與壓力測試" data-link-desc="要準備多少資源才夠 — 壓力測試方法、峰值估算、成本模型、規模拐點的判斷">模組五 容量規劃</a></li>
<li>Collector 的可插拔 storage 架構 → <a href="/blog/devops/monitoring/04-collector/scaling-evolution/" data-link-title="規模演進" data-link-desc="可插拔 Storage Backend 架構 — SQLite 預設、PostgreSQL 觸發切換、時間序列 DB 長期演進">monitoring 模組四 規模演進</a></li>
<li>Queue 的選型 → <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">backend 非同步佇列</a></li>
</ul>
]]></content:encoded></item></channel></rss>