java面試題 --- 分佈式

1. 什麼是分佈式?

  • 將服務部署在多臺機器上,就叫分佈式。分佈式有兩種形式,一種是水平擴展,即將同樣的系統部署在多臺機器上,讓流量分發到這多臺機器上;另一種是垂直拆分,就是把一個系統拆分成若干個子系統,不同的子系統負責不同的服務。

2. 什麼是集羣?

  • 不同的機器部署相同的服務,對外表現爲一個整體。集羣要具有高可用性,一臺機器掛了其他機器還能正常提供服務;也得具備可擴展性,可以動態地增加機器,提高集羣的處理能力;還得具備負載均衡能力。

3. 什麼是 CAP 定理?

  • C 表示一致性,A 表示可用性,P 表示分區容錯性。分佈式系統是通過網絡聯通的,但是由於一些故障可能導致各節點之間聯不通了,數據分佈在不同的節點上,這就叫出現了網絡分區。當某份數據只保存在某一個節點且那個節點又掛掉了的時候,那個整個系統就不可用了,這時就沒有容錯性,這種情況是要避免的,因此只能把相同的數據部署在多個節點上,而這又會帶來一致性的問題。要保證各節點的數據完全一致,那麼寫數據時就得讓所有節點都成功了纔算成功,這又會帶來可用性的問題。所以並不是 CAP 只能 CP 或 AP,只是當網絡發生分區時,分區容錯性是一定要滿足的,不能出現分區了整個服務就不可用了,所以就得在一致性和可用性之間做取捨。

4. 什麼是 base 理論?

  • base 理論是基本可用、軟狀態和最終一致性三個單詞的縮寫,也就是分佈式系統出現故障的時候,允許損失部分的可用性,多個節點的數據同步允許存在一定的延時,即允許軟狀態存在,通過一定時間的同步後,最終能夠達到一致性,這是對一致性和可用性權衡的結果。

5. 對 dubbo 瞭解嗎?

  • dubbo 是阿里開源的 RPC 框架,所謂 RPC,就是遠程調用,即調用別的服務的方法可以像調用本地方法一樣。dubbo 的架構是由 註冊中心 register、監控中心 monitor、服務提供者 provider 和服務消費者 consumer 組成。dubbo 工作流程就是 provider 向 register 註冊自己的服務,consumer 在 register 訂閱自己需要的服務,同時 provider 和 consumer 都會記錄自己的調用次數和時間等,發送到 monitor 中進行統計。dubbo 底層採用 netty 進行通信。

6. 分佈式鎖有哪些實現方案?

分佈式鎖應該要做到在同一時刻同一方法只能被一臺機器的一個線程執行,同事具備可重入性,具備鎖失效機制,具備非阻塞鎖的特性,具備高可用性以及高性能。

  • 用數據庫實現:執行邏輯前先往數據庫插入一條記錄,如果成功,就表示佔鎖成功,執行完邏輯後刪除記錄;如果插入失敗,就以當前線程 ID ,機器 IP 以及方法名爲條件去查詢是否存在記錄,如果存在,則表示獲取鎖成功。
  • 用 Redis 實現:利用 Redis 的 set k v nx ex 命令就可以達到分佈式鎖效果,不過這種方式只適用單機版的 Redis,如果 Redis 是集羣,那就可能存在 master 上設置了 key,還沒來得及同步到 slave 上的時候,master 掛了,slave 成了新的 master,新的 master 上沒有該 key,因此又可以獲取鎖成功。解決辦法是用 red lock,即紅鎖算法,要在超過一半的 Redis 節點上都獲取鎖成功了且獲取鎖的總時間小於鎖過期時間時,纔會認爲獲取鎖成功。還有一點要注意,Redis 釋放鎖的時候應該用 lua 腳本,因爲釋放鎖時首先要根據 key 獲取到值,然後判斷值跟自己的值是否相同,相同再刪除 key,這並不是一個原子操作,因此要用 lua 腳本實現。
  • 用 zookeeper 實現:可以用 zookeeper 的臨時順序節點來實現。先新建一個 lock 持久節點,然後線程申請鎖時,就在 lock 下新建一個臨時順序節點比如 lock1,然後查找 lock 下所有節點,判斷 lock1 是不是第一個,如果是,獲取鎖成功,如果不是,獲取鎖失敗,同時監控自己前面的那個節點,當自己前面那個節點被幹掉時,再去檢查自己是不是第一個。

7. 分佈式 ID 有哪些實現方案?

分佈式 ID 應該全局唯一,趨勢遞增,單調遞增,保證信息安全,不能根據已知 ID 猜出下一個 ID,含時間戳,便於追蹤問題。

  • UUID:本地生成,沒有網絡消耗,但是無序,不能趨勢遞增,入庫性能較差;
  • 數據庫自增:搞個專門的表,用 replace into 語句來插入數據生成 ID,簡單易用,不需要額外的成本,但是併發性不好;
  • 用 Redis 實現:利用 Redis 的 incr 或者 incrby,性能好,但需要維護 Redis 集羣,成本較高;
  • 雪花算法:是一個 64bit 的整數,首位是符號位,固定是 0,第 2 到 42 位是時間戳,全部是 1 的話,換算後大概是 69 年,從 1970 年開始算,可以用到 2039 年;第 43 到 52 位,5 位表示機房號,5 位 表示機器編號,最後 12 位是序列號,用來記錄同一毫秒內生成的不同 ID。性能好,同意機器同一毫秒內最多生成 4095 個 ID,但是可能會出現時鐘回撥問題。所謂時鐘回撥,就是如果服務器的時間快了,通過 ntp 校驗後,回到了以前的時間,這樣就可能生成重複的 ID。可以用百度開源的 UidGenerator、hutool 工具裏的雪花算法來解決這個問題。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章