(全文目錄:)

開篇語

哈嘍,各位小夥伴們,你們好呀,我是喵手。運營社區:C站/掘金/騰訊雲/阿里雲/華為雲/51CTO;歡迎大家常來逛逛

  今天我要給大家分享一些自己日常學習到的一些知識點,並以文字的形式跟大家一起交流,互相學習,一個人雖可以走的更快,但一羣人可以走的更遠。

  我是一名後端開發愛好者,工作日常接觸到最多的就是Java語言啦,所以我都儘量抽業餘時間把自己所學到所會的,通過文章的形式進行輸出,希望以這種方式幫助到更多的初學者或者想入門的小夥伴們,同時也能對自己的技術進行沉澱,加以覆盤,查缺補漏。

小夥伴們在批閲的過程中,如果覺得文章不錯,歡迎點贊、收藏、關注哦。三連即是對作者我寫作道路上最好的鼓勵與支持!

一、CAP定理 & BASE理論:魚和熊掌不可兼得

在進入實戰之前,必須得搞明白一個靈魂拷問:“我到底是要強一致性,還是要高可用?”


✳️ CAP 定理是什麼?

CAP 定理,全名是:Consistency(一致性)、Availability(可用性)、Partition tolerance(分區容錯性)

它告訴你:分佈式系統最多隻能同時滿足其中兩個,三者不可兼得。

組合 特點説明
CP 強一致性 + 分區容錯,但可用性低(如:Zookeeper)
AP 高可用 + 分區容錯,但犧牲一致性(如:DNS、Cassandra)
CA 只能存在於理想世界,分區容忍性不可能缺席

👉 舉個栗子: Zookeeper 選擇的是 CP,如果主節點掛了,它會停止對外提供服務來保持一致性; Cassandra 選擇的是 AP,即使有節點掛了也能讀寫,但可能讀到“舊數據”。


✳️ BASE 理論呢?

如果説 CAP 是硬規則,那 BASE 就是權衡後的實用主義哲學

BASE = Basically Available + Soft State + Eventually Consistent 翻譯成人話就是:

“別追求每次都對,能接受最終對就行。”

你點外賣,騎手遲到 2 分鐘還能接受;但你付完錢訂單沒了,系統崩盤——那就不能接受。


二、分佈式事務:本地事務已死,誰來背鍋?

在單體架構裏,你可以用 @Transactional 一把梭,提交失敗就回滾,瀟灑得很。

可分佈式系統裏,數據庫一堆、服務一堆、消息一堆……一個接口跨三個系統,哪裏來的事務一致性?


🚨 典型痛點:

  • 用户下單成功了 → 賬户沒扣錢 → 庫存沒減 → 財務找上門:“你到底賣了沒賣?”

分佈式事務解決方案(常見的三種):

1. 兩階段提交(2PC)

  • 第一階段:各節點“預提交”
  • 第二階段:協調者通知“提交”或“回滾”

🧨 缺點:協調者一掛,系統直接殭屍化。


2. TCC(Try Confirm Cancel)

  • Try:預留資源
  • Confirm:正式提交
  • Cancel:回滾資源

適用於業務可以拆成三個階段的(比如:賬户凍結 → 確認扣款 → 解凍)。

// Try
accountService.tryFreeze(userId, amount);

// Confirm
accountService.confirm(userId);

// Cancel
accountService.cancel(userId);

優點是靈活,缺點是業務入侵嚴重,每個系統都得支持三套邏輯。


3. 消息最終一致性(基於 MQ)

  • 下單 → 發送 MQ 消息 → 異步扣庫存/扣款 → 成功或失敗後回調更新狀態

是 BASE 理論的最佳落地方式,**“先做再對齊”**。


三、分佈式鎖:防止“多人搶麥”的場景神器

  如果你遇到“同一商品被兩個人秒殺成功”、“同一用户支付兩次”這種情況,恭喜你踩了併發坑的第一個雷——缺少分佈式鎖。


🧱 為什麼不能用 synchronized

因為在分佈式系統中,多個服務實例運行在多個 JVM 中,synchronized 只能鎖住本地線程! 根本沒用!


🐵 分佈式鎖方案:

1. Redis 鎖(最常見)

Boolean success = redisTemplate.opsForValue()
        .setIfAbsent("lock:product:1001", "UUID", 10, TimeUnit.SECONDS);

if (Boolean.TRUE.equals(success)) {
    try {
        // 執行業務邏輯
    } finally {
        redisTemplate.delete("lock:product:1001");
    }
}

但注意:

  • 要防止鎖過期業務未完成(可以用 Redisson)
  • 要防止誤刪鎖(加唯一標識)

2. Zookeeper 分佈式鎖(CP風格)

Zookeeper 使用臨時順序節點實現鎖競爭。

優點:

  • 強一致性
  • 有“排隊”機制,不會飢餓

缺點:

  • 性能不如 Redis,適合少量高價值的鎖

四、分庫分表 & 讀寫分離:性能優化,還是一致性災難?

  你的系統一旦數據量上來了,老闆盯着 QPS 和響應時間,DBA 拍着桌子説:“必須分庫分表!” 你以為只是多了幾張表?結果你發現自己進入了分頁排序分頁失效、ID碰撞、事務混亂的地獄循環。


🎯 分庫分表的典型方式:

  • 垂直拆分:按業務拆(用户表放A庫,訂單表放B庫)
  • 水平分表:按數據行拆(訂單_0 表、訂單_1 表)

常見組件:

  • ShardingSphere
  • MyCat
  • 自研中間件(最穩定也最累)

🚦 讀寫分離帶來的挑戰:

  • 主從延遲 → 寫完讀不到
  • 查詢一致性問題 → 業務邏輯出錯
  • 強一致需求要“強制走主庫”
// 讀寫分離偽代碼
if (isWriteRequest) {
    routeTo(masterDB);
} else {
    routeTo(slaveDB);
}

你以為是優化,其實是“新坑入口”,必須引入全鏈路追蹤、慢 SQL 警報等手段兜底。


結語:分佈式系統的美,是建立在代價之上的

  很多人把“分佈式”當成“高級架構”的代名詞,但真相是:

每多一個節點,就多一個出錯點;每多一份數據,就多一份一致性代價。

CAP 定理不是傳説,分佈式事務不是理想,分庫分表也不只是寫個路由規則那麼簡單。

... ...

文末

好啦,以上就是我這期的全部內容,如果有任何疑問,歡迎下方留言哦,咱們下期見。

... ...

學習不分先後,知識不分多少;事無鉅細,當以虛心求教;三人行,必有我師焉!!!

wished for you successed !!!


⭐️若喜歡我,就請關注我叭。

⭐️若對您有用,就請點贊叭。 ⭐️若有疑問,就請評論留言告訴我叭。


版權聲明:本文由作者原創,轉載請註明出處,謝謝支持!