ITKeyword - 技术文章推荐分享

首页 > (十四) Thunder分布式RPC框架

(十四) Thunder分布式RPC框架

相关推荐:(一) Thunder分布式RPC框架

Thunder(QQ 群 471164539)发布在淘宝代码基地 http://code.taobao.org/p/Thunder/1. 概要1.1 Thunder是基于Netty + Hessian + Kafka + ActiveMQ + Tibco + Zookeeper(Curator Framework) + Redis + FST + Spring + Spring Web MVC分布式RPC调用框

Thunder(QQ 群 471164539)发布在淘宝代码基地 http://code.taobao.org/p/Thunder/ 调用链根据单端和多端分成两种方式单端链式调用多端跨进程调用链单端链式调用基于Jdeferred框架,实现单端的链式调用,支持异步链式Callback调用。它的优点是:业务端不需要实现Callback业务端原本需要通过Callback串联起来的若干个异步调用,直接由链式调用代理业务端任何异常抛出,都将终止下一次的调用,并被捕获链式调用的代码,无论是放在主线程/子线程执行,都不会阻塞当前线程的其它代码执行链式调用支持多个链式调用的并发,哪怕某个链式环节所调用的接口,方法,参数等都是一样的,它也不会走岔,即从哪个链式出来请求,会准确返回到哪个链式去链式调用通过泛型化,明确无误的告诉业务端开发人员,入参和出参类型,如果没设置对,直接从代码编译上出错,即Eclipse等编辑器自动会报错链式调用不需要业务端手工埋点,以内置的全局唯一的MessageId作为回调方法准确寻址的依据下面是链式调用示例代码,我们可以看出,链式调用过程是service1.do(int value),回调后,调用service2.do(String value),回调后,调用service3.do(Long value),最后链式调用结束打印,如果有环节发生异常,就会打印异常,终止链式调用

final int param = 0;

PromiseExecutor promiseExecutor = new PromiseExecutor();

promiseExecutor.then(new PromisePipe<Void, String> {

@Override

public void onResult(Void origin) {

service1.do(param);

}

}).then(new PromisePipe<String, Long>() {

@Override

public void onResult(String result) {

service2.do(result);

}

}).then(new PromisePipe<Long, Boolean>() {

@Override

public void onResult(Long result) {

service3.do(result);

}

}).done(new PromiseDone<Boolean>() {

@Override

public void onDone(Boolean result) {

LOG.info("链式调用完成,最终值={}", result);

}

}).fail(new PromiseFail() {

@Override

public void onFail(Exception exception) {

LOG.error("链式调用异常", exception);

}

});

promiseExecutor.execute();1. PromiseExecutor基于Jdeferred框架的DeferredObject,Thunder框架封装成PromiseExecutor,它是链式调用的发起者,它的用法是:发起调用 - promiseExecutor.execute()链式调用过程 - promiseExecutor.then(...).then(...)....done(...).fail(...)then方法可以无数个done和fail的方法必须是一个,也可以没有,但强烈建议加上如果需要处理最终的结果,必须加done如果需要处理链式调用中的异常,必须加fail2. PromisePipe基于Jdeferred框架的DonePipe,Thunder框架封装成PromisePipe,它是链式调用的流程控制和参数传递的通道,通过泛型化入参(T)和出参(R)来实例化,如果PromisePipe在调用过程中有异常抛出,将终止下一个链式调用,直接把异常交给PromiseFail,并被捕捉到。如果整个链式调用如期完成,那么将最终数据交给PromiseDone进行处理入参(T) - 上一个链式调用的回调值类型,第一个链式调用的入参为Void。例如上例中service2.do(result)所在的PromisePipi,它的入参类型是String出参(R) - 下一个链式调用的参数值类型。例如上例中service2.do(result)所在的PromisePipi,它的出参类型是Long管道处理 - 必须实现onResult(T result)方法,在这里经过一些业务处理,再去调用下一个业务接口。例如上例中service2.do(result)所在的PromisePipi,它的入参类型是String,所以管道处理方法肯定也是onResult(String result)3. PromiseDone基于Jdeferred框架的DoneCallback,Thunder框架封装成PromiseDone,它是链式调用接收最终数据的通道,通过泛型化入参(T)来实例化入参(T) - 上一个链式调用的回调值类型管道处理 - 必须实现onDone(T result)方法4. PromiseFail基于Jdeferred的FailCallback,Thunder框架封装成PromiseFail,它可以捕捉链式调用任何中间环节的异常管道处理 - 必须实现onFail(Exception exception)方法5. Promise回调定义只需要在定义callback的时候,写成callback="promise"<thunder:reference id="myInterface" interface="com.nepxion.thunder.service.MyInterface">

<thunder:method method="myMethod" async="true" callback="promise"/></thunder:reference> 6. Promise回调异常的捕捉通过PromiseFail的方式,捕捉业务异常通过EventBus的方式,捕捉超时异常(场景一般是调用端发出请求后,服务端接收到后死机,那么Promise长期回不来,就根据调用端定义的超时时间,通过异步时间通知捕捉到异常)具体示例见Thunder/ trunk / nepxion-thunder / src / test / java / com / nepxion / thunder / traceAEnd4执行的是两次Callback调用,采用Promise框架实现多端跨进程调用链框架支持跨进程调用链。它和单端链式调用的区别是:多端跨进程调用链更偏向服务治理的范畴,通过外部拓扑图,表格等界面显示方式,让业务端更容易的看到全局调用过程单端链式调用则偏向框架友好性的范畴,让业务端使用更方面它和单端链式调用的关系是:多端跨进程调用链和单端链式调用可以同时使用单端链式调用的路由分析,也可以通过多端跨进程调用链的方式来实现它的优点是:业务端可以轻易的串联起位于不同服务器上的调用业务端根据全局TraceId寻找出调用链路径,异常分析它的缺点是:业务端需要自己手工埋点,通过API的方式,例如xxxService.do(String traceId, .....)。对于业务端来说,这个traceId是全局唯一的(如果不设置,默认取第一个参数),例如电商系统可以采用订单号,支付系统可以采用交易号参考下图,它的调用过程是:A,B,C是同一个服务器的不同进程,也可以是不同服务器的进程A先发请求(同步或者异步)到BB收到A的请求后,再发送请求(同步或者异步)到CC收到B的请求后,进行处理,发送响应到BB收到C的响应后,进行处理,发送响应到AA收到B的响应后,进行处理,结束 跨进程调用链的实现思路是每一个进程必须服务端和调用端为一

相关推荐:(九) Thunder分布式RPC框架

Thunder(QQ 群 471164539)发布在淘宝代码基地 http://code.taobao.org/p/Thunder/1. 介绍治理中心是基于Nepxion Swing Repository组件,Java Desktop版的服务治理系统,计划用基于Ebay Jetstream框架做个Web版。它的主要功能包括1.1 登录需要填入

体,即A向B发送请求的时候,A是调用端,B是服务端,B向C发送请求的时候,B是调用端,C是服务端。同理,C向B发送响应(其实也是请求,只不过以请求的方式包装了响应结果)的时候,C是调用端,B是服务端。这就要求,在一个业务应用的Spring配置里,必须同时配置服务端和调用端,例如如下:bInterface必须注入aInterface和cInterface的引用,通过业务层面去控制调用(这个很简单)<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xmlns:thunder="http://www.nepxion.com/schema/thunder"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd

http://www.nepxion.com/schema/thunder http://www.nepxion.com/schema/thunder/thunder-1.0.xsd">

<thunder:application id="application" application="Audit" group="POA_EA_INF" cluster="BCluster" port="2000"/>

<thunder:registry id="registry" type="zookeeper" config="remote"/>

<thunder:protocol id="protocol" type="netty"/>

<thunder:strategy id="strategy" loadbalance="roundRobin"/>

<thunder:monitor id="monitor" type="logService,redisService"/>

<thunder:service id="bInterface1" interface="com.nepxion.thunder.trace.service.BInterface1" ref="bInterface1Impl"/>

<bean name="bInterface1Impl" class="com.nepxion.thunder.trace.service.BInterface1Impl">

<property name="aInterface" ref="aInterface"/>

<property name="cInterface" ref="cInterface"/>

</bean>

<thunder:service id="bInterface2" interface="com.nepxion.thunder.trace.service.BInterface2" ref="bInterface2Impl"/>

<bean name="bInterface2Impl" class="com.nepxion.thunder.trace.service.BInterface2Impl">

<property name="aInterface" ref="aInterface"/>

</bean>

<thunder:reference id="aInterface" interface="com.nepxion.thunder.trace.service.AInterface">

<thunder:method method="asyncToA" async="true"/>

</thunder:reference>

<thunder:reference id="cInterface" interface="com.nepxion.thunder.trace.service.CInterface">

<thunder:method method="asyncToC" async="true"/>

<thunder:method method="syncToC" async="false"/>

</thunder:reference>

<bean id="eventInterceptor" class="com.nepxion.thunder.trace.service.ServiceEventInterceptor"/></beans>具体示例见Thunder/ trunk / nepxion-thunder / src / test / java / com / nepxion / thunder / trace该示例主要是为了模拟调用链,运行CEnd1和CEnd2会启动C集群服务器,运行BEnd1和BEnd2会启动B集群服务器。 集群下的若干服务器将会自行负载均衡调用。其中AEnd1执行的全异步调用路径,AEnd2和AEnd1属于一个集群服务器,可以代替AEnd1接收消 息;AEnd3执行的是全同步调用路径;AEnd5执行的是先异步后同步的调用路径

相关推荐:(十五) Thunder分布式RPC框架

Thunder(QQ 群 471164539)发布在淘宝代码基地 http://code.taobao.org/p/Thunder/框架支持两种方式的序列化,Java对象和字节数组的序列化和反序列化,Java对象和Json字符串的转换1)binary - Java实体类和字节数组的序列化/反序列化2)compression -

Thunder(QQ 群 471164539)发布在淘宝代码基地 http://code.taobao.org/p/Thunder/?调用链根据单端和多端分成两种方式单端链式调用多端跨进程调用链单端链式调用基于Jdeferred框架...

------分隔线----------------------------