<?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>Rollback on Tarragon</title><link>https://tarrragon.github.io/blog/tags/rollback/</link><description>Recent content in Rollback on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Thu, 21 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/rollback/index.xml" rel="self" type="application/rss+xml"/><item><title>Serverless function 版本、事件來源與回復流程</title><link>https://tarrragon.github.io/blog/ci/serverless-deploy/function-version-event-flow/</link><pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/ci/serverless-deploy/function-version-event-flow/</guid><description>&lt;p>Serverless 發布流程的核心責任是把函式 artifact、&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/function-alias/" data-link-title="Function Alias" data-link-desc="說明 serverless function alias 如何把穩定入口指向特定版本並支援流量切換與回復">Function Alias&lt;/a>、權限與 &lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/event-source/" data-link-title="Event Source" data-link-desc="說明 serverless 與事件驅動流程中觸發來源如何影響 retry、dead-letter 與回復策略">Event Source&lt;/a> 一起推進。Serverless 部署看起來比長駐服務短，但每次 invocation 都依賴 runtime、IAM、event source、retry policy 與 observability；CI/CD 需要把這些條件視為發布契約。&lt;/p>
&lt;h2 id="流程定位">流程定位&lt;/h2>
&lt;p>Serverless 的風險集中在觸發條件。函式部署成功只代表新版本存在，實際風險會在 HTTP request、queue message、topic event、scheduled job 或 edge request 觸發時出現。發布流程要能區分「版本建立成功」「alias 切流量成功」「事件來源行為正確」三件事。&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>Package&lt;/td>
 &lt;td>產生 function bundle / layer&lt;/td>
 &lt;td>dependency、runtime target 是否固定&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Version&lt;/td>
 &lt;td>發布 immutable function version&lt;/td>
 &lt;td>version 是否可追到 commit&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Alias / traffic&lt;/td>
 &lt;td>控制新舊版本流量&lt;/td>
 &lt;td>alias 權重、錯誤率、冷啟動&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Permission&lt;/td>
 &lt;td>限制 IAM、secret、resource policy&lt;/td>
 &lt;td>最小權限與環境隔離&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/event-source/" data-link-title="Event Source" data-link-desc="說明 serverless 與事件驅動流程中觸發來源如何影響 retry、dead-letter 與回復策略">Event Source&lt;/a>&lt;/td>
 &lt;td>管理 trigger、retry、dead-letter&lt;/td>
 &lt;td>重試與毒訊息處理是否明確&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Recovery&lt;/td>
 &lt;td>alias rollback、disable trigger、replay&lt;/td>
 &lt;td>是否能止血與修補資料&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Package 階段負責產生可執行 bundle。Serverless 常見失敗是本機 dependency 可用，但打包後缺檔、runtime target 不符、native extension 不相容或 layer 版本漂移；CI 應在接近目標 runtime 的環境做 smoke test。&lt;/p>
&lt;p>Version 階段負責建立不可變版本。直接覆蓋 &lt;code>$LATEST&lt;/code> 會讓事故追溯困難；正式流量應指向 version 或 &lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/function-alias/" data-link-title="Function Alias" data-link-desc="說明 serverless function alias 如何把穩定入口指向特定版本並支援流量切換與回復">Function Alias&lt;/a>，讓 rollback 能把 alias 切回前一個已知版本。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/function-alias/" data-link-title="Function Alias" data-link-desc="說明 serverless function alias 如何把穩定入口指向特定版本並支援流量切換與回復">Function Alias&lt;/a> / traffic 階段負責控制流量切換。HTTP function 可以用少量權重 canary；queue trigger 則要觀察 batch failure、retry、dead-letter 與 downstream side effect，因為同一個錯誤 event 可能被重試多次。&lt;/p>
&lt;p>Permission 階段負責限制 blast radius。Serverless 函式容易因部署方便而累積過大 IAM 權限；每個 function 應只拿到必要 resource、secret 與 network access，並把 production secret 與 preview / staging 隔離。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/event-source/" data-link-title="Event Source" data-link-desc="說明 serverless 與事件驅動流程中觸發來源如何影響 retry、dead-letter 與回復策略">Event Source&lt;/a> 階段負責定義失敗重送語意。Queue、topic、object storage、HTTP 與 scheduler 的錯誤行為不同；CI/CD 文件要記錄 retry 次數、dead-letter destination、batch size、concurrency limit 與 replay 條件。&lt;/p>
&lt;p>Recovery 階段負責止血。Serverless 常見止血方式是 alias rollback、停用 trigger、降低 concurrency、清理毒訊息、重放事件或 forward fix；只回退 code 版本不一定能處理已經排入 queue 的事件。&lt;/p></description><content:encoded><![CDATA[<p>Serverless 發布流程的核心責任是把函式 artifact、<a href="/blog/ci/knowledge-cards/function-alias/" data-link-title="Function Alias" data-link-desc="說明 serverless function alias 如何把穩定入口指向特定版本並支援流量切換與回復">Function Alias</a>、權限與 <a href="/blog/ci/knowledge-cards/event-source/" data-link-title="Event Source" data-link-desc="說明 serverless 與事件驅動流程中觸發來源如何影響 retry、dead-letter 與回復策略">Event Source</a> 一起推進。Serverless 部署看起來比長駐服務短，但每次 invocation 都依賴 runtime、IAM、event source、retry policy 與 observability；CI/CD 需要把這些條件視為發布契約。</p>
<h2 id="流程定位">流程定位</h2>
<p>Serverless 的風險集中在觸發條件。函式部署成功只代表新版本存在，實際風險會在 HTTP request、queue message、topic event、scheduled job 或 edge request 觸發時出現。發布流程要能區分「版本建立成功」「alias 切流量成功」「事件來源行為正確」三件事。</p>
<table>
  <thead>
      <tr>
          <th>階段</th>
          <th>責任</th>
          <th>判讀訊號</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Package</td>
          <td>產生 function bundle / layer</td>
          <td>dependency、runtime target 是否固定</td>
      </tr>
      <tr>
          <td>Version</td>
          <td>發布 immutable function version</td>
          <td>version 是否可追到 commit</td>
      </tr>
      <tr>
          <td>Alias / traffic</td>
          <td>控制新舊版本流量</td>
          <td>alias 權重、錯誤率、冷啟動</td>
      </tr>
      <tr>
          <td>Permission</td>
          <td>限制 IAM、secret、resource policy</td>
          <td>最小權限與環境隔離</td>
      </tr>
      <tr>
          <td><a href="/blog/ci/knowledge-cards/event-source/" data-link-title="Event Source" data-link-desc="說明 serverless 與事件驅動流程中觸發來源如何影響 retry、dead-letter 與回復策略">Event Source</a></td>
          <td>管理 trigger、retry、dead-letter</td>
          <td>重試與毒訊息處理是否明確</td>
      </tr>
      <tr>
          <td>Recovery</td>
          <td>alias rollback、disable trigger、replay</td>
          <td>是否能止血與修補資料</td>
      </tr>
  </tbody>
</table>
<p>Package 階段負責產生可執行 bundle。Serverless 常見失敗是本機 dependency 可用，但打包後缺檔、runtime target 不符、native extension 不相容或 layer 版本漂移；CI 應在接近目標 runtime 的環境做 smoke test。</p>
<p>Version 階段負責建立不可變版本。直接覆蓋 <code>$LATEST</code> 會讓事故追溯困難；正式流量應指向 version 或 <a href="/blog/ci/knowledge-cards/function-alias/" data-link-title="Function Alias" data-link-desc="說明 serverless function alias 如何把穩定入口指向特定版本並支援流量切換與回復">Function Alias</a>，讓 rollback 能把 alias 切回前一個已知版本。</p>
<p><a href="/blog/ci/knowledge-cards/function-alias/" data-link-title="Function Alias" data-link-desc="說明 serverless function alias 如何把穩定入口指向特定版本並支援流量切換與回復">Function Alias</a> / traffic 階段負責控制流量切換。HTTP function 可以用少量權重 canary；queue trigger 則要觀察 batch failure、retry、dead-letter 與 downstream side effect，因為同一個錯誤 event 可能被重試多次。</p>
<p>Permission 階段負責限制 blast radius。Serverless 函式容易因部署方便而累積過大 IAM 權限；每個 function 應只拿到必要 resource、secret 與 network access，並把 production secret 與 preview / staging 隔離。</p>
<p><a href="/blog/ci/knowledge-cards/event-source/" data-link-title="Event Source" data-link-desc="說明 serverless 與事件驅動流程中觸發來源如何影響 retry、dead-letter 與回復策略">Event Source</a> 階段負責定義失敗重送語意。Queue、topic、object storage、HTTP 與 scheduler 的錯誤行為不同；CI/CD 文件要記錄 retry 次數、dead-letter destination、batch size、concurrency limit 與 replay 條件。</p>
<p>Recovery 階段負責止血。Serverless 常見止血方式是 alias rollback、停用 trigger、降低 concurrency、清理毒訊息、重放事件或 forward fix；只回退 code 版本不一定能處理已經排入 queue 的事件。</p>
<h2 id="事件來源判讀">事件來源判讀</h2>
<p>事件來源判讀的責任是找出失敗是否可重試。Serverless 常被誤判為「函式自己失敗」，但實際根因可能是 event schema、權限、上游重試或下游限流。</p>
<table>
  <thead>
      <tr>
          <th>Event source</th>
          <th>常見失敗</th>
          <th>下一步</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>HTTP / API</td>
          <td>status code、timeout、冷啟動</td>
          <td>看 latency、concurrency、alias</td>
      </tr>
      <tr>
          <td>Queue</td>
          <td>batch failure、毒訊息、重試風暴</td>
          <td>看 DLQ、batch size、visibility timeout</td>
      </tr>
      <tr>
          <td>Topic</td>
          <td>event schema 漂移</td>
          <td>驗證 publisher / subscriber 契約</td>
      </tr>
      <tr>
          <td>Object store</td>
          <td>權限或路徑 pattern 錯誤</td>
          <td>檢查 resource policy 與 filter</td>
      </tr>
      <tr>
          <td>Scheduler</td>
          <td>timezone、重入、上次執行未完成</td>
          <td>檢查 idempotency 與 lock</td>
      </tr>
  </tbody>
</table>
<p>這張表讓 release failure 能被導向正確 owner。若 event schema 變了，修 function 可能只是表面補丁；真正的 gate 要加在 publisher contract 或 sample event validation。</p>
<h2 id="最小發布-gate">最小發布 gate</h2>
<p>Serverless workflow 的最小 gate 應覆蓋 package、permission、event 與 alias。缺其中一段，部署成功就可能只是建立了一個尚未被驗證的函式版本。</p>
<ol>
<li>Package bundle，固定 runtime target 與 dependency。</li>
<li>對 bundle 執行 unit / contract / sample event test。</li>
<li>用 least privilege policy 做 deploy dry run 或 policy diff。</li>
<li>發布 immutable function version。</li>
<li>用 alias 將少量流量導向新版本。</li>
<li>觀察 error、latency、retry、DLQ 與 downstream 指標。</li>
<li>指標穩定後提高 alias 權重或完成切換。</li>
<li>指標觸發 tripwire 時切回 alias、停用 trigger 或啟動 repair。</li>
</ol>
<p>這個流程把 Serverless 發布從「上傳函式」提升成可回復流程。對事件驅動函式而言，trigger 與 retry policy 是發布契約的一部分。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>Serverless 部署總覽：回 <a href="../">Serverless 部署 CI/CD</a>。</li>
<li>Rollout 概念：讀 <a href="/blog/ci/knowledge-cards/rollout-strategy/" data-link-title="Rollout Strategy" data-link-desc="說明新版本如何以可控節奏推進到全部流量">Rollout Strategy</a>。</li>
<li>失敗處理：讀 <a href="../../github-actions-failure-flow/">CI 失敗到修復發布流程</a>。</li>
</ul>
]]></content:encoded></item><item><title>後端 migration、rollout 與 rollback 流程</title><link>https://tarrragon.github.io/blog/ci/backend-deploy/migration-rollout-rollback-flow/</link><pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/ci/backend-deploy/migration-rollout-rollback-flow/</guid><description>&lt;p>後端部署流程的核心責任是讓程式、資料與流量在相容窗口內推進。後端服務通常會同時依賴 database、queue、cache、外部 API 與 runtime config；CI/CD 需要把 build 成功、migration 安全、readiness 可信、rollback 可執行分成不同 gate。&lt;/p>
&lt;h2 id="流程定位">流程定位&lt;/h2>
&lt;p>後端部署的主要風險是有狀態依賴。前端 artifact 可以直接回退上一份靜態檔，後端服務一旦寫入新資料、消費 queue message 或呼叫外部 side effect，rollback 就不再只是換回舊 image。發布流程要先定義新舊版本如何短暫共存，再決定 migration 與流量切換順序。&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>Build&lt;/td>
 &lt;td>產生 binary、package 或 image&lt;/td>
 &lt;td>版本是否可追到 commit&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Contract test&lt;/td>
 &lt;td>驗證 API、queue、DB 相容性&lt;/td>
 &lt;td>新舊 schema / message 是否可共存&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/migration/" data-link-title="Migration" data-link-desc="說明資料或結構變更如何在服務不中斷前提下受控推進">Migration&lt;/a>&lt;/td>
 &lt;td>推進資料結構與資料狀態&lt;/td>
 &lt;td>是否可漸進、可重試、可停止&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/rollout-strategy/" data-link-title="Rollout Strategy" data-link-desc="說明新版本如何以可控節奏推進到全部流量">Rollout strategy&lt;/a>&lt;/td>
 &lt;td>分批接流量&lt;/td>
 &lt;td>readiness、error rate、latency 是否可信&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/rollback-strategy/" data-link-title="Rollback Strategy" data-link-desc="說明發布異常時如何快速回到已知可用狀態">Rollback strategy&lt;/a>&lt;/td>
 &lt;td>縮小錯誤版本影響&lt;/td>
 &lt;td>程式、資料、queue 與 config 是否可回復&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Build 階段負責產生可部署服務。服務版本要能從 runtime 反查 commit、workflow run、image digest 與 migration 版本，讓事故時能快速定位哪一次變更進入環境。&lt;/p>
&lt;p>Contract test 階段負責驗證跨邊界相容。API response、database schema、queue message 與 config key 都是契約；只測 service 內部函式，通常抓不到新舊版本並存時的破壞性變更。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/migration/" data-link-title="Migration" data-link-desc="說明資料或結構變更如何在服務不中斷前提下受控推進">Migration&lt;/a> 階段負責推進資料狀態。安全 migration 通常採 expand-and-contract：先加相容欄位或表、部署可讀新舊格式的程式、回填資料，最後移除舊格式。直接在同一次 release 刪欄位與切程式，會讓 rollback 失去空間。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/rollout-strategy/" data-link-title="Rollout Strategy" data-link-desc="說明新版本如何以可控節奏推進到全部流量">Rollout strategy&lt;/a> 階段負責控制新版本接到的流量。Rolling、canary 與 blue-green 都需要可信 readiness；readiness 應檢查服務能否接流量，而不只是 process alive。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/rollback-strategy/" data-link-title="Rollback Strategy" data-link-desc="說明發布異常時如何快速回到已知可用狀態">Rollback strategy&lt;/a> 階段負責定義失敗時的處理路由。後端 rollback 常見做法是 app rollback、config rollback、traffic rollback 或 forward fix；資料已被新程式寫入時，forward fix 往往比直接資料回滾安全。&lt;/p>
&lt;h2 id="migration-順序">Migration 順序&lt;/h2>
&lt;p>Migration 順序的責任是保留相容窗口。資料結構變更應讓至少兩個相鄰程式版本能共存，避免部署中途任何一端先完成都造成服務不可用。&lt;/p>
&lt;ol>
&lt;li>新增向前相容 schema，例如新增 nullable column 或新表。&lt;/li>
&lt;li>部署可同時讀舊欄位與新欄位的程式。&lt;/li>
&lt;li>執行 backfill 或 background migration。&lt;/li>
&lt;li>切換讀取來源或寫入路徑。&lt;/li>
&lt;li>觀察穩定後移除舊欄位、舊 index 或舊 message 格式。&lt;/li>
&lt;/ol>
&lt;p>這個順序的價值是可停止。若第 3 步回填異常，可以暫停 backfill，不必立即回退 app；若第 4 步切換後錯誤率升高，可以先切回舊讀取路徑，再評估資料修補。&lt;/p>
&lt;h2 id="rollout-判讀">Rollout 判讀&lt;/h2>
&lt;p>Rollout 判讀要同時看技術指標與業務副作用。服務能啟動不代表能安全接流量；API error、queue lag、database lock、第三方 API 錯誤與核心業務漏斗都可能是發布問題。&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>readiness 未通過&lt;/td>
 &lt;td>新版本尚未能接流量&lt;/td>
 &lt;td>暫停 rollout，查 config / 依賴&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>error rate 上升&lt;/td>
 &lt;td>新版本或相依服務契約出錯&lt;/td>
 &lt;td>降低流量或切回舊版本&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>migration lock 久&lt;/td>
 &lt;td>schema 變更影響正常查詢&lt;/td>
 &lt;td>停止 migration，改成分段方案&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>consumer lag 上升&lt;/td>
 &lt;td>worker 消費速度或 message 壞&lt;/td>
 &lt;td>暫停新版 worker 或降速&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>rollback 後仍錯&lt;/td>
 &lt;td>資料或外部 side effect 已變動&lt;/td>
 &lt;td>進入 forward fix / repair 流程&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>這些訊號要先接到發布流程。若指標只存在 dashboard 裡、workflow 不知道如何判讀，團隊仍會在事故當下靠人工臨場決策。&lt;/p></description><content:encoded><![CDATA[<p>後端部署流程的核心責任是讓程式、資料與流量在相容窗口內推進。後端服務通常會同時依賴 database、queue、cache、外部 API 與 runtime config；CI/CD 需要把 build 成功、migration 安全、readiness 可信、rollback 可執行分成不同 gate。</p>
<h2 id="流程定位">流程定位</h2>
<p>後端部署的主要風險是有狀態依賴。前端 artifact 可以直接回退上一份靜態檔，後端服務一旦寫入新資料、消費 queue message 或呼叫外部 side effect，rollback 就不再只是換回舊 image。發布流程要先定義新舊版本如何短暫共存，再決定 migration 與流量切換順序。</p>
<table>
  <thead>
      <tr>
          <th>階段</th>
          <th>責任</th>
          <th>判讀訊號</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Build</td>
          <td>產生 binary、package 或 image</td>
          <td>版本是否可追到 commit</td>
      </tr>
      <tr>
          <td>Contract test</td>
          <td>驗證 API、queue、DB 相容性</td>
          <td>新舊 schema / message 是否可共存</td>
      </tr>
      <tr>
          <td><a href="/blog/ci/knowledge-cards/migration/" data-link-title="Migration" data-link-desc="說明資料或結構變更如何在服務不中斷前提下受控推進">Migration</a></td>
          <td>推進資料結構與資料狀態</td>
          <td>是否可漸進、可重試、可停止</td>
      </tr>
      <tr>
          <td><a href="/blog/ci/knowledge-cards/rollout-strategy/" data-link-title="Rollout Strategy" data-link-desc="說明新版本如何以可控節奏推進到全部流量">Rollout strategy</a></td>
          <td>分批接流量</td>
          <td>readiness、error rate、latency 是否可信</td>
      </tr>
      <tr>
          <td><a href="/blog/ci/knowledge-cards/rollback-strategy/" data-link-title="Rollback Strategy" data-link-desc="說明發布異常時如何快速回到已知可用狀態">Rollback strategy</a></td>
          <td>縮小錯誤版本影響</td>
          <td>程式、資料、queue 與 config 是否可回復</td>
      </tr>
  </tbody>
</table>
<p>Build 階段負責產生可部署服務。服務版本要能從 runtime 反查 commit、workflow run、image digest 與 migration 版本，讓事故時能快速定位哪一次變更進入環境。</p>
<p>Contract test 階段負責驗證跨邊界相容。API response、database schema、queue message 與 config key 都是契約；只測 service 內部函式，通常抓不到新舊版本並存時的破壞性變更。</p>
<p><a href="/blog/ci/knowledge-cards/migration/" data-link-title="Migration" data-link-desc="說明資料或結構變更如何在服務不中斷前提下受控推進">Migration</a> 階段負責推進資料狀態。安全 migration 通常採 expand-and-contract：先加相容欄位或表、部署可讀新舊格式的程式、回填資料，最後移除舊格式。直接在同一次 release 刪欄位與切程式，會讓 rollback 失去空間。</p>
<p><a href="/blog/ci/knowledge-cards/rollout-strategy/" data-link-title="Rollout Strategy" data-link-desc="說明新版本如何以可控節奏推進到全部流量">Rollout strategy</a> 階段負責控制新版本接到的流量。Rolling、canary 與 blue-green 都需要可信 readiness；readiness 應檢查服務能否接流量，而不只是 process alive。</p>
<p><a href="/blog/ci/knowledge-cards/rollback-strategy/" data-link-title="Rollback Strategy" data-link-desc="說明發布異常時如何快速回到已知可用狀態">Rollback strategy</a> 階段負責定義失敗時的處理路由。後端 rollback 常見做法是 app rollback、config rollback、traffic rollback 或 forward fix；資料已被新程式寫入時，forward fix 往往比直接資料回滾安全。</p>
<h2 id="migration-順序">Migration 順序</h2>
<p>Migration 順序的責任是保留相容窗口。資料結構變更應讓至少兩個相鄰程式版本能共存，避免部署中途任何一端先完成都造成服務不可用。</p>
<ol>
<li>新增向前相容 schema，例如新增 nullable column 或新表。</li>
<li>部署可同時讀舊欄位與新欄位的程式。</li>
<li>執行 backfill 或 background migration。</li>
<li>切換讀取來源或寫入路徑。</li>
<li>觀察穩定後移除舊欄位、舊 index 或舊 message 格式。</li>
</ol>
<p>這個順序的價值是可停止。若第 3 步回填異常，可以暫停 backfill，不必立即回退 app；若第 4 步切換後錯誤率升高，可以先切回舊讀取路徑，再評估資料修補。</p>
<h2 id="rollout-判讀">Rollout 判讀</h2>
<p>Rollout 判讀要同時看技術指標與業務副作用。服務能啟動不代表能安全接流量；API error、queue lag、database lock、第三方 API 錯誤與核心業務漏斗都可能是發布問題。</p>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>判讀</th>
          <th>下一步</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>readiness 未通過</td>
          <td>新版本尚未能接流量</td>
          <td>暫停 rollout，查 config / 依賴</td>
      </tr>
      <tr>
          <td>error rate 上升</td>
          <td>新版本或相依服務契約出錯</td>
          <td>降低流量或切回舊版本</td>
      </tr>
      <tr>
          <td>migration lock 久</td>
          <td>schema 變更影響正常查詢</td>
          <td>停止 migration，改成分段方案</td>
      </tr>
      <tr>
          <td>consumer lag 上升</td>
          <td>worker 消費速度或 message 壞</td>
          <td>暫停新版 worker 或降速</td>
      </tr>
      <tr>
          <td>rollback 後仍錯</td>
          <td>資料或外部 side effect 已變動</td>
          <td>進入 forward fix / repair 流程</td>
      </tr>
  </tbody>
</table>
<p>這些訊號要先接到發布流程。若指標只存在 dashboard 裡、workflow 不知道如何判讀，團隊仍會在事故當下靠人工臨場決策。</p>
<h2 id="常見反模式">常見反模式</h2>
<p>反模式的共同問題是把後端部署當成單一 deploy 動作。後端發布的本質是多個相依狀態的協調流程。</p>
<table>
  <thead>
      <tr>
          <th>反模式</th>
          <th>風險</th>
          <th>替代做法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>app 與 destructive migration 同步</td>
          <td>rollback 後舊程式失去讀取契約</td>
          <td>expand-and-contract</td>
      </tr>
      <tr>
          <td>readiness 只檢查 process alive</td>
          <td>流量進入尚未準備好的服務</td>
          <td>檢查依賴、config 與初始化狀態</td>
      </tr>
      <tr>
          <td>rollback 只切 image tag</td>
          <td>資料與 queue side effect 留下</td>
          <td>定義 app / data / config 路由</td>
      </tr>
      <tr>
          <td>migration 沒有 dry run</td>
          <td>發布時才發現權限或鎖表問題</td>
          <td>staging 或 shadow 環境先跑驗證</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>後端部署總覽：回 <a href="../">後端部署 CI/CD</a>。</li>
<li>Migration 術語：讀 <a href="/blog/ci/knowledge-cards/migration/" data-link-title="Migration" data-link-desc="說明資料或結構變更如何在服務不中斷前提下受控推進">Migration</a>。</li>
<li>Gate 原理：讀 <a href="../../ci-gate-workflow-boundary/">CI gate 與 workflow 邊界</a>。</li>
</ul>
]]></content:encoded></item><item><title>Rollback Strategy</title><link>https://tarrragon.github.io/blog/ci/knowledge-cards/rollback-strategy/</link><pubDate>Wed, 06 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/ci/knowledge-cards/rollback-strategy/</guid><description>&lt;p>Rollback Strategy 的核心概念是「在異常發布後縮小影響範圍並回到可用狀態」。它屬於部署設計的一部分，需要在事故前完成。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Rollback Strategy 位在 deploy、rollout 與 incident handling 之間，通常要和資料遷移、feature flag 與流量切換一起設計。&lt;/p>
&lt;h2 id="可觀察訊號">可觀察訊號&lt;/h2>
&lt;ul>
&lt;li>發布後錯誤率或延遲快速升高。&lt;/li>
&lt;li>新舊版本存在相容性風險。&lt;/li>
&lt;li>團隊需要在分鐘級別恢復核心功能。&lt;/li>
&lt;/ul>
&lt;h2 id="接近真實服務的例子">接近真實服務的例子&lt;/h2>
&lt;p>靜態站可回退前一版 artifact。後端服務可回退 image tag 並暫停新 migration。App 場域可先用 remote config 關閉新功能，再走 hotfix 發版。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Rollback Strategy 要定義觸發條件、責任人、回退動作與回復後驗證，並定期演練。&lt;/p></description><content:encoded><![CDATA[<p>Rollback Strategy 的核心概念是「在異常發布後縮小影響範圍並回到可用狀態」。它屬於部署設計的一部分，需要在事故前完成。</p>
<h2 id="概念位置">概念位置</h2>
<p>Rollback Strategy 位在 deploy、rollout 與 incident handling 之間，通常要和資料遷移、feature flag 與流量切換一起設計。</p>
<h2 id="可觀察訊號">可觀察訊號</h2>
<ul>
<li>發布後錯誤率或延遲快速升高。</li>
<li>新舊版本存在相容性風險。</li>
<li>團隊需要在分鐘級別恢復核心功能。</li>
</ul>
<h2 id="接近真實服務的例子">接近真實服務的例子</h2>
<p>靜態站可回退前一版 artifact。後端服務可回退 image tag 並暫停新 migration。App 場域可先用 remote config 關閉新功能，再走 hotfix 發版。</p>
<h2 id="設計責任">設計責任</h2>
<p>Rollback Strategy 要定義觸發條件、責任人、回退動作與回復後驗證，並定期演練。</p>
]]></content:encoded></item></channel></rss>