java開源項目jremoting

 

https://github.com/jremoting/jremotingjava

jremoting是一個相似dubbo的rpc服務治理框架,而且能夠與dubbo相互調用。jremoting的實現是參考了dubbo的許多概念,可是代碼相比 dubbo更簡潔,模型也更精簡更靈活。底層nio通訊是基於netty 4.x實現的。註冊中心同開源版本的dubbo同樣基於zookeeper實現。git

主要功能包括github

  1. 透明方式的rpc調用,支持consumer端異步調用與provider的異步實現
  2. 服務的動態發現
  3. 負載均衡+ failover
  4. 動態路由
  5. 動態分組
  6. 服務限流(開發中)

如何使用: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>
相關文章
相關標籤/搜索