大部分分佈式應用須要一個主控、協調器或者控制器來管理物理分佈的子進程。目前,大多數都要開發私有的協調程序,缺少一個通用機制,協調程序的反覆編寫浪費,且難以造成通用、伸縮性好的協調器,zookeeper提供通用的分佈式鎖服務,用以協調分佈式應用。因此說zookeeper是分佈式應用的協做服務。php
zookeeper做爲註冊中心,服務器和客戶端都要訪問,若是有大量的併發,確定會有等待。因此能夠經過zookeeper集羣解決。spring
下面是zookeeper集羣部署結構圖:服務器
Zookeeper的啓動過程當中leader選舉是很是重要並且最複雜的一個環節。那麼什麼是leader選舉呢?zookeeper爲何須要leader選舉呢?zookeeper的leader選舉的過程又是什麼樣子的?併發
首先咱們來看看什麼是leader選舉。其實這個很好理解,leader選舉就像總統選舉同樣,每人一票,得到多數票的人就當選爲總統了。在zookeeper集羣中也是同樣,每一個節點都會投票,若是某個節點得到超過半數以上的節點的投票,則該節點就是leader節點了。分佈式
以一個簡單的例子來講明整個選舉的過程.
假設有五臺服務器組成的zookeeper集羣,它們的id從1-5,同時它們都是最新啓動的,也就是沒有歷史數據,在存放數據量這一點上,都是同樣的.假設這些服務器依序啓動,來看看會發生什麼 。
1) 服務器1啓動,此時只有它一臺服務器啓動了,它發出去的報沒有任何響應,因此它的選舉狀態一直是LOOKING狀態
2) 服務器2啓動,它與最開始啓動的服務器1進行通訊,互相交換本身的選舉結果,因爲二者都沒有歷史數據,因此id值較大的服務器2勝出,可是因爲沒有達到超過半數以上的服務器都贊成選舉它(這個例子中的半數以上是3),因此服務器1,2仍是繼續保持LOOKING狀態.
3) 服務器3啓動,根據前面的理論分析,服務器3成爲服務器1,2,3中的老大,而與上面不一樣的是,此時有三臺服務器選舉了它,因此它成爲了此次選舉的leader.
4) 服務器4啓動,根據前面的分析,理論上服務器4應該是服務器1,2,3,4中最大的,可是因爲前面已經有半數以上的服務器選舉了服務器3,因此它只能接收當小弟的命了.
5) 服務器5啓動,同4同樣,當小弟測試
真實的集羣是須要部署在不一樣的服務器上的,可是在咱們測試時同時啓動十幾個虛擬機內存會吃不消,因此咱們一般會搭建僞集羣,也就是把全部的服務都搭建在一臺虛擬機上,用端口進行區分。spa
咱們這裏要求搭建一個三個節點的Zookeeper集羣(僞集羣)。server
從新部署一臺虛擬機做爲咱們搭建集羣的測試服務器。進程
(1)安裝JDK 【此步驟省略】。內存
(2)Zookeeper壓縮包上傳到服務器
(3)將Zookeeper解壓 ,建立data目錄 ,將 conf下zoo_sample.cfg 文件更名爲 zoo.cfg
(4)創建/usr/local/zookeeper-cluster目錄,將解壓後的Zookeeper複製到如下三個目錄
/usr/local/zookeeper-cluster/zookeeper-1
/usr/local/zookeeper-cluster/zookeeper-2
/usr/local/zookeeper-cluster/zookeeper-3
[root@localhost ~]# mkdir /usr/local/zookeeper-cluster [root@localhost ~]# cp -r zookeeper-3.4.6 /usr/local/zookeeper-cluster/zookeeper-1 [root@localhost ~]# cp -r zookeeper-3.4.6 /usr/local/zookeeper-cluster/zookeeper-2 [root@localhost ~]# cp -r zookeeper-3.4.6 /usr/local/zookeeper-cluster/zookeeper-3 |
(5) 配置每個Zookeeper 的dataDir(zoo.cfg) clientPort 分別爲2181 2182 2183
修改/usr/local/zookeeper-cluster/zookeeper-1/conf/zoo.cfg
clientPort=2181 dataDir=/usr/local/zookeeper-cluster/zookeeper-1/data |
修改/usr/local/zookeeper-cluster/zookeeper-2/conf/zoo.cfg
clientPort=2182 dataDir=/usr/local/zookeeper-cluster/zookeeper-2/data |
修改/usr/local/zookeeper-cluster/zookeeper-3/conf/zoo.cfg
clientPort=2183 dataDir=/usr/local/zookeeper-cluster/zookeeper-3/data |
(1)在每一個zookeeper的 data 目錄下建立一個 myid 文件,內容分別是1、2、3 。這個文件就是記錄每一個服務器的ID
-------知識點小貼士------ 若是你要建立的文本文件內容比較簡單,咱們能夠經過echo 命令快速建立文件 格式爲: echo 內容 > 文件名 例如咱們爲第一個zookeeper指定ID爲1,則輸入命令
|
(2)在每個zookeeper 的 zoo.cfg配置客戶端訪問端口(clientPort)和集羣服務器IP列表。
集羣服務器IP列表以下
server.1=192.168.25.140:2881:3881 server.2=192.168.25.140:2882:3882 server.3=192.168.25.140:2883:3883 |
解釋:server.服務器ID=服務器IP地址:服務器之間通訊端口:服務器之間投票選舉端口
-----知識點小貼士----- 咱們可使用EditPlus遠程修改服務器的文本文件的內容,更加便捷 (1)在菜單選擇FTP Settings
(2)點擊ADD按鈕
(3)輸入服務器信息
(4)點擊高級選項按鈕
(5)選擇SFTP 端口22
(6)OK 。完成配置
鏈接:
哈哈,無敵啦~~~~ 你可能要問,老師,你爲啥不早告訴我有這一招 ! |
啓動集羣就是分別啓動每一個實例。
啓動後咱們查詢一下每一個實例的運行狀態
先查詢第一個服務
Mode爲follower表示是跟隨者(從)
再查詢第二個服務Mod 爲leader表示是領導者(主)
查詢第三個爲跟隨者(從)
(1)首先咱們先測試若是是從服務器掛掉,會怎麼樣
把3號服務器停掉,觀察1號和2號,發現狀態並無變化
由此得出結論,3個節點的集羣,從服務器掛掉,集羣正常
(2)咱們再把1號服務器(從服務器)也停掉,查看2號(主服務器)的狀態,發現已經中止運行了。
由此得出結論,3個節點的集羣,2個從服務器都掛掉,主服務器也沒法運行。由於可運行的機器沒有超過集羣總數量的半數。
(3)咱們再次把1號服務器啓動起來,發現2號服務器又開始正常工做了。並且依然是領導者。
(4)咱們把3號服務器也啓動起來,把2號服務器停掉(汗~~幹嗎?領導掛了?)停掉後觀察1號和3號的狀態。
發現新的leader產生了~
由此咱們得出結論,當集羣中的主服務器掛了,集羣中的其餘服務器會自動進行選舉狀態,而後產生新得leader
(5)咱們再次測試,當咱們把2號服務器從新啓動起來(汗~~這是詐屍啊!)啓動後,會發生什麼?2號服務器會再次成爲新的領導嗎?咱們看結果
咱們會發現,2號服務器啓動後依然是跟隨者(從服務器),3號服務器依然是領導者(主服務器),沒有撼動3號服務器的領導地位。哎~退休了就是退休了,說了不算了,哈哈。
由此咱們得出結論,當領導者產生後,再次有新服務器加入集羣,不會影響到現任領導者。
修改服務提供者和服務調用者的spring 配置文件
<!-- 指定註冊中心地址 --> <dubbo:registry protocol="zookeeper" address="192.168.25.140:2181,192.168.25.140:2182,192.168.25.140:2183"> </dubbo:registry> |