一.HSF的基本概念 HSF全稱為High-Speed Service Framework,旨在為淘系的應用提供一個分布式的服務框架,HSF從分布式應用層面以及統(tǒng)一的發(fā)布/調(diào)用方式層面為大家提供支持,從而可以很容易的開發(fā)分布式的應用以及提供或使用公用功能模塊,而不用考慮分布式領(lǐng)域中的各種細節(jié)技術(shù),例如遠程通訊、性能損耗、調(diào)用的透明化、同步/異步調(diào)用方式的實現(xiàn)等等問題。
二.知識準備 通過以上的說明,大致了解了一下RPC與HSF的總體架構(gòu),但是總體架構(gòu)離具體實現(xiàn)還想差很多,有些知識準備還是很有必要的。 1.對象的序列化 對象的序列化過程在RPC過程中是很重要的一個環(huán)節(jié),序列化對于遠程調(diào)用的響應速度、吞吐量、網(wǎng)絡帶寬消耗等同樣也起著至關(guān)重要的作用。 2.動態(tài)代理 對于消費方來說,所存在的只有一個接口,雖然底層的實現(xiàn)原理我們知道,但是為了在使用時的高度透明,在JAVA語言層面上的表現(xiàn)形式則是通過動態(tài)代理的方式實現(xiàn)的,很多的邏輯都在InvocationHandler 中處理的。關(guān)于如何實現(xiàn)動態(tài)代理,還動態(tài)代理的一些使用的細節(jié)也可以稍作了解。 3.網(wǎng)絡通信NIO 如果在網(wǎng)絡傳輸過程中,采取普通的BIO,會有很多的問題存在,例如如果調(diào)用端有多個請求過來,那么就得需要多個線程去處理,每個線程都使用獨立的連接,在遠端的提供者端有對應的多個線程來執(zhí)行相應的服務。這種方式會使得調(diào)用者和提供者之間建立大量的連接,而且是阻塞的方式,連接并不能得到充分的利用(摘自《大型網(wǎng)站系統(tǒng)與JAVA中間件》)。采用NIO則就可以避免這樣的損耗,但是HSF在使用時并不是采用直接的NIO編程,而是通過第三方的框架Netty。
二.HSF 實現(xiàn)原理 1.提供服務的大致流程如下: 從以上幾個問題出發(fā),看下HSF的實現(xiàn)方式。 2.HSF的整體實現(xiàn)方式: 從圖中可以看出,HSF的實現(xiàn)方式可以理解為是C/S的架構(gòu),但是和傳統(tǒng)的C/S架構(gòu)相比還是有很大的不同,HSF沒有真正的服務器,每個應用都可以成為服務的調(diào)用方和提供方。具體工作方式如下: ConfigServer:遠程調(diào)用對端的地址就是由ConfigServer 來推送的,這樣用戶只需要配置自己的服務端或者消費端,不需要對自己的地址進行管理。 Diamond:持久化的配置中心,用于配置服務調(diào)用的規(guī)則。 服務:服務是調(diào)用方和提供方交流的依憑,一般是一個接口,表示一個業(yè)務行為以及相關(guān)的數(shù)據(jù)含義。通過使用HSFApiProviderBean能夠暴露一個服務,將機器的地址注冊到configserver,并且能夠通過12200端口進行服務提供,通過HSFApiConsumerBean能夠包裝出一個客戶端,它是服務接口的一個代理,并且它從configserver上訂閱了服務的地址列表,能夠在這個列表上完成隨機調(diào)用,做到負載均衡與HA((High Available,高可用性群集)。 網(wǎng)絡通信:HSF的底層網(wǎng)絡通信是使用netty框架實現(xiàn)的,是基于epoll的NIO的網(wǎng)絡通訊框架,HSF在此使用的是長連接,通過合理的服務部署及負債均衡,基本不存在I/O方面的限制。
三.HSF設(shè)計架構(gòu)
Client是HSF的重點,下面是各模塊的功能介紹: HSF調(diào)用流程
四.HSF處理請求流程 1.HSF提供端初始化 2.HSF消費端初始化 3.消費方請求到提供方,響應一次調(diào)用 4.實現(xiàn)細節(jié) 心跳檢測: 1、客戶端主動關(guān)閉連接:客戶端第一次與服務端建立鏈接后,就會周期性(27s)發(fā)送心跳包的callback調(diào)用,如果連續(xù)三次收不到服務端的心跳包回應,客戶端主動關(guān)閉鏈接 2、服務端主動關(guān)閉連接:當連接59s沒有調(diào)用(對方網(wǎng)絡不可用,或者full gc太久),相當于兩次(2*27s)收不到心跳包的時間 從上圖可以看出RPC要解決以下幾個問題: 如何解決網(wǎng)絡通信問題,主要是通過在客戶端和服務器之間建立TCP連接,遠程過程調(diào)用的所有交換的數(shù)據(jù)都在這個連接里傳輸。連接可以是按需連接,調(diào)用結(jié)束后就斷掉,也可以是長連接,多個遠程過程調(diào)用共享同一個連接。 如何解決尋址問題,客戶端如何找到制定的服務端,也就是保證準確有效的完成一次服務調(diào)用的前提。 參數(shù)的傳遞及服務端在收到客戶端請求后如何實現(xiàn)其具體功能并返回,由于網(wǎng)絡傳輸協(xié)議是二進制的,內(nèi)存中的參數(shù)值必須要解決序列化,反序列化,以及對半包,粘包的處理。
五.HSF的優(yōu)點: 1.服務的自動注冊、發(fā)現(xiàn) 通過注冊中心,實現(xiàn)服務的注冊/注銷與服務的發(fā)現(xiàn)。當服務啟動后,會調(diào)用publish來將服務發(fā)布到中心,而服務的消費者,通過調(diào)用訂閱接口傳入的監(jiān)聽器來更新服務提供者列表。HSF提供了三種注冊中心實現(xiàn),分別是ConfigServer,Zookeper,和配置文件模式。 這里僅對Zookeper進行分析,ZookeeperMetadataAddressService 實現(xiàn)了上述接口,在初始化中實例化了一個ZookeeperRegistry來進行管理,其使用了一個封裝了zookeperclient的實例-ZkclientZookeeperClient,在注冊服務的時候根據(jù)url參數(shù)中的Constants.DYNAMIC_KEY來確定創(chuàng)建Persistent節(jié)點還是Ephemeral節(jié)點,Ephemeral節(jié)點生命周期與本機連接綁定,這樣就可以實現(xiàn)本機離線后的服務自動注銷的功能。 2) 服務提供者與消費者之間長連接。 HSF采用長連接方式進行通信,相比短連接,長連接更具性能優(yōu)勢,避免連接重復創(chuàng)建與銷毀帶來的緩沖區(qū)申請與釋放。HSF抽象了連接AbstractClient(Client),并采用了netty框架作為底層實現(xiàn)。netty是一個性能非常優(yōu)秀的通信框架,基于反應器模式,內(nèi)部采用了管線模式來解耦不同層次的邏輯之間的耦合問題。HSF為了強化TCP連接的可用性,增加HeartBeat功能,使用了一個Netty提供的 HashedWheelTimer 的定時任務調(diào)度器來執(zhí)行心跳包的發(fā)送(補充:此HashedWheelTimer原理采用輪片式的桶結(jié)構(gòu),避免每次操作對全部任務的迭代操作,只對將要到期的桶進行操作,此原理也可用于緩存系統(tǒng)設(shè)計,在需要進行垃圾回收的情況下只需要按照桶為單位進行內(nèi)存回收)。 3) 非侵入性 HSF最大優(yōu)點是非侵入性,它使用了JAVA的Proxy機制來實現(xiàn)這一特點,在通過xml配置文件配置Consumer的時候,實際上是調(diào)用了 HSFApiConsumerBean ,在它的初始化方法中,讀取了配置的實現(xiàn)接口,并在ProcessComponent中用一個封裝了Proxy注冊功能,并實現(xiàn)了InvocationHandler接口的類HSFServiceProxy去管理。使用者在自己的代碼中無需做任何特殊處理,就像使用本地方法一樣去調(diào)用其方法。 4) 版本管理 這一特性可以很靈活的幫助上線運營的服務在升級過程中避免服務不可用的情況。 5) 服務治理 可以通過網(wǎng)頁可視化查看、管理、測試服務的可用。 6) 擴展靈活 可以接入自動服務降級功能(熔斷) - 根據(jù)配置或服務的執(zhí)行結(jié)果,在調(diào)用級控制服務是否調(diào)用執(zhí)行,避免服務整體癱瘓,提升服務的可用性。
|
|