背景
目前nodejs應用越來越廣泛,但和java的dubbo體系接入困難,所以我們需要實現node端的dubbo provider邏輯。java的dubbo provider是和consumer在一個jar中,提供了服務配置、注冊、集群與負載均衡、監控和多種協議。使用nodejs實現一個可用的dubbo provider SDK完全沒有問題,最簡單的實現則是在對應ZK集群注冊接口與機器IP的映射關系,consumer便可以訪問對應rpc接口。可是,在可用基礎上,仍然需要提供相關配套設施如配置、注冊和監控等,達到商業上的高可用。在評估了各種實現方案后,決定放棄開發node provider端sdk,使用node+agent的proxy模式。
agent是一個可與node服務交互通信的,並提供dubbo provider功能的java服務。agent部署在nodejs服務機器上,扮演dubbo服務的入口角色,同時node服務返回的數據類型由agent進行轉換映射,如 object(node) -> Map(Java), 具體轉換規則則由node接口提供方提供調用接口jar包,consumer使用jar包進行調用即可。
整體架構
其中 vitamin為基於數據庫的統一配置平台,解耦各個系統的強依賴。
Node中間件
Node中間件提供dubbo接口上報和服務提供功能。上報http接口要暴露的Dubbo服務配置信息(interface+version+method)即映射關系,node的提供rpc服務以HTTP形式存在(兼容之前業務),由agent進行調用,數據類型為JSON。
Agent
-
根據Vitamin的實時配置向zookeeper注冊dubbo服務(泛化)
-
泛化服務每個method會根據Vitamin中的映射關系找到對應的http本地接口(localhost)進行調用
-入參和返回值進行json和Java類型的轉換
Node業務方
-
Node提供普通的HTTP+JSON服務,可復用歷史接口
-
提供一個對應dubbo接口的jar包,需保證http接口json和jar中的model轉換關系可行
上游業務
- 拿到jar包依賴之后,像普通dubbo服務一樣調用即可
類型轉換
Dubbo方法入參轉換成NodeJs的http調用參數:強類型轉弱類型,可直接轉換
NodeJs服務返回的json轉Dubbo方法返回值:弱類型轉強類型
解決方案:Dubbo泛化服務返回Map,consumer端拿到這個Map會自動根據client.jar的方法返回值類型(支持泛型)進行相應的字段注入
可能存在的問題
-
agent不會在調用nodejs服務進行熔斷,即nodejs服務大量超時可能會讓agent連接池或線程池占滿
-
agent進程的生命周期由node進程維護,通過基於配置中心的心跳機制檢測agent進程是否存活
-
錯誤排查定位由於多了一層調用,更為復雜
-
可能存在的單機性能問題