XXL-RPC 是一個分佈式服務框架,提供穩定高性能的RPC遠程服務調用功能。擁有"高性能、分佈式、註冊中心、負載均衡、服務治理"等特性。現已開放源代碼,開箱即用。javascript
RPC(Remote Procedure Call Protocol,遠程過程調用),調用遠程服務就像調用本地服務,在提供遠程調用能力時不損失本地調用的語義簡潔性;css
通常公司,尤爲是大型互聯網公司內部系統由上千上萬個服務組成,不一樣的服務部署在不一樣機器,跑在不一樣的JVM上,此時須要解決兩個問題:html
「XXL-RPC」能夠高效的解決這個問題:java
源碼倉庫地址 | Release Download |
---|---|
https://github.com/xuxueli/xxl-rpc | Download |
https://gitee.com/xuxueli0323/xxl-rpc | Download |
一、編譯項目nginx
源碼目錄介紹:git
推薦使用 "XXL-REGISTRY" 做爲註冊中心。可前往 XXL-REGISTRY (https://github.com/xuxueli/xxl-registry ) 查看部署文檔。很是輕量級,一分鐘可完成部署工做。github
以示例項目 「xxl-rpc-sample-springboot」 爲例講解;算法
開發RPC服務的 「接口 / interface」 和 「數據模型 / DTO」;spring
可參考以下代碼:
com.xxl.rpc.sample.api.DemoService com.xxl.rpc.sample.api.dto.UserDTO
需引入:XXL-RPC核心依賴 + 公共API接口依賴docker
<dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-rpc-core</artifactId> <version>${parent.version}</version> </dependency>
// 參考代碼位置:com.xxl.rpc.sample.server.conf.XxlRpcProviderConfig @Bean public XxlRpcSpringProviderFactory xxlRpcSpringProviderFactory() { XxlRpcSpringProviderFactory providerFactory = new XxlRpcSpringProviderFactory(); providerFactory.setPort(port); providerFactory.setServiceRegistryClass(XxlRegistryServiceRegistry.class); providerFactory.setServiceRegistryParam(new HashMap<String, String>(){{ put(XxlRegistryServiceRegistry.XXL_REGISTRY_ADDRESS, address); put(XxlRegistryServiceRegistry.ENV, env); }}); logger.info(">>>>>>>>>>> xxl-rpc provider config init finish."); return providerFactory; }
ProviderFactory 參數 | 說明 |
---|---|
netType | 服務通信方案,可選範圍:NETTY(默認)、NETTY_HTTP ; |
serialize | 序列化方案,可選範圍: HESSIAN(默認)、HESSIAN1 ; |
ip | 服務方IP,爲空自動獲取機器IP,支持手動指定 |
port | 服務方端口,默認 7080 |
accessToken | 服務鑑權Token,非空時生效; |
serviceRegistryClass | 服務註冊中心,可選範圍:LocalServiceRegistry.class、ZkServiceRegistry.class;支持靈活自由擴展; |
serviceRegistryParam | 服務註冊中心啓動參數,參數說明可參考各註冊中心實現的 start() 的方法註釋; |
實現 「服務API」 的接口,開發業務邏輯代碼;
可參考以下代碼:
com.xxl.rpc.sample.api.DemoService 注意: 一、添加 「@Service」 註解:被Spring容器掃描識別爲SpringBean; 二、添加 「@XxlRpcService」 註解:被 「XXL-RPC」 的 ProviderFactory 掃描識別,進行Provider服務註冊,若是開啓註冊中心同時也會進行註冊中心服務註冊;
「@XxlRpcService」 註解參數 | 說明 |
---|---|
version | 服務版本,默認空;可據此區分同一個「服務API」 的不一樣版本; |
需引入:XXL-RPC核心依賴 + 公共API接口依賴
<dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-rpc-core</artifactId> <version>${parent.version}</version> </dependency>
// 參考代碼位置:com.xxl.rpc.sample.client.conf.XxlRpcInvokerConfig @Bean public XxlRpcSpringInvokerFactory xxlJobExecutor() { XxlRpcSpringInvokerFactory invokerFactory = new XxlRpcSpringInvokerFactory(); invokerFactory.setServiceRegistryClass(XxlRegistryServiceRegistry.class); invokerFactory.setServiceRegistryParam(new HashMap<String, String>(){{ put(XxlRegistryServiceRegistry.XXL_REGISTRY_ADDRESS, address); put(XxlRegistryServiceRegistry.ENV, env); }}); logger.info(">>>>>>>>>>> xxl-rpc invoker config init finish."); return invokerFactory; }
InvokerFactory 參數 | 說明 |
---|---|
serviceRegistryClass | 服務註冊中心,可選範圍:LocalServiceRegistry.class、ZkServiceRegistry.class;支持靈活自由擴展; |
serviceRegistryParam | 服務註冊中心啓動參數,參數說明可參考各註冊中心實現的 start() 的方法註釋; |
// 參考代碼位置:com.xxl.rpc.sample.client.controller.IndexController @XxlRpcReference private DemoService demoService; …… UserDTO user = demoService.sayHi(name); ……
「@XxlRpcReference」 註解參數 | 說明 |
---|---|
netType | 服務通信方案,可選範圍:NETTY(默認)、NETTY_HTTP; |
serializer | 序列化方案,可選範圍: HESSIAN(默認)、HESSIAN1; |
address | 服務遠程地址,ip:port 格式;選填;非空時將會優先實用該服務地址,爲空時會從註冊中心服務地址發現; |
accessToken | 服務鑑權Token,非空時生效; |
version | 服務版本,默認空;可據此區分同一個「服務API」 的不一樣版本; |
timeout | 服務超時時間,單位毫秒; |
callType | 請求類型,可選範圍:SYNC(默認)、ONEWAY、FUTURE、CALLBACK; |
// 參考代碼位置:com.xxl.rpc.sample.client.controller.IndexController
代碼中將上面配置的消費方 invoker 遠程服務注入到測試 Controller 中使用,調用該服務,查看看是否正常。 若是正常,說明該接口項目經過XXL-RPC從 client 項目調用了 server 項目中的服務,誇JVM進行了一次RPC通信。
訪問該Controller地址便可進行測試:http://127.0.0.1:8081/?name=jack
得益於優良的兼容性與模塊化設計,不限制外部框架;除 spring/springboot 環境以外,理論上支持運行在任何Java代碼中,甚至main方法直接啓動運行;
以示例項目 「xxl-rpc-sample-frameless」 爲例講解;該示例項目以直連IP方式進行演示,也能夠選擇接入註冊中心方式使用,如接入 XXL-REGISTRY。
// 參考代碼位置:com.xxl.rpc.sample.server.XxlRpcServerApplication // init XxlRpcProviderFactory providerFactory = new XxlRpcProviderFactory(); providerFactory.initConfig(NetEnum.NETTY, Serializer.SerializeEnum.HESSIAN.getSerializer(), -1, -1, null, 7080, null, null, null); // add services providerFactory.addService(DemoService.class.getName(), null, new DemoServiceImpl()); // start providerFactory.start(); while (!Thread.currentThread().isInterrupted()) { TimeUnit.HOURS.sleep(1); } // stop providerFactory.stop();
// 參考代碼位置:com.xxl.rpc.sample.client.XxlRpcClientAplication // init client DemoService demoService = (DemoService) new XxlRpcReferenceBean(NetEnum.NETTY, Serializer.SerializeEnum.HESSIAN.getSerializer(), CallType.SYNC, DemoService.class, null, 500, "127.0.0.1:7080", null, null).getObject(); // test UserDTO userDTO = demoService.sayHi("[SYNC]jack"); System.out.println(userDTO);
提供穩定高性能的RPC遠程服務調用功能,簡化分佈式服務通信開發。
概念:
RPC通信,可大體劃分爲四個步驟,可參考上圖進行理解:(XXL-RPC提供了多種調用方案,此處以 「SYNC」 方案爲例講解;)
consumer和provider採用NIO方式通信,其中TCP通信方案可選NETTY具體選型,高吞吐高併發;可是僅僅依靠單個TCP鏈接進行數據傳輸存在瓶頸和風險,所以XXL-RPC在consumer端自身實現了內部鏈接池,consumer和provider之間爲了一個鏈接池,當盡情底層通信是會取出一條TCP鏈接進行通信(可參考上圖)。
XXL-RPC採用NIO進行底層通信,可是NIO是異步通信模型,調用線程並不會阻塞獲取調用結果,所以,XXL-RPC實現了在異步通信模型上的同步調用,即「sync-over-async」,實現原理以下,可參考上圖進行理解:
XXL-RPC的註冊中心,是可選組件,支持服務註冊並動態發現;
可選擇不啓用,直接指定服務提供方機器地址通信;
選擇啓用時,內置可選方案:「XXL-REGISTRY 輕量級註冊中心」(推薦)、「ZK註冊中心」、「Local註冊中心」等;
推薦使用內置的 "XXL-REGISTRY" 做爲註冊中心。可前往 XXL-REGISTRY (https://github.com/xuxueli/xxl-registry ) 查看部署文檔。很是輕量級,一分鐘可完成部署工做。
更易於集羣部署、橫向擴展,搭建與學習成本更低,推薦採用該方式;
內置「ZK註冊中心」,可選組件,結構圖以下:
原理:
XXL-RPC中每一個服務在zookeeper中對應一個節點,如圖"iface name"節點,該服務的每個provider機器對應"iface name"節點下的一個子節點,如圖中"192.168.0.1:9999"、"192.168.0.2:9999"和"192.168.0.3:9999",子節點類型爲zookeeper的EPHMERAL類型,該類型節點有個特色,當機器和zookeeper集羣斷掉鏈接後節點將會被移除。consumer底層能夠從zookeeper獲取到可提供服務的provider集羣地址列表,從而能夠向其中一個機器發起RPC調用。
服務提供方新增 "/services" 服務目錄功能,可查看在線服務列表;暫時僅針對NETTY_HTTP通信方案,瀏覽器訪問地址 "{端口地址}/services" 便可。
XXL-RPC提供多中通信方案:支持 TCP 和 HTTP 兩種通信方式進行服務調用;其中 TCP 提供可選方案 NETTY ,HTTP 提供可選方案 NETTY_HTTP (新版本移除了Mina和Jetty通信方案,主推Netty;若是有須要能夠參考舊版本;);
若是須要切換XXL-RPC「通信方案」,只須要執行如下兩個步驟便可:
XXL-RPC的註冊中心,是一個可選組件,不強制依賴;支持服務註冊並動態發現;
可選擇不啓用,直接指定服務提供方機器地址通信;
選擇啓用時,原生提供多種開箱即用的註冊中心可選方案,包括:「XXL-RPC原生輕量級註冊中心」、「ZK註冊中心」、「Local註冊中心」等;
若是須要切換XXL-RPC「註冊中心」,只須要執行如下兩個步驟便可:
XXL-RPC 提供 "泛華調用" 支持,服務調用方不依賴服務方提供的API;泛化調用一般用於框架集成,好比 "網關平臺、跨語言調用、測試平臺" 等; 開啓 "泛華調用" 時服務方不須要作任何調整,僅須要調用方初始化一個泛華調用服務Reference ("XxlRpcGenericService") 便可。
「XxlRpcGenericService#invoke」 請求參數 | 說明 |
---|---|
String iface | 服務接口類名 |
String version | 服務版本 |
String method | 服務方法 |
String[] parameterTypes | 服務方法形參-類型,如 "int、java.lang.Integer、java.util.List、java.util.Map ..." |
Object[] args | 服務方法形參-數據 |
// 服務Reference初始化-註解方式示例 @XxlRpcReference private XxlRpcGenericService genericService; // 服務Reference初始化-API方式示例 XxlRpcGenericService genericService = (XxlRpcGenericService) new XxlRpcReferenceBean(……).getObject(); // 調用方示例 Object result = genericService.invoke( "com.xxl.rpc.sample.server.service.Demo2Service", null, "sum", new String[]{"int", "int"}, new Object[]{1, 2} ); // 服務方示例 public class Demo2ServiceImpl implements Demo2Service { @Override public int sum(int a, int b) { return a + b; } }
歡迎參與項目貢獻!好比提交PR修復一個bug,或者新建 Issue 討論新特性或者變動。
更多接入的公司,歡迎在 登記地址 登記,登記僅僅爲了產品推廣。
產品開源免費,而且將持續提供免費的社區技術支持。我的或企業內部可自由的接入和使用。
不管金額多少都足夠表達您這份心意,很是感謝 :) 前往捐贈