Circuit Breaker
在軟體系統中,「斷路器」是一種保護機制,用來避免系統在發生連續錯誤時被拖垮。它的核心目標是當外部服務或資源連續失敗時,暫時中斷請求,讓系統有時間恢復
家裡的電路,如果有電器短路,會造成電流暴增。斷路器就會「跳電」,暫時切斷電力,避免整個家被燒掉。在軟體中也是一樣,如果外部 API 一直回錯誤(例如 Timeout 或 500 Error),我們不應該一再重試,否則會耗盡 Thread、CPU、甚至把整個應用拖慢。所以斷路器會「跳閘」,暫停對那個外部服務的呼叫一段時間
狀態
意義
行為
Closed(關閉)
一切正常
請求會照常發送。如果有失敗,會記錄下來。
Open(開啟)
外部服務被認定「壞掉」
直接阻擋呼叫,立即回錯誤,不再嘗試。
Half-Open(半開啟)
試探階段
過一段時間後,允許少量請求試試看服務是否恢復。成功就恢復 Closed。
Polly12345678910111213141516171819202122232425262728293031323334using Polly;using Polly.CircuitBreaker;using ...
Circuit Breaker
熔斷並不是「修補不穩定」的設計,而是預防連鎖崩潰的一種保險。就像電路裡的保險絲,當某個服務過載或回應過慢時,熔斷器會暫時中斷請求,防止所有流量一起壓垮整個系統。這其實是一種「系統彈性」設計哲學
熔斷後要多久恢復?如果恢復太慢會影響體驗,太快又可能反覆熔斷?這是一種「穩定 vs 敏捷」的矛盾。恢復時間太短,會導致「抖動效應」——服務剛好起來又被壓垮;太長則使用者體驗差。理想的策略是設一個半開狀態(Half-Open):部分流量試探性放行
假設支付服務在 10 秒內失敗了 5 次後被熔斷。30 秒後熔斷器自動進入「半開」,只允許 10% 的請求通過測試;若成功率高於 80%,則恢復正常運行
熔斷與重試(Retry)會不會互相衝突「重試」希望挽救暫時錯誤,「熔斷」希望阻止持續錯誤,若兩者交錯使用不當,會導致雪崩效應(大量重試瞬間壓垮服務)
在支付請求中若每次失敗都重試3次,而熔斷器設定在10次錯誤觸發,實際上只要4個使用者同時錯誤,就可能觸發熔斷。
結帳系統
加入購物車限流器單位時間內,限制可以加入購物車的數量
兩層票匣(Token Bucket)+ 秒級時間窗可以把每個方塊視為「某個時間窗內允許的票(tokens)」:
By SkuId 的票匣:每個 SKU 每秒最多 100 次加入(圖的 100 只是示意)。同一秒內,第 101 個想加的,因為他拿不到票,就被「請稍後再試」。
By ShopId 的票匣:同一商店合計每秒最多 1000 次加入。即使很多 SKU 分散加,也不能超過商店總上限,避免把該商店的後端資源用光。
時間軸(1s、2s、3s、…、ns):代表「固定秒級視窗」或「每秒補票」。每過一秒,票匣重新裝滿(或按速率補票),下一秒再算。
🌳 「要通過,得同時有 Sku 的票 + Shop 的票」。任一票用完就被擋
〈每家店獨立設定〉—配額可調、資源隔離Shop A、Shop B 各自一套配額
A 店的白/藍/黃(SKU)可以是每秒 100。
B 店的大小中 SKU 也各有每秒 100。
營運面可調。大店、熱門品給高一點;新店、長尾品給保守值。
把限流放在「加入購物車」前段,Fail-fast ...
Rate Limiter
限流設定太嚴活動秒殺時,限流設定太嚴導致一堆使用者被攔在外,但系統明明負載還有餘裕
限流規則以「API層」為單位,還是以「使用者動作意圖」為單位深層解析
多數限流設計只看 API 請求頻率(例如每秒可呼叫幾次),但購物行為其實是「任務導向」的。同樣的 API,在不同情境下(加購、改數量、結帳前檢查)代表不同優先度。若只看技術層頻率,會錯殺真實用戶。這是「技術限流」與「業務語意限流」的衝突。
具體例子
A 用戶在秒殺活動中加購一件商品,B 用戶在修改購物車,兩者都觸發相同限流規則,但其實 A 的行為應該更被優先處理。
限流的錯誤回饋,是「資訊透明」還是「行為引導」目前許多限流回饋只是彈窗:「因搶購熱烈,請稍後再試」。但這會導致用戶亂重試、加重流量。若能在訊息中加入「重試建議」或「倒數回應」,就能把限流轉化為節流(引導行為)。這是「被動防守」與「主動引導」的矛盾。
具體例子
使用者被告知「請稍後重試」不如告訴他「系統將於3秒後自動重試」或「已為你保留名額30秒」。
限流策略是否考慮跨服務依賴(例如庫存、票匣、購物車)之間的同步深層解析
目前流程是線性檢查(庫存 → 全店票匣 → SKU票 ...
CPU - DB
NodeAlwaysOn Availability GroupAWS RDS 的 Multi-AZ + Read Replica 架構RW / ROCPU 效能消耗來源CPU HIGH 原因分析檢查 Query Plain 方式搶券優化 - 關於 tempTable 濫用後台付款查詢 - 關於索引summary一個 Node = 一個獨立運作的資料庫執行單位,實務上 通常對應一台 Instance(VM / EC2 / RDS instance)
一個「節點」就是一台資料庫伺服器(Server),在分散式或高可用架構中會有多台,也就是多節點佈署
1234567891011121314 +-------------------------+ | App / API Server | +-----------+-------------+ | v┌─────────────────────────────┐│ DB Cluster │├────────── ...
DynamoDB - 讓流量走散,是最溫柔的防禦
DynamoDB 是怎麼把「高併發壓力」攤平的DynamoDB 是怎麼把「高併發壓力」攤平的流量真的變很大時,DynamoDB 會做什麼購物車回饋活動管庫存資料存取模式明確、可預期的系統「不適合」用 DynamoDB
不要硬撐,不要集中,讓壓力自然就是分流,是最溫柔也最有效的防禦
如果把所有時間自我認同都投入單一面向上,一旦單點開始延遲、停滯、壓力襲來,整個人不是失落而是直接瓦解,開始焦慮、開始失去存在感
把自己拆成很多 partition,工作只是其中一塊、關係只是其中一塊,興趣、休息、身體、學習,各自扛一點
某一塊出問題 ≠ 整個人生當機
人生若綁定特定的 hot key ,可能是只從某個人那裡獲得肯定、只用成績證明自己、只靠收入撐安全感、情緒只剩一個出口,那個地方一爆,你會覺得為什麼我明明很努力,卻撐不住?不是你不夠強,而是你把所有流量都導到同一個點
我不需要承受,只要分散DynamoDB 一開始就把資料切碎,讓很多台機器各自扛一小部分,DynamoDB 真正在做的是資料本來就分散在很多 partition,當流量來了會調整 partition 數量與吞吐,這會讓「請求平均打到不 ...
DynamoDB 基礎概念 - 分散的藝術
故事:圖書館的智慧📘 RCU & WCU:圖書館的服務能量☁️ Serverless:你不用管伺服器🚦 Throttling:被限流了怎麼辦🔑 Partition Key:資料的身分證
想像一座巨大的圖書館,每天有成千上萬的人來借還書。
傳統的圖書館只有一個櫃檯,所有人都要排隊等候同一個館員處理。高峰時段,隊伍排得很長,有人只是想借一本輕小說,卻要等前面的人處理完十幾本厚重的專業書籍。
聰明的館長決定改革:
把圖書館分成多個區域(Partition):小說區、科技區、藝術區…每個區都有獨立的櫃檯
每本書都有明確的歸屬(Partition Key):根據書的類別編號,自動知道該去哪個櫃檯
每個櫃檯都能獨立工作(分散式處理):不會因為科技區很忙,就影響到小說區的借書速度
這就是 DynamoDB 的核心思想:不要讓所有人擠在同一個地方,把壓力分散開來,每個人都能快速得到服務。
當某個區域(partition)突然湧入大量讀者,館長不需要叫所有館員都跑去幫忙,只要在那個區域增加一個臨時櫃檯就好。這就是 Serverless 和 Auto Scaling 的概念。
但如果所有人都只想 ...
Middleware
Middleware 的運作原理如何「交換 Middleware 的順序」如何「跳過」特定 Middleware(但不跳過整條)多層 Middleware 之間交換資訊ASP.NET Core 的請求流程是一條「洋蔥模型」
當一個 Request 進來,他進入 ASP.NET Core 的處理管線(Pipeline),依照註冊順序進入 Middleware,第一個 UseXXX 註冊的 Middleware 最先被執行,每個 Middleware 都「包住」後面所有的 Middleware
當你呼叫 UseMiddleware() ,Framework 會產生一個 RequestDelegate 並把「下一個 Middleware」當成 next 傳進來,而在 Middleware 執行自己的邏輯時,可以在這裡做任何事(Log、驗證、改 Header…)、決定要不要呼叫 await next(context),若呼叫表示請求繼續往下一層走,選擇不呼叫,則流程在這一層就被「攔截」
此時 Response 從最內層往外回傳
✅ 方法一:直接調整註冊順序在 Program.cs 或 ...
Dependency Injection - State
.NET DI 中的 Service Lifetime(Transient / Scoped / Singleton)為什麼「無 Request 專屬狀態」的服務通常用 Singleton?Singleton - EntityHelperTransient - RequestMessageLoggingDelegatingHandlerPromotionEngineService 為何用 ScopedScoped 存在的目的Interface 跟 DI 關聯Registering & Resolving靜態物件的問題在 .NET DI 裡,我們註冊服務時通常會用三種生命週期
生命週期
建立時機
何時被回收
常見用途
Transient
每次注入時都會 new 一個新的實例
呼叫結束後可回收
短期任務、Request 專屬狀態的物件
Scoped
每個 Request (或每個範圍) 共用同一個實例
Request 結束時回收
Web Request、需在同一 Request 內共享狀態
Singleton
第一次解析時建立一次,全程共用
應用程式結束時回收
共用服務 ...
Closure
Closure方法呼叫(傳參數)編譯器背後的轉換點擊次數 Counter事件計數器累積計算器狀態機模擬提供 RetryClosure,就像人生的記憶機制。它讓一段邏輯,不只記得「要做什麼」,也記得「曾經與誰有關」。在我們離開某個場景之後,它仍攜帶著當時的狀態、情緒與環境,就像一個攜帶回憶的函式,延續著那份未完的故事。Closure 使「lambda 可以用外部變數」,但它的本質遠不只是「抓外部變數來用」,而是一種讓函式擁有「記憶狀態」的機制
立刻執行 → 當下的值是什麼就拿什麼
123456789101112131415void Show(int n) { Console.WriteLine(n);}for (int i = 0; i < 5; i++){ Show(i); // 當下的 i 是多少就傳進去}//0//1//2//3//4
而 Lambda 並不是幫你把當下的值存起來,而是把「之後要用哪一個變數」記住,所以多個 Lambda 如果指向同一個變數,就一定會互相干擾,Lambda 的目的是「延後執行一段邏輯」,而 ...








