購物車系統的高並發改造(二):Redisson 分散式鎖、讀寫分離路由與 Docker HA 水平擴展
前言 第一篇解決了系統的吞吐量問題:Virtual Threads 讓執行緒不再阻塞在 I/O 上,HikariCP 調校讓資料庫連線不再是瓶頸,Redis 快取讓熱點讀取從記憶體直接回傳。 但吞吐量提升後,反而暴露出一個更深層的問題: 並發請求同時寫入同一份資料,怎麼保證正確性? 想像雙十一活動開始的那一秒,同一個用戶的兩個 Tab 同時按下「加入購物車」;或者同一個人網路不穩,重試了兩次「立即結帳」——這兩種場景都會導致重複訂單或資料不一致。 這篇介紹 PR #228 帶來的三個進階改造: Redisson 分散式鎖:防止同一用戶的並發寫入互相干擾 讀寫分離路由:把讀請求分流到 Replica,Primary 只處理寫入 Docker HA 水平擴展:Nginx + 多個 App 實例 + MySQL 主從複製 方案四:Redisson 分散式鎖 為什麼需要分散式鎖? 第一篇的 CartService.addToCart() 在高並發下有一個隱患: 1// Part 1 的版本(沒有鎖) 2public void addToCart(AddToCartDto addToCartDto, Product product, User user) { 3 Cart cart = new Cart(product, addToCartDto.getQuantity(), user); 4 cartRepository.save(cart); // ← 多個執行緒可能同時執行這一行 5} 當同一個用戶同時發出兩個「加入購物車」請求時: Thread A: new Cart(productX, qty=1, user) → save → 購物車有 1 個 productX Thread B: new Cart(productX, qty=1, user) → save → 購物車有 2 個 productX(重複!) cartRepository.