1. 概述
1.1 分布式應用
分布式應用(distributed application)指的是應用程式分布在不同計算機上,通過網路來共同完成一項任務的作業方式,以javaEE實作一個電商網站為例:
- 單體應用:所有功能都寫在一個專案了;打包成一個可運行的war包;部署這個war包就可以完成整個網站所有功能,
- 分布式應用:不同的功能寫在不同的專案里;打包成多個可運行的war包;由多個運行的服務共同完成整個網站的完整功能,

? 如上圖,這個電商網站包含了用戶管理、商品管理、訂單管理、支付管理4個模塊(也稱為服務),在分布式應用里面,許多功能都是多個服務共同協作完成的,服務間如何高效有序地協作就成為分布式開發中一個重要的問題,
- 類比:
- 單一應用 --> 所有作業都一個人完成
- 分布式應用 --> 很多作業由多個人共同協作完成
1.2 什么是zookeeper
ZooKeeper是一個分布式的,開放原始碼的分布式應用程式協調服務,是Google的Chubby一個開源的實作,是Hadoop和Hbase的重要組件,它主要是用來解決分布式應用中經常遇到的一些問題,
ZooKeeper從字面意思理解,【Zoo - 動物園,Keeper - 管理員】動物園中有很多種動物,這里的動物就可以比作分布式環境下多種多樣的服務,而ZooKeeper做的就是管理這些服務,
1.3 架構
zookeeper的架構如下圖所示:

ZooKeeper集群由一組Server節點組成,這一組Server節點中存在一個角色為Leader的節點,其他節點都為Follower,管與zookeeper架構有如下幾個要點:
-
讀操作,直接讀取其中一個Follwer并直接回傳,
-
寫操作,zookeeper集群會做如下兩步處理:
- 這些請求會被發送到Leader節點上
- Leader節點上資料變更會同步到集群中其他的Follower節點
-
Leader節點在接收到資料變更請求后,首先將變更寫入本地磁盤,以作恢復之用,當所有的寫請求持久化到磁盤以后,才會將變更應用到記憶體中,
-
注意:持久化到硬碟的資料,只是用于服務重啟時資料恢復,
-
當Leader節點出現故障無法正常相應時,集群會自動重新選舉一Follwer節點作為Leader,
1.4 存盤結構和分層命名空間
ZooKeeper有一個分層的命名空間,結構類似檔案系統的目錄結構,非常簡單而直觀,其中,ZNode是最重要的概念,

在ZooKeeper中每個命名空間(Namespace)被稱為ZNode,你可以這樣理解,每個ZNode包含一個路徑和與之相關的屬性和資料,以及繼承自該節點的孩子串列,與傳統檔案系統不同的是,ZooKeeper中的資料保存在記憶體中,實作了分布式同步服務的高吞吐和低延遲,
ZNode分類及特性:
1.4.1永久節點和臨時節點(Ephemeral)
- 永久節點(默認):一但創建成功就不會自動消失,
- 臨時節點:創建成功后,一但客戶端與服務器失去連接,就會自動洗掉
1.4.2有序節點**(**Sequence Nodes)
? zookeeper支持創建有序節點,也就是在zNode名稱后面自動拼接一個遞增的數字,
1.4.3節點的更新與監聽(watches)
? zookeeper客戶端可以監聽zNode資料的變化,一但zNode的資料發生變化,則自動通知到正在監聽的客戶端,
02.zookeeper使用場景
2.1 分布式鎖
2.1.1 為什么使用分布式鎖
一個方法在高并發情況下的同一時間只能被同一個執行緒執行,在傳統單體應用單機部署的情況下,可以使用Java并發處理相關的API(如ReentrantLcok或synchronized)進行互斥控制,但是,隨著業務發展的需要,原單體單機部署的系統被演化成分布式系統后,由于分布式系統多執行緒、多行程并且分布在不同機器上,這將使原單機部署情況下的并發控制鎖策略失效,為了解決這個問題就需要一種跨JVM的互斥機制來控制共享資源的訪問,這就是分布式鎖要解決的問題.

2.1.2 基于zookeeper的分布式鎖原理
一個分布式鎖對應ZooKeeper的一個節點,每個需要獲取這個分布式鎖的客戶端執行緒在這個節點下創建一個臨時有序節點,此時有兩種情況:
-
創建的臨時順序節點是檔案夾下的第一個節點,則認為是獲取分布式鎖成功,
-
創建的臨時順序節點不是檔案夾下的第一個節點,則認為當前鎖已經被另一個客戶端執行緒獲取,此時需要進入阻塞狀態,等待節點順序中的前一個節點釋放鎖的時候喚醒當前執行緒,

2.2 配置中心
對于專案中用到的配置資訊(例如資料庫地址、用戶名、密碼……)一般有兩種處理方式:
- 直接放到專案組態檔里,會有如下缺點:
- 容易導致敏感資訊泄露(例如線上的用戶名、密碼……)
- 一但配置資訊變化(例如資料庫密碼變化),需要重新打包上線
- 配置中心,將配置資訊維護到配置中心里
- 流程:
- 服務啟動的時候直接來配置中心獲取配置資訊
- 配置資訊變化時直接修改配置中心里的資料,配置中心將新的配置資訊推送給服務(tomcat),無需重啟服務,

- 流程:
2.3 注冊中心
在生產環境中需要在一個業務服務器(例如tomcat)中呼叫另一個業務服務器的介面(例如HTTP介面),那么就需要知道被呼叫方的IP地址和埠我們有三種方案:
-
IP&埠寫死在專案里(不推薦)
-
優點:簡單直接,
-
缺點:如果被呼叫方IP地址和埠發生變化或者部署節點的數量發生變化,就需要修改呼叫方代碼重新上線

-
類比
- app1–>同學A
- app2–>同學B
- IP+埠–>電話號碼
- 呼叫–>同學A撥打同學B的電話
-
-
反向代理服務器,例如nginx
-
優點:呼叫方只需要配置Nginx地址,無需關心被呼叫用者真實的IP地址和埠,

-
類比:
- nginx --> 班長
- 反向代理服務器轉發–>同學A讓班長捎話給同學B
-
-
注冊中心,例如zookeeper
- 優點:呼叫方無需配置被呼叫方的IP地址,當被呼叫方的資訊變化可以自動更新,
- 流程:
- 注冊,app2啟動時將IP、埠等資訊發送到注冊中心
- app1啟動時去注冊中心拉取app2的資訊(IP、埠等資訊)
- 發起呼叫(例如HTTP請求)
- 分布式框架dubbo推薦使用zookeeepr作為注冊中心,

- 類比:
- 注冊中心 --> 班主任
- 注冊 -->所有同學在入學的時候都將手機號告訴班主任
- 拉取目標服務器資訊再發起呼叫–>同學A找班主任要同學B的電話號碼再撥打電話
2.4 其他
除了上面列舉的三種常見使用場景,zookeeper還可以實作名稱服務器、佇列、barrier(柵欄)、原子型別、選舉等功能,在此不再贅述,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/278836.html
標籤:其他
上一篇:JavaWeb購物系統(超詳細!!!包括介紹、演示、全部開源代碼)
下一篇:Double搭建Mysql集群
