https://github.com/jremoting/jremotingjava
jremoting是一個相似dubbo的rpc服務治理框架,而且能夠與dubbo相互調用。jremoting的實現是參考了dubbo的許多概念,可是代碼相比 dubbo更簡潔,模型也更精簡更靈活。底層nio通訊是基於netty 4.x實現的。註冊中心同開源版本的dubbo同樣基於zookeeper實現。git
主要功能包括github
如何使用:spring
服務提供方(provider)提供的服務接口定義,並將實現經過spring定義發佈到註冊中心(registry)json
public interface HelloService { String hello(String name); } public class HelloServiceImpl implements HelloService { @Override public String hello(String name) { return "hello,"+ name; } } public class TestProvider { public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("server-context.xml"); System.in.read(); context.close(); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <import resource="classpath:jremoting-context.xml"/> <bean id="helloServiceProvider" class="com.github.jremoting.spring.JRemotingProviderBean" init-method="start"> <constructor-arg name="interfaceName" value="com.github.jremoting.example.HelloService" /> <constructor-arg name="version" value="1.0" /> <constructor-arg name="target" ref="helloService" /> <constructor-arg name="rpcServer" ref="rpcServer" /> </bean> <bean id="helloService" class="com.github.jremoting.example.HelloServiceImpl"></bean> </beans>
服務消費方(consumer)只依賴接口(HelloService)既能夠經過rpc的方式調用遠程provider的實現app
/*consumer端本身定義異步版本接口*/ public interface AsyncHelloService { /** * 異步方法的簽名規則是同步方法名加前綴 $, 返回結果爲ListenableFuture */ ListenableFuture<String> $hello(String name); } public class TestClient { public static void main(String[] args) throws IOException, InterruptedException, ExecutionException { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("client-context.xml"); HelloService helloService = context.getBean(HelloService.class); //同步調用 String result = helloService.hello("jremoting"); System.out.println(result); //異步調用 AsyncHelloService asyncHelloService = (AsyncHelloService)helloService; ListenableFuture<String> future = asyncHelloService.$hello("jremoting async invoke!"); System.out.println(future.get()); //異步listener方式調用,注意operationComplete是在jremoting-context.xml中配置的專門executor上執行的。也能夠本身指定executor future = asyncHelloService.$hello("jremoting async use future listener!"); future.addListener(new FutureListener<String>() { @Override public void operationComplete(ListenableFuture<String> future) { if(future.isSuccess()) { System.out.println(future.result()); } } }); //若是consumer端,不想依賴provider定義的接口,也能夠直接調用遠程方法,不過要把複雜對象都用map來代替,返回結果也同樣 RpcClient rpcClient = context.getBean(RpcClient.class); ServiceConsumer consumer = new ServiceConsumer("com.github.jremoting.example.HelloService", "1.0", rpcClient).start(); Object obj = consumer.invoke("hello", new String[]{java.lang.String.class.getName()}, new Object[]{"generic invoke!"}); System.out.println(obj); //關閉容器退出 System.in.read(); context.close(); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <import resource="classpath:jremoting-context.xml"/> <bean id="helloService" class="com.github.jremoting.spring.JRemotingConsumerBean" init-method="start"> <constructor-arg name="interfaceName" value="com.github.jremoting.example.HelloService" /> <constructor-arg name="version" value="1.0" /> <constructor-arg name="rpcClient" ref="rpcClient" /> <property name="asyncInterfaceName" value="com.github.jremoting.example.AsyncHelloService"></property> </bean> </beans>
jremoting註冊中心基於zookeeper實現的,測試hello world例子須要安裝zookeeper. jremoting-context.xml中配置了jremoting運行 定義的bean對象 以及zookeeper鏈接地址,已經provider端鏈接的監聽端口。另外還有jremoting的protocal,serializer,executor,invokefilter,registrywrapper等對象定義。用戶能夠本身定義每一個組件的實現bean負載均衡
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 定義serializer,默認提供json與hessian序列化 --> <bean id="jsonSerializer" class="com.github.jremoting.serializer.JsonSerializer" ></bean> <bean id="hessianSerializer" class="com.github.jremoting.serializer.HessianSerializer" ></bean> <!-- 定義服務註冊中心,底層採用zookeeper來實現,服務的動態發現與配置的動態推送。除了CacheRegistryWrapper,與ZookeeperRegistry爲必選,其餘實現分組,路由,權重爲可選 --> <bean id="registry" class="com.github.jremoting.route.RouteRegistryWrapper"> <constructor-arg> <bean class="com.github.jremoting.group.GroupRegistryWrapper"> <constructor-arg> <bean class="com.github.jremoting.registry.CacheRegistryWrapper"> <constructor-arg> <bean class="com.github.jremoting.registry.ZookeeperRegistry"> <constructor-arg name="zookeeperConnectionString" value="127.0.0.1:2181" /> </bean> </constructor-arg> </bean> </constructor-arg> </bean> </constructor-arg> </bean> <!-- 定義協議 ,並給協議關聯序列化與註冊中心--> <bean id="jremotingProtocal" class="com.github.jremoting.protocal.JRemotingProtocal"> <constructor-arg name="registry" ref="registry" /> <constructor-arg name="serializers"> <array> <ref bean="jsonSerializer"/> <ref bean="hessianSerializer"/> </array> </constructor-arg> </bean> <!-- 定義io線程池 底層netty處理io事件與ChannelHandler的線程池 --> <bean id="eventExecutor" class="com.github.jremoting.transport.EventExecutor"></bean> <!-- 定義用戶線程池,可用於consumer端的異步回調處理,或者provider端的服務方法處理--> <bean id="executor" class="com.github.jremoting.util.concurrent.Executors" factory-method="newExecutor"> <constructor-arg name="corePoolSize" value="3"></constructor-arg> <constructor-arg name="maxPoolSize" value="20"></constructor-arg> <constructor-arg name="queueSize" value="20"></constructor-arg> </bean> <!-- 定義rpc client對象,用戶定製consumer端須要的各類組件,包括協議,默認序列化方式,異步調用線程池,調用攔截器 --> <bean id="rpcClient" class="com.github.jremoting.transport.DefaultRpcClient"> <constructor-arg name="protocal" ref="jremotingProtocal" /> <constructor-arg name="defaultSerializer" ref="hessianSerializer" /> <constructor-arg name="eventExecutor" ref="eventExecutor" /> <constructor-arg name="asyncInvokeExecutor" ref="executor" /> <constructor-arg name="invokeFilters"> <list> <!-- 實現重試功能的攔截器 --> <bean class="com.github.jremoting.invoke.RetryInvokeFilter" /> <!-- 實現軟負載與failover的攔截器 , 負載方式爲在可用provider間隨機調用--> <bean class="com.github.jremoting.invoke.ClusterInvokeFilter" /> </list> </constructor-arg> </bean> <!-- 定義rpc server對象,定製server端的各類組件,包括協議,執行provider方法的線程池,調用攔截器 --> <bean id="rpcServer" class="com.github.jremoting.transport.DefaultRpcServer"> <constructor-arg name="eventExecutor" ref="eventExecutor" /> <constructor-arg name="serviceExecutor" ref="executor" /> <constructor-arg name="protocal" ref="jremotingProtocal" /> <constructor-arg name="port" value="8687" /> <constructor-arg name="invokeFilters"> <list></list> </constructor-arg> </bean> <!-- 監聽spring容器的關閉事件,同時關閉jremoting須要關閉的資源,包括監聽,註冊中心,線程池 --> <bean id="jremmotingLifeCycle" class="com.github.jremoting.spring.JRemotingLifeCycleBean"> <property name="rpcClients"> <list> <ref bean="rpcClient"/> </list> </property> <property name="rpcServers"> <list> <ref bean="rpcServer"/> </list> </property> </bean> </beans>