不久前,我們討論過Nginx+tomcat組成的叢集,這已經是非常靈活的叢集技術,但是當我們的系統遇到更大的瓶頸,全部應用的單點伺服器已經不能滿足我們的需求,這時,我們要考慮另外一種,我們熟悉的內容,就是分布式,而當下流行的Dubbo架構,不容我們忽視,這裡,咱們一起來探討一下這個架構的使用。
一,背景
以前我們需要遠程調用他人的介面,我們是這麼做的:
我們遇到的問題:
(1) 當服務越來越多時,服務URL組態管理變得非常困難,F5硬體負載平衡器的單點壓力也越來越大。
此時需要一個服務註冊中心,動態註冊和探索服務,使服務的位置透明。
並通過在消費方擷取服務提供者地址清單,實現軟負載平衡和Failover,降低對F5硬體負載平衡器的依賴,也能減少部分成本。
(2) 當進一步發展,服務間依賴關係變得錯蹤複雜,甚至分不清哪個應用要在哪個應用之前啟動,架構師都不能完整的描述應用的架構關係。
這時,需要自動畫出應用間的依賴關係圖,以協助架構師理清理關係。
(3) 接著,服務的調用量越來越大,服務的容量問題就暴露出來,這個服務需要多少機器支撐。什麼時候該加機器。
為瞭解決這些問題,第一步,要將服務現在每天的調用量,回應時間,都統計出來,作為容量規劃的參考指標。
其次,要可以動態調整權重,線上上,將某台機器的權重一直加大,並在加大的過程中記錄回應時間的變化,直到回應時間到達閥值,記錄此時的訪問量,再以此訪問量乘以機器數反推總容量。
為解決這些問題,Dubbo為我們做了什麼呢:
負載平衡:
這就是所謂的軟負載平衡。
現在讓我們一起來接觸下這個優秀的架構:
簡介
架構如圖:
節點角色說明:
Provider: 暴露服務的服務提供者。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務註冊與發現的註冊中心。
Monitor: 統計服務的調用次調和調用時間的監控中心。
Container: 服務運行容器。
調用關係說明:
0. 服務容器負責啟動,載入,運行服務提供者。
1. 服務提供者在啟動時,向註冊中心註冊自己提供的服務。
2. 服務消費者在啟動時,向註冊中心訂閱自己所需的服務。
3. 註冊中心返回服務提供者地址清單給消費者,如果有變更,註冊中心將基於長串連推送變更資料給消費者。
4. 服務消費者,從提供者地址清單中,基於軟負載平衡演算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。
5. 服務消費者和提供者,在記憶體中累計調用次數和調用時間,定時每分鐘發送一次統計資料到監控中心。
Dubbo提供了很多協議,Dubbo協議、RMI協議、Hessian協議,我們查看Dubbo原始碼,有各種協議的實現,如圖所示:
我們之前沒用Dubbo之前時,大部分都使用Hessian來使用我們服務的暴露和調用,利用HessianProxyFactory調用遠程介面。
上面是參考了Dubbo官方網介紹,接下來我們來介紹SpringMVC、Dubbo、Zookeeper整合使用。
第三:Dubbo與Zookeeper、SpringMVC整合使用
第一步:在Linux上安裝Zookeeper
Zookeeper作為Dubbo服務的註冊中心,Dubbo原先基於資料庫的註冊中心,沒採用Zookeeper,Zookeeper一個分布式的服務架構,是樹型的目錄服務的資料存放區,能做到叢集管理資料 ,這裡能很好的作為Dubbo服務的註冊中心,Dubbo能與Zookeeper做到叢集部署,當提供者出現斷電等異常停機時,Zookeeper註冊中心能自動刪除提供者資訊,當提供者重啟時,能自動回復註冊資料,以及訂閱請求。我們先在linux上安裝Zookeeper,我們安裝最簡單的單點,叢集比較麻煩。
先需要安裝JdK,從Oracle的Java網站下載,安裝很簡單,就不再詳述。
單機模式
單機安裝非常簡單,只要擷取到 Zookeeper 的壓縮包並解壓到某個目錄如:C:/zookeeper-3.4.5/下,Zookeeper 的啟動指令碼在 bin 目錄下,Windows 下的啟動指令碼是 zkServer.cmd。
在你執行啟動指令碼之前,還有幾個基本的配置項需要配置一下,Zookeeper 的設定檔在 conf 目錄下,這個目錄下有 zoo_sample.cfg 和 log4j.properties,你需要做的就是將 zoo_sample.cfg 改名為 zoo.cfg,因為 Zookeeper 在啟動時會找這個檔案作為預設設定檔。下面詳細介紹一下,這個設定檔中各個配置項的意義。
<span style="font-size:18px;"># The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit=10 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=5 # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. dataDir=C://zookeeper-3.4.5//data dataLogDir=C://zookeeper-3.4.5//log # the port at which the clients will connect clientPort=2181 # # Be sure to read the maintenance section of the # administrator guide before turning on autopurge. # # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance # # The number of snapshots to retain in dataDir #autopurge.snapRetainCount=3 # Purge task interval in hours # Set to "0" to disable auto purge feature #autopurge.purgeInterval=1</span>
tickTime:這個時間是作為 Zookeeper 伺服器之間或用戶端與伺服器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發送一個心跳。 dataDir:顧名思義就是 Zookeeper 儲存資料的目錄,預設情況下,Zookeeper 將寫資料的記錄檔也儲存在這個目錄裡。 dataLogDir:顧名思義就是 Zookeeper 儲存記錄檔的目錄 clientPort:這個連接埠就是用戶端串連 Zookeeper 伺服器的連接埠,Zookeeper 會監聽這個連接埠,接受用戶端的訪問請求。
當這些配置項配置好後,你現在就可以啟動 Zookeeper 了,啟動後要檢查 Zookeeper 是否已經在服務,可以通過 netstat – ano 命令查看是否有你配置的 clientPort 連接埠號碼在監聽服務。
第二步:配置dubbo-admin的管理頁面,方便我們管理頁面
(1)下載dubbo-admin-2.4.1.war包,在windows的tomcat部署,先把dubbo-admin-2.4.1放在tomcat的webapps/ROOT下,然後進行解壓
(2)然後到webapps/ROOT/WEB-INF下,有一個dubbo.properties檔案,裡面指向Zookeeper ,使用的是Zookeeper 的註冊中心,如圖所示:
<span style="font-size:18px;">dubbo.registry.address=zookeeper://127.0.0.1:2181 dubbo.admin.root.password=root dubbo.admin.guest.password=guest</span>
(3)然後啟動tomcat服務,使用者名稱和密碼:root,並訪問服務,顯示登陸頁面,說明dubbo-admin部署成功,如圖所示:
第三步:SpringMVC與Dubbo的整合,這邊使用的Maven的管理項目
第一:我們先開發服務註冊的,就是提供服務,項目結構如圖所示:
(1)test-maven-api項目加入了一個服務介面,代碼如下:
public interface TestRegistryService { public String hello(String name); }
(2)test-maven-console在pom.xml加入Dubbo和Zookeeper的jar包、引用test-maven-api的jar包,代碼如下:
<span style="font-size:18px;"><dependency> <groupId>cn.test</groupId> <artifactId>test-maven-api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency></span>
(3)test-maven-console實現具體的服務,代碼如下:
@Service("testRegistryService") public class TestRegistryServiceImpl implements TestRegistryService { public String hello(String name) { return &quo