Dubbo原理簡單分析

小飛鶴發表於2017-04-13

1.Dubbo原理分析

alibaba有好幾個分散式框架,主要有:進行遠端呼叫(類似於RMI的這種遠端呼叫)的(dubbo、hsf),jms訊息服務(napoli、notify),KV資料庫(tair)等。這個框架/工具/產品在實現的時候,都考慮到了容災,擴充套件,負載均衡,於是出現一個配置中心(ConfigServer)的東西來解決這些問題。
基本原理如圖:

 

在我們的系統中,經常會有一些跨系統的呼叫,如在A系統中要呼叫B系統的一個服務,我們可能會使用RMI直接來進行,B系統釋出一個RMI介面服務,然後A系統就來通過RMI呼叫這個介面,為了解決容災,擴充套件,負載均衡的問題,我們可能會想很多辦法,alibaba的這個辦法感覺不錯。
 
本文只說dubbo,原理如下:
  • ConfigServer
配置中心,和每個Server/Client之間會作一個實時的心跳檢測(因為它們都是建立的Socket長連線,比如幾秒鐘檢測一次。收集每個Server提供的服務的資訊,每個Client的資訊,整理出一個服務列表,如:
 serviceName serverAddressList clientAddressList
 UserService 192.168.0.1,192.168.0.2,192.168.0.3,192.168.0.4  172.16.0.1,172.16.0.2
 ProductService 192.168.0.3,192.168.0.4,192.168.0.5,192.168.0.6 172.16.0.2,172.16.0.3
 OrderService 192.168.0.10,192.168.0.12,192.168.0.5,192.168.0.6  172.16.0.3,172.16.0.4
當某個Server不可用,那麼就更新受影響的服務對應的serverAddressList即把這個Server從serverAddressList中踢出去(從地址列表中刪除),同時將推送serverAddressList給這些受影響的服務的clientAddressList裡面的所有Client。如:192.168.0.3掛了,那麼UserService和ProductService的serverAddressList都要把192.168.0.3刪除掉,同時把新的列表告訴對應的Client 172.16.0.1,172.16.0.2,172.16.0.3
個Client掛了,那麼更新受影響的服務對應的clientAddressList
ConfigServer根據服務列表,就能提供一個web管理介面,來檢視管理服務的提供者和使用者。
新加一個Server時,由於它會主動與ConfigServer取得聯絡,而ConfigServer又會將這個資訊主動傳送給Client,所以新加一個Server時,只需要啟動Server,然後幾秒鐘內,Client就會使用上它提供的服務
  • Client
呼叫服務的機器,每個Client啟動時,主動與ConfigServer建立Socket長連線,並將自己的IP等相應資訊傳送給ConfigServer。
Client在使用服務的時候根據服務名稱去ConfigServer中獲取服務提供者資訊(這樣ConfigServer就知道某個服務是當前哪幾個Client在使用),Client拿到這些服務提供者資訊後,與它們都建立連線,後面就可以直接呼叫服務了,當有多個服務提供者的時候,Client根據一定的規則來進行負載均衡,如輪詢,隨機,按權重等。
一旦Client使用的服務它對應的服務提供者有變化(服務提供者有新增,刪除的情況),ConfigServer就會把最新的服務提供者列表推送給Client,Client就會依據最新的服務提供者列表重新建立連線,新增的提供者建立連線,刪除的提供者丟棄連線
  • Server
真正提供服務的機器,每個Server啟動,主動與ConfigServer建立Scoket長連線,並將自己的IP,提供的服務名稱,埠等資訊直接傳送給ConfigServer,ConfigServer就會收集到每個Server提供的服務的資訊。
 
優點:
1,只要在Client和Server啟動的時候,ConfigServer是好的,服務就可呼叫了,如果後面ConfigServer掛了,那隻影響ConfigServer掛了以後服務提供者有變化,而Client還無法感知這一變化。
2,Client每次呼叫服務是不經過ConfigServer的,Client只是與它建立聯絡,從它那裡獲取提供服務者列表而已
3,呼叫服務-負載均衡:Client呼叫服務時,可以根據規則在多個服務提供者之間輪流呼叫服務。
4,服務提供者-容災:某一個Server掛了,Client依然是可以正確的呼叫服務的,當前提是這個服務有至少2個服務提供者,Client能很快的感知到服務提供者的變化,並作出相應反應。
5,服務提供者-擴充套件:新增一個服務提供者很容易,而且Client會很快的感知到它的存在並使用它。


順便說一下,hadoop裡面的中心節點跟這裡的configServer作用類似,在維護節點列表方面,不過它的相關計算都需要通過中心節節點,讓它來分配任務


2.Zookeeper實現服務註冊與發現


zookeeper的實際運用場景:

  場景一:統一命名服務

  有一組伺服器客戶端提供某種服務,我們希望客戶端每次請求服務端都可以找到服務端叢集中某一臺伺服器,這樣服務端就可以向客戶端提供客戶端所需的服務。對於這種場景,我們的程式中一定有一份這組伺服器的列表,每次客戶端請求時候,都是從這份列表裡讀取這份伺服器列表。那麼這份列表顯然不能儲存在一臺單節點的伺服器上,否則這個節點掛掉了,整個叢集都會發生故障,我們希望這份列表時高可用的。

  高可用的解決方案是:這份列表是分散式儲存的,它是由儲存這份列表的伺服器共同管理的,如果儲存列表裡的某臺伺服器壞掉了,其他伺服器馬上可以替代壞掉的伺服器,並且可以把壞掉的伺服器從列表裡刪除掉,讓故障伺服器退出整個叢集的執行,而這一切的操作又不會由故障的伺服器來操作,而是叢集里正常的伺服器來完成。這是一種主動的分散式資料結構,能夠在外部情況發生變化時候主動修改資料項狀態的資料機構。Zookeeper框架提供了這種服務。這種服務名字就是:統一命名服務,它和JavaEE裡的JNDI服務很像。 

  場景二:分散式鎖服務

  當分散式系統運算元據,例如:讀取資料、分析資料、最後修改資料。在分散式系統裡這些操作可能會分散到叢集裡不同的節點上,那麼這時候就存在資料操作過程中一致性的問題,如果不一致,我們將會得到一個錯誤的運算結果,在單一程式的程式裡,一致性的問題很好解決,但是到了分散式系統就比較困難,因為分散式系統裡不同伺服器的運算都是在獨立的程式裡,運算的中間結果和過程還要通過網路進行傳遞,那麼想做到資料操作一致性要困難的多。Zookeeper提供了一個鎖服務解決了這樣的問題,能讓我們在做分散式資料運算時候,保證資料操作的一致性。 

  場景三:配置管理

  在分散式系統裡,我們會把一個服務應用分別部署到n臺伺服器上,這些伺服器的配置檔案是相同的(例如:我設計的分散式網站框架裡,服務端就有4臺伺服器,4臺伺服器上的程式都是一樣,配置檔案都是一樣),如果配置檔案的配置選項發生變化,那麼我們就得一個個去改這些配置檔案,如果我們需要改的伺服器比較少,這些操作還不是太麻煩,如果我們分散式的伺服器特別多,比如某些大型網際網路公司的hadoop叢集有數千臺伺服器,那麼更改配置選項就是一件麻煩而且危險的事情。

  這時候zookeeper就可以派上用場了,我們可以把zookeeper當成一個高可用的配置儲存器,把這樣的事情交給zookeeper進行管理,我們將叢集的配置檔案拷貝到zookeeper的檔案系統的某個節點上,然後用zookeeper監控所有分散式系統裡配置檔案的狀態,一旦發現有配置檔案發生了變化,每臺伺服器都會收到zookeeper的通知,讓每臺伺服器同步zookeeper裡的配置檔案,zookeeper服務也會保證同步操作原子性,確保每個伺服器的配置檔案都能被正確的更新。 

  場景四:為分散式系統提供故障修復的功能

  叢集管理是很困難的,在分散式系統里加入了zookeeper服務,能讓我們很容易的對叢集進行管理。叢集管理最麻煩的事情就是節點故障管理,zookeeper可以讓叢集選出一個健康的節點作為master,master節點會知道當前叢集的每臺伺服器的執行狀況,一旦某個節點發生故障,master會把這個情況通知給叢集其他伺服器,從而重新分配不同節點的計算任務。Zookeeper不僅可以發現故障,也會對有故障的伺服器進行甄別,看故障伺服器是什麼樣的故障,如果該故障可以修復,zookeeper可以自動修復或者告訴系統管理員錯誤的原因讓管理員迅速定位問題,修復節點的故障。大家也許還會有個疑問,master故障了,那怎麼辦了?zookeeper也考慮到了這點,zookeeper內部有一個“選舉領導者的演算法”,master可以動態選擇,當master故障時候,zookeeper能馬上選出新的master對叢集進行管理。

 

  下面我要講講zookeeper的特點:  

  zookeeper是一個精簡的檔案系統。zookeeper這個檔案系統是管理小檔案的。
  zookeeper提供了豐富的“構件”,這些構件可以實現很多協調資料結構和協議的操作。例如:分散式佇列、分散式鎖以及一組同級節點的“領導者選舉”演算法。
  zookeeper是高可用的,它本身的穩定性是相當之好,分散式叢集完全可以依賴zookeeper叢集的管理,利用zookeeper避免分散式系統的單點故障的問題。
  zookeeper採用了鬆耦合的互動模式。這點在zookeeper提供分散式鎖上表現最為明顯,zookeeper可以被用作一個約會機制,讓參入的程式不在了解其他程式的(或網路)的情況下能夠彼此發現並進行互動,參入的各方甚至不必同時存在,只要在zookeeper留下一條訊息,在該程式結束後,另外一個程式還可以讀取這條資訊,從而解耦了各個節點之間的關係。
  zookeeper為叢集提供了一個共享儲存庫,叢集可以從這裡集中讀寫共享的資訊,避免了每個節點的共享操作程式設計,減輕了分散式系統的開發難度。

  zookeeper的設計採用的是觀察者的設計模式,zookeeper主要是負責儲存和管理大家關心的資料,然後接受觀察者的註冊,一旦這些資料的狀態發生變化,Zookeeper 就將負責通知已經在 Zookeeper 上註冊的那些觀察者做出相應的反應,從而實現叢集中類似 Master/Slave 管理模式。

   由此可見zookeeper很利於分散式系統開發,它能讓分散式系統更加健壯和高效。

  前不久我參加了部門的hadoop興趣小組,測試環境的hadoop、mapreduce、hive及hbase都是我來安裝的,安裝hbase時候安裝要預先安裝zookeeper,最早我是在四臺伺服器上都安裝了zookeeper,但是同事說安裝四臺和安裝三臺是一回事,這是因為zookeeper要求半數以上的機器可用,zookeeper才能提供服務,所以3臺的半數以上就是2臺了,4臺的半數以上也是兩臺,因此裝了三臺伺服器完全可以達到4臺伺服器的效果,這個問題說明zookeeper進行安裝的時候通常選擇奇數臺伺服器。在學習hadoop的過程中,我感覺zookeeper是最難理解的一個子專案,原因倒不是它技術負責,而是它的應用方向很讓我困惑,所以從zookeeper開始,也不講具體技術實現,而從zookeeper的應用場景講起,理解了zookeeper應用的領域,我想再學習zookeeper就會更加事半功倍。


相關文章