架構設計:一種遠程調用服務的設計構思(zookeeper的一種應用實踐)

  在深刻學習zookeeper我想先給你們介紹一個和zookeeper相關的應用實例,我把這個實例命名爲遠程調用服務。經過對這種應用實例的描述,咱們會對zookeeper應用場景會有深刻的瞭解。前端

  遠程調用是系統與系統之間的通訊機制,它的另外一種理解就是進程間的通訊。作分佈式系統的開發,遠程調用技術是其核心技術。遠程調用技術能夠將一組計算機系統造成一個網絡系統,對外提供總體服務,那麼這一羣的計算機系統就構成了一個更大型,性能更高的計算機系統。java

  我在前面的博客裏介紹了一種分佈式網站的架構設計,其中就有一個使用netty技術編寫的組件做爲前端系統和服務端系統通訊的媒介。在一個大型的互聯網公司裏會有不少這樣的網站系統,若是每個網站都像我博客裏所論述的進行開發,那麼對於系統通訊維護和管理,以及每一個系統網絡資源的分配管理就會形成必定的問題,對於這樣的問題,我舉個例子可能你們會更明白些,好比一個互聯網公司有數個對外提供服務的網站,有的網站訪問量很大,有的相對較小,可是公司的寬帶資源是有限的,那麼咱們就但願動態的管理和分配這些資源,若是咱們網站的通訊功能和網站都是緊耦合的,那麼調配這些資源的工做就會比較複雜和繁瑣,也很容易出問題。這樣的問題還會還有不少,我這裏不作細緻分析了。作軟件開發時候,有個原則,若是某個功能是能夠通用的,該功能很須要統一管理時候,咱們就應該把這個功能抽取成一個獨立的系統或組件,而且這個系統或組件賦予一些加強級的功能特性,這樣一定對整個系統的健壯性、可用性以及效率上有所提高。linux

  而我在分佈式網站裏所描述的通訊技術,就是遠程調用技術的一種,遠程調用技術就是客戶端和服務端的通訊技術,它能夠當作cs架構技術的一種,在java裏有不少優秀的框架實現遠程調用,例如java自帶的RMI,spring自帶的Httpinvoker,webservice技術等等。可是現有的這些技術知足不了互聯網公司的遠程調用需求,今天我將講述一套我本身構思的一套遠程調用技術,這個是借鑑了一些咱們公司的相似軟件的作法。web

  該框架主要是針對java的,其餘語言目前不能支持。首先我要總結遠程調用技術要包括那些技術,它們分別是:spring

  1. 通訊技術:遠程調用就是經過網絡技術將不一樣系統構成一個總體,所以通訊技術是其重點,通訊技術我這裏選擇的是netty技術,Netty提供異步的、事件驅動的網絡應用程序框架和工具,用以快速開發高性能、高可靠性的網絡服務器和客戶端程序。Netty會讓咱們開發通訊程序變得簡單,高效,其效率也是很是好的,同時它還支持多種不一樣的網絡協議。
  2. 序列化和反序列化技術:java的序列化技術是指將對象轉換爲byte數據,這些數據能夠被還原爲java對象,這種還原的過程就是反序列化了,該機制能夠自動處理不一樣操做系統之間的差別,例如window下序列化的對象,能夠在linux上進行從新構建。Java的jdk裏自帶了一個序列化和反序列化機制,熟悉hadoop的人知道hadoop設計了一套序列化和反序列化機制,爲何hadoop做者不選擇使用java自帶的序列化機制,這是由於java序列化機制很是複雜,複雜帶來效率低下,java的序列化機制還有一個重要的缺點就是它序列化的二進制數據會很是大,由於java序列化時候會附帶太多該對象的相關信息,過大的數據量就會影響網絡傳輸的效率,所以hadoop本身設計了一套序列化和反序列化機制,hadoop不一樣節點之間的通訊也是一種遠程調用機制,所以咱們發現好的序列化和反序列化技術對於遠程調用是至關重要的。咱們公司的遠程調用框架序列化技術有兩種一種就是java自帶的序列化和反序列化機制,一種是hessian技術,它是一種更加高效的序列化和反序列化技術。
  3. 壓縮技術:作網絡編程,最稀缺的資源就是寬帶資源,若是傳輸數據過大,那麼對數據的壓縮就會顯得十分重要,這裏我推薦一個壓縮技術snappy,它是一種高效的壓縮和解壓縮包,google公司內部普遍使用的一種壓縮技術。
  4. 高併發的技術:遠程調用技術必定會是多線程,只有這樣才能知足多個併發的處理請求,java在1.5的版本里提供了一個Executor框架,它在線程開發裏引入了任務的概念,使得多線程的程序開發會更加合理和可控,關於executor的技術你們能夠看看一本經典的書籍《java併發編程實踐》。想讓線程更加有效率,池技術也是並不可少的,apache的common-pool是一個很是好的池技術,咱們能夠將線程都預先建立好,而後放入到common-pool池裏進行管理。
  5. 非侵入式:這個也能夠叫作鬆耦合,對於java的web開發,最好的解耦方式就是使用spring技術,當咱們系統裏把遠程調用框架引入後,配置好相關的參數,咱們能夠把用於遠程調用的方法定義在spring的配置文件裏,那麼在程序裏調用的時候,利用spring直接獲取這個bean,那麼對於遠程調用的開發就和咱們在action裏調用server的方法沒啥區別了。下面是一段實例代碼:
<!-- 服務提供者配置 -->
<bean id="serverProvider" class="cn.com.sharpxiajun.RmifSpringProviderBean">
    <property name="interface" value="cn.com.ITest"></property><!-- 遠程調用的接口 -->
    <property name="target" ref="clsTest"></property><!-- clsTest實現ITest的實現類,clsTest這裏是一個bean的id值 -->
</bean>

<!-- 服務調用者配置 -->
<bean id="clientConsumer" class="cn.com.sharpxiajun.RmifSpringConsumerBean">
    <property name="interface" value="cn.com.clsTest"></property><!-- value就是Provider定義的target的接口實現類 -->
    <property name="seriaType" value="hessian"></property><!--序列化方式  -->
    <property name="compress" value="true"></property><!-- 壓縮標記 -->
</bean>

 

  6.負載均衡:分佈式系統都離不開負載均衡,好的負載均衡能夠充分利用好不一樣服務器的計算資源,提供系統的併發量和運算能力,對於網站而言(咱們公司如今網站服務器不是太多)少於10臺服務器可使用兩種策略:一種是簡單輪詢,好比有6臺服務端,咱們會把第一個請求給第一臺服務器,第二個請求給第二臺,依次類推,等6臺循環完畢,又從第一臺開始;第二種是隨機方式,即便用random函數,固然更多的服務器我就不知道有什麼輪詢機制比較好,但願有知道的童鞋能夠給我推薦下。apache

  我這裏設計的遠程調用框架,除了以上的功能外,我但願它還能有心跳管理機制,超時管理機制,服務分級管理,就是根據服務的重要性或者系統的繁忙度能夠調節網絡資源。編程

  哈哈,講了這麼久估計有童鞋可能有點煩了,不是說應用zookeeper的實例嗎?怎麼還沒見到zookeeper的影子。彆着急,zookeeper立刻就要上場了。瀏覽器

  仍是以我前面博客裏寫分佈式網站講起,服務端系統咱們能夠當作服務提供者,前端系統當作服務調用者,提供者能夠類比商戶,調用者能夠類比客戶,商戶和客戶能夠直接進行交易,這種直接交易方式很是原始甚至還會有風險,現代社會商戶和客戶直接的交易十分高效,高效的緣由是由於有一個規範的大市場,商戶和客戶的交易在市場裏進行的,這樣交易會變得更加安全和高效,我設計的分佈式框架最大的特色就是提供了一個相似市場的角色,它來管理服務提供者和服務調用者,我把這個功能模塊稱爲遠程調用管理組件。安全

  遠程調用管理組件是本框架的核心,它的主要做用是接收服務端提供者的註冊的通知,該通知通常是接口以及該接口的實現類還有服務器的ip地址,管理組件會將這些通知記錄下來,而且根據配置對這些服務程序進行分組和標記,註冊好的信息管理組件會將這些信息推送到服務調用者。遠程調用管理組件還包含心跳機制,這個心跳機制是針對服務提供者,經過心跳機制檢測服務提供者的健康情況,管理組件不會檢測服務調用者的健康狀態,由於這個不必,由於本框架的使用仍是調用者直接去請求提供者,邏輯上是不必關心調用者的狀態,這和bs架構裏瀏覽器同樣,咱們不會去關心瀏覽器用戶是否是存在。服務提供者、服務調用者和遠程調用管理組件的關係以下圖所示:服務器

  遠程調用框架運行的過程是:當服務提供者啓動時候,它會將本身的ip地址和註冊的方法傳輸到遠程調用管理組件,管理組件接收到註冊信息會將這些信息存儲下來,存儲技術就是使用zookeeper,存儲成功後,管理組件會將成功通知傳回給服務提供者,同時管理組件還會經過心跳檢測服務提供者是否健康;當服務調用者啓動時候,它會向管理組件請求服務提供者信息,管理組件接收到請求後會將相關信息推送給服務調用者。在實際系統運行時候,服務調用者直接和服務提供者進行通訊交互了,通訊方式是netty,若是調用者和提供者有相關變化,都會先通知服務管理組件,服務管理組件會將相關變動信息推送給相應的系統。

 

  遠程調用管理組件主要是經過zookeeper實現,zookeeper擁有一個層次的命名空間,它的模型是一個樹狀結構,樹狀結構是一個強大的數據類型,它幾乎能存儲全部不一樣的數據類型,咱們經過zookeeper將這些信息保存起來,便於咱們管理整個遠程調用框架,同時zookeeper仍是高可靠的,這個我在前面zookeeper文章裏講到了,這樣就保證了整個遠程調用框架的穩定性,實際應用中咱們會將組件編譯成一個jar包,不一樣的項目直接引用這個jar包,這樣管理組件服務端和服務的提供者和調用者就聯繫起來。至於提供者和調用者的通訊機制是直接進行,由於咱們將通訊程序集成在jar包裏,只不過相應的管理機制抽取到外部服務端進行統一管理。

 

  這就是我設計的遠程調用框架,惋惜的是,這個構思我尚未真正實現過,今天拿出來是想體現zookeeper的實際應用,爲我後面講解zookeeper作鋪墊,至因而否可行,看之後有沒有機會開發個相似的系統,到時估計還有不少意想不到的問題要解決。

 

    (遠程調用服務的設計我參考了技術友人馬德鑫的設計,他曾是淘寶的技術架構師)

相關文章
相關標籤/搜索