<?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>Exponential-Backoff on Tarragon</title><link>https://tarrragon.github.io/blog/tags/exponential-backoff/</link><description>Recent content in Exponential-Backoff on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Fri, 19 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/exponential-backoff/index.xml" rel="self" type="application/rss+xml"/><item><title>Retry 機制 UX</title><link>https://tarrragon.github.io/blog/ux-design/04-error-recovery/retry-mechanism-ux/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/ux-design/04-error-recovery/retry-mechanism-ux/</guid><description>&lt;p>重試是錯誤恢復的第一手段。重試策略的選擇取決於兩個因素：失敗是否可能自行恢復（暫時性網路中斷 vs 伺服器不存在），以及使用者是否願意等待（前景操作 vs 背景同步）。&lt;/p>
&lt;h2 id="自動重試-vs-手動重試">自動重試 vs 手動重試&lt;/h2>
&lt;h3 id="自動重試">自動重試&lt;/h3>
&lt;p>系統在失敗後自動重新嘗試，使用者不需要手動操作。適合背景操作（資料同步、事件上報、心跳檢查）和暫時性失敗（網路閃斷、server 短暫過載）。&lt;/p>
&lt;p>自動重試的 UX 要求：使用者需要知道系統正在重試。「連線中斷，正在重新連線（第 2 次嘗試）」比靜默重試更透明。如果使用者不知道系統在重試，靜默的等待會被解讀為「系統卡住了」。&lt;/p>
&lt;p>自動重試必須有上限。無限重試在不可恢復的失敗場景中（伺服器已關閉、認證已過期）浪費資源和電量，且使用者無法察覺問題。&lt;/p>
&lt;h3 id="手動重試">手動重試&lt;/h3>
&lt;p>使用者點擊「重試」按鈕觸發重新嘗試。適合前景操作（使用者主動發起的連線、提交、搜尋）和需要使用者確認意圖的場景。&lt;/p>
&lt;p>手動重試的 UX 要求：重試按鈕在 error 畫面上明顯可見，旁邊有退出路徑（返回按鈕）。使用者可以選擇重試或放棄。&lt;/p>
&lt;h3 id="混合策略">混合策略&lt;/h3>
&lt;p>先自動重試 N 次，失敗後切換到手動重試。這是連線類操作的常見模式 — WebSocket 斷線後自動重連 3 次，3 次都失敗後顯示「連線失敗」+ 手動重連按鈕。&lt;/p>
&lt;h2 id="重試間隔策略">重試間隔策略&lt;/h2>
&lt;h3 id="立即重試">立即重試&lt;/h3>
&lt;p>失敗後立即重新嘗試，中間沒有等待。適合極短暫的瞬態失敗（DNS 解析偶發失敗、TCP 連線被 reset）。&lt;/p>
&lt;p>立即重試的風險是在 server 過載時加劇問題 — 多個 client 同時立即重試產生 thundering herd 效應。&lt;/p>
&lt;h3 id="固定間隔重試">固定間隔重試&lt;/h3>
&lt;p>每次重試間隔固定時間（例如每 5 秒重試一次）。簡單可預測，使用者能估算等待時間。&lt;/p>
&lt;h3 id="指數退避exponential-backoff">指數退避（exponential backoff）&lt;/h3>
&lt;p>每次重試的間隔加倍。第一次 1 秒、第二次 2 秒、第三次 4 秒、第四次 8 秒。加上隨機抖動（jitter）避免多個 client 同步重試。&lt;/p>
&lt;p>指數退避適合 server 端過載或暫時不可用的場景。間隔越來越長給 server 恢復的時間，同時減少 client 的資源消耗。&lt;/p>
&lt;p>指數退避的 UX 挑戰是使用者感知到的等待越來越長。第四次重試等 8 秒時使用者可能已經失去耐心。解法是顯示倒數計時（「12 秒後自動重試」）和手動重試按鈕（使用者可以跳過等待立即重試）。&lt;/p>
&lt;h2 id="重試狀態的-ui-呈現">重試狀態的 UI 呈現&lt;/h2>
&lt;p>使用者需要知道三件事：系統正在重試、已經重試了幾次、下一次重試在什麼時候。&lt;/p>





&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">連線失敗，正在重新連線...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">第 2 次嘗試（共 5 次上限）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">下次重試：8 秒後 [立即重試] [返回首頁]&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>重試達到上限後，UI 從「重試中」切換到「失敗」狀態，顯示手動重試和退出路徑。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;ul>
&lt;li>部分功能不可用的降級設計 → &lt;a href="https://tarrragon.github.io/blog/ux-design/04-error-recovery/degraded-mode-design/" data-link-title="Degraded mode 設計" data-link-desc="部分功能不可用時怎麼告知使用者 — 靜默隱藏 vs 明確標示 vs 替代方案的設計取捨">Degraded mode 設計&lt;/a>&lt;/li>
&lt;li>重試循環的逃生口 → &lt;a href="https://tarrragon.github.io/blog/ux-design/04-error-recovery/error-loop-escape/" data-link-title="error → retry → error 循環的逃生口設計" data-link-desc="當重試持續失敗時，使用者需要第二條路 — 逃生口設計讓使用者能離開失敗循環而非被困住">error → retry → error 循環的逃生口&lt;/a>&lt;/li>
&lt;li>Gate 失敗的 fallback → &lt;a href="https://tarrragon.github.io/blog/ux-design/02-gate-fallback/" data-link-title="模組二：Gate 與 Fallback 設計" data-link-desc="Biometric / Network / Auth / Permission — 每個 gate 成功時做什麼、失敗時做什麼、使用者不知道發生什麼時做什麼">ux-design 模組二 Gate 與 Fallback&lt;/a>&lt;/li>
&lt;li>Server 端的限速機制（影響 retry 策略設計）→ &lt;a href="https://tarrragon.github.io/blog/devops/03-traffic-management/" data-link-title="模組三：流量管控" data-link-desc="收到的流量超過處理能力時怎麼辦 — 背壓、rate limit、熔斷、bulkhead 四種防護機制">DevOps 流量管控&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>重試是錯誤恢復的第一手段。重試策略的選擇取決於兩個因素：失敗是否可能自行恢復（暫時性網路中斷 vs 伺服器不存在），以及使用者是否願意等待（前景操作 vs 背景同步）。</p>
<h2 id="自動重試-vs-手動重試">自動重試 vs 手動重試</h2>
<h3 id="自動重試">自動重試</h3>
<p>系統在失敗後自動重新嘗試，使用者不需要手動操作。適合背景操作（資料同步、事件上報、心跳檢查）和暫時性失敗（網路閃斷、server 短暫過載）。</p>
<p>自動重試的 UX 要求：使用者需要知道系統正在重試。「連線中斷，正在重新連線（第 2 次嘗試）」比靜默重試更透明。如果使用者不知道系統在重試，靜默的等待會被解讀為「系統卡住了」。</p>
<p>自動重試必須有上限。無限重試在不可恢復的失敗場景中（伺服器已關閉、認證已過期）浪費資源和電量，且使用者無法察覺問題。</p>
<h3 id="手動重試">手動重試</h3>
<p>使用者點擊「重試」按鈕觸發重新嘗試。適合前景操作（使用者主動發起的連線、提交、搜尋）和需要使用者確認意圖的場景。</p>
<p>手動重試的 UX 要求：重試按鈕在 error 畫面上明顯可見，旁邊有退出路徑（返回按鈕）。使用者可以選擇重試或放棄。</p>
<h3 id="混合策略">混合策略</h3>
<p>先自動重試 N 次，失敗後切換到手動重試。這是連線類操作的常見模式 — WebSocket 斷線後自動重連 3 次，3 次都失敗後顯示「連線失敗」+ 手動重連按鈕。</p>
<h2 id="重試間隔策略">重試間隔策略</h2>
<h3 id="立即重試">立即重試</h3>
<p>失敗後立即重新嘗試，中間沒有等待。適合極短暫的瞬態失敗（DNS 解析偶發失敗、TCP 連線被 reset）。</p>
<p>立即重試的風險是在 server 過載時加劇問題 — 多個 client 同時立即重試產生 thundering herd 效應。</p>
<h3 id="固定間隔重試">固定間隔重試</h3>
<p>每次重試間隔固定時間（例如每 5 秒重試一次）。簡單可預測，使用者能估算等待時間。</p>
<h3 id="指數退避exponential-backoff">指數退避（exponential backoff）</h3>
<p>每次重試的間隔加倍。第一次 1 秒、第二次 2 秒、第三次 4 秒、第四次 8 秒。加上隨機抖動（jitter）避免多個 client 同步重試。</p>
<p>指數退避適合 server 端過載或暫時不可用的場景。間隔越來越長給 server 恢復的時間，同時減少 client 的資源消耗。</p>
<p>指數退避的 UX 挑戰是使用者感知到的等待越來越長。第四次重試等 8 秒時使用者可能已經失去耐心。解法是顯示倒數計時（「12 秒後自動重試」）和手動重試按鈕（使用者可以跳過等待立即重試）。</p>
<h2 id="重試狀態的-ui-呈現">重試狀態的 UI 呈現</h2>
<p>使用者需要知道三件事：系統正在重試、已經重試了幾次、下一次重試在什麼時候。</p>





<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">連線失敗，正在重新連線...
</span></span><span class="line"><span class="ln">2</span><span class="cl">第 2 次嘗試（共 5 次上限）
</span></span><span class="line"><span class="ln">3</span><span class="cl">下次重試：8 秒後 [立即重試] [返回首頁]</span></span></code></pre></div><p>重試達到上限後，UI 從「重試中」切換到「失敗」狀態，顯示手動重試和退出路徑。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>部分功能不可用的降級設計 → <a href="/blog/ux-design/04-error-recovery/degraded-mode-design/" data-link-title="Degraded mode 設計" data-link-desc="部分功能不可用時怎麼告知使用者 — 靜默隱藏 vs 明確標示 vs 替代方案的設計取捨">Degraded mode 設計</a></li>
<li>重試循環的逃生口 → <a href="/blog/ux-design/04-error-recovery/error-loop-escape/" data-link-title="error → retry → error 循環的逃生口設計" data-link-desc="當重試持續失敗時，使用者需要第二條路 — 逃生口設計讓使用者能離開失敗循環而非被困住">error → retry → error 循環的逃生口</a></li>
<li>Gate 失敗的 fallback → <a href="/blog/ux-design/02-gate-fallback/" data-link-title="模組二：Gate 與 Fallback 設計" data-link-desc="Biometric / Network / Auth / Permission — 每個 gate 成功時做什麼、失敗時做什麼、使用者不知道發生什麼時做什麼">ux-design 模組二 Gate 與 Fallback</a></li>
<li>Server 端的限速機制（影響 retry 策略設計）→ <a href="/blog/devops/03-traffic-management/" data-link-title="模組三：流量管控" data-link-desc="收到的流量超過處理能力時怎麼辦 — 背壓、rate limit、熔斷、bulkhead 四種防護機制">DevOps 流量管控</a></li>
</ul>
]]></content:encoded></item></channel></rss>