企业生产级百亿日PV高可用可拓展的RPC框架。理论上并发数量接近服务器带宽,客户端采用thrift协议,服务端支持etty和thrift的TThreadedSelectorServer半同步半异步线程模型,支持动态扩容,服务上下线,权重动态,可用性配置,泛化调用,页面流量统计,泛化调用等,支持trace跟踪等,天然接入cat支持数据大盘展示等
1:为什么要写这个RPC
市面上常见的RPC框架很多,grpc,mota,dubbo等,但是随着越来越多的元素加入,复杂的架构设计等因素似使得这些框架和sprig一样,虽然号称是轻量级,但是用起来却是让我们很蹩脚,大量的配置,繁杂的API设计,其实,我们根本用不上这些东西!!!我也算得上是在很多个互联网企业厮杀过,见过很多很多的内部RPC框架,有些优秀的设计让我非常赞赏,有一天我突然想着,为什么不对这些设计原型进行聚合归类,自己搞一套【轻量级】RPC框架呢,碍于工作原因,一直没有时间倒腾出空,十一期间工作闲暇,说搞就搞吧,落地不易,很多细节性问题,比如tcp中怎么解决大量的wait-time,如何做到thrift和etty的兼容等等大量细节的优化,希望源码对大家对认识RPC框架起到推进的作用。东西越写越多,有各种问题欢迎随时拍砖
2:为什么叫koalas
树袋熊英文翻译,希望考拉RPC给那些不太喜欢动手自己去造轮子的人提供可靠的RPC使用环境
3:技术栈
thrift0.8.0 sprig-core-4.2.5,sprig-cotext-4.2.5,sprig-beas-4.2.5 log4j,slf4j org.apache.commos(v2.0+) io.etty4 fastJso zookeeper 点评cat(V3.0.0+做数据大盘统计上报等使用,可不配置) AOP,反射代理等4:关于技术选型
序列化篇考察了很多个序列化组件,其中包括jdk原生,kryo、hessia、protoStuff,thrift,jso等,最终选择了Thrift,原因如下原生JDK序列化反序列化效率堪忧,其序列化内容太过全面kryo和hessia,jso相对来说比原生JDK强一些,但是对跨语言支持一般,所以舍弃了,最终想在protoBuf和Thrift协议里面选择一套框架,这俩框架很相通,支持跨语言,需要静态编译等等。但是protoBuf不带RPC服务,本着提供多套服务端模式(thriftrpc,etty)的情况下,最终选择了Thrift协议。IO线程模型篇原生socket可以模拟出简单的RPC框架,但是对于大规模并发,要求吞吐量的系统来说,也就算得上是一个demo级别的,所以BIO肯定是不考虑了,NIO的模型在序列化技术选型的时候已经说了,Thrift本身支持很多个io线程模型,同步,异步,半同步异步等(SimpleServer,TNoblockigServer,THsHaServer,TThreadedSelectorServer,TThreadPoolServer),其中吞吐量最高的肯定是半同步半异步的IO模TThreadedSelectorServer了,具体原因大家可自行google,这次不做多的阐述,选择好了模型之后,发现thrift简直就是神器一样的存在,再一想,对于服务端来说,IO模型怎么能少得了Netty啊,所以下决心也要支持Netty,但是很遗憾Netty目前没有对Thrift的序列化解析,拆包粘包的处理,但是有protoBuf,和http协议的封装,怎么办,自己在etty上写对thrift的支持呗,虽然工作量大了一些,但是一想etty不就是干这个事儿的嘛--!服务发现支持集群的RPC框架里面,像dubbo,或者是其他三方框架,对服务发现都进行的封装,那么自研RPC的话,服务发现就要自己来写了,那么简单小巧容易上手的zookeeper肯定是首选了。5:安装教程
考拉RPC确保精简,轻量的原则,只需要zk服务器进行服务发现(后续版本服务治理可能需要Datasource),对于zookeeper的各个环境安装教程请自行google,不在本安装教程内特意说明如果需要cat的数据大盘功能,想更方便的查看服务的调用情况,需要安装cat服务,至于cat的安装就更简单了,就是war包扔在tomcat里面运行,然后配置一些参数即可,当然你也可以不接入cat,单独的作为RPC框架来使用。CAT接入参考:https://www.oschia.et/p/cat-diapig
二:使用说明1:前期准以及依赖
mave依赖
<depedecy><groupId>koalas.rpc</groupId><artifactId>com.Koalas.rpc</artifactId><versio>Koalas-1.0-SNAPSHOT</versio></depedecy>关于私服的引用问题,记得全局文件不要把全局的依赖都代理掉,因为这么做只能从aliyu的私服上下载项目,由于koalas-rpc中的Cat依赖只在美团点评的私有仓库中存在,这么做会下载依赖失败,所以不要暴力的设置下面的代理做法。
<mirror><id>exus-aliyu</id><mirrorOf>*</mirrorOf><ame>Nexusaliyu</ame><url>https://mave.aliyu.com/exus/cotet/groups/public</url></mirror>正确的做法是将代理去掉,直接按照作者在pom.xml文件中给定的依赖仓库地址就可以了。
首先需要编写自己的thriftidl文件了,这里多说一句,在群里的小伙伴曾经说过idl文件编写不熟悉,有可能出错这里顺带说一嘴,thrift的ldl文件和写java的请求体和service几乎没有任何区别,熟能生巧,上手之后非常简单这里推荐几篇thrift的文章,有兴趣可以看一看 https://blog.csd.et/lk10207160511/article/details/50450541, https://blog.csd.et/hr1216/article/details/51306395 下面截图为测试的thrift文件
amespacejavathrift.serviceiclude'WmCreateAccoutRequest.thrift'iclude'WmCreateAccoutRespoe.thrift'serviceWmCreateAccoutService{WmCreateAccoutRespoe.WmCreateAccoutRespoegetRPC(1:WmCreateAccoutRequest.WmCreateAccoutRequestwmCreateAccoutRequest);WmCreateAccoutRespoe.WmCreateAccoutRespoekoaloasTest1(1:WmCreateAccoutRequest.WmCreateAccoutRequestwmCreateAccoutRequest);WmCreateAccoutRespoe.WmCreateAccoutRespoekoaloasTest2(1:WmCreateAccoutRequest.WmCreateAccoutRequestwmCreateAccoutRequest);WmCreateAccoutRespoe.WmCreateAccoutRespoekoaloasTest3(1:WmCreateAccoutRequest.WmCreateAccoutRequestwmCreateAccoutRequest);WmCreateAccoutRespoe.WmCreateAccoutRespoekoaloasTest4(1:WmCreateAccoutRequest.WmCreateAccoutRequestwmCreateAccoutRequest);WmCreateAccoutRespoe.WmCreateAccoutRespoekoaloasTest5(1:WmCreateAccoutRequest.WmCreateAccoutRequestwmCreateAccoutRequest);WmCreateAccoutRespoe.WmCreateAccoutRespoekoaloasTest6(1:WmCreateAccoutRequest.WmCreateAccoutRequestwmCreateAccoutRequest);WmCreateAccoutRespoe.WmCreateAccoutRespoekoaloasTest7(1:WmCreateAccoutRequest.WmCreateAccoutRequestwmCreateAccoutRequest);WmCreateAccoutRespoe.WmCreateAccoutRespoekoaloasTest8(1:WmCreateAccoutRequest.WmCreateAccoutRequestwmCreateAccoutRequest);WmCreateAccoutRespoe.WmCreateAccoutRespoekoaloasTest9(1:WmCreateAccoutRequest.WmCreateAccoutRequestwmCreateAccoutRequest);WmCreateAccoutRespoe.WmCreateAccoutRespoekoaloasTest10(1:WmCreateAccoutRequest.WmCreateAccoutRequestwmCreateAccoutRequest);WmCreateAccoutRespoe.WmCreateAccoutRespoekoaloasTest11(1:WmCreateAccoutRequest.WmCreateAccoutRequestwmCreateAccoutRequest);WmCreateAccoutRespoe.WmCreateAccoutRespoekoaloasTest12(1:WmCreateAccoutRequest.WmCreateAccoutRequestwmCreateAccoutRequest);}amespacejavathrift.domai/***测试类**/structWmCreateAccoutRequest{1:i32source,2:i32accoutType,3:i64parterId,4:i32parterType,5:strigparterName,6:i32poiFlag,}amespacejavathrift.domai/***测试类**/structWmCreateAccoutRespoe{1:i32code,2:strigmessage,}编译器需要大家去下载对应的版本widows和liux下不同的编译器,下载地址https://archive.apache.org/dist/thrift/0.8.0/ 下载0.8.0版本即可,0.8.0版本是很老的版本了,但是相对稳定,后续会把thirft版本升级。如果上面地址下载不下来或者失效,可以上作者的网盘上下载zip包,上面有wi版本和mac,liux版本的0.8.0的thrift编译器,链接: https://pa.baidu.com/s/1JpLqVbmokTOe30U_TzWw提取码:tye,编译上面三个文件thrift-gejavaWmCreateAccoutService.thrift,thrift-gejavaWmCreateAccoutRequest.thrift,thrift-gejavaWmCreateAccoutRespoe.thrift在当前目录下会生成3个java文件这三个文件分别是请求体,返回体,和服务类,就这么简单Ok作为开发者而言,所有的准备工作都结束了。下面就开始进入实际开发~
2:xml配置方式1.客户端同步调用
首先在你的xml里面配置一下引用
<?xmlversio="1.0"ecodig="UTF-8"?><beasxmls="https://www.sprigframework.org/schema/beas"xmls:xsi="https://www.w3.org/2001/XMLSchema-istace"xmls:koalas="https://www.koalas.com/schema/ch"xsi:schemaLocatio="https://www.sprigframework.org/schema/beashttps://www.sprigframework.org/schema/beas/sprig-beas-4.2.xsdhttps://www.koalas.com/schema/chhttps://www.koalas.com/schema/ch.xsd"><koalas:clietid="wmCreateAccoutService1"serviceIterface="thrift.service.WmCreateAccoutService"zkPath="127.0.0.1:2181"/></beas>首先引用koalas的自定义schema,xmls:koalas和xsi:schemaLocatio,其中serviceIterface为thrift自动生成的java类,zkPath为zk的服务地址,默认是同步调用,接下来就是在java里面的远程调用了。
packagethrift.service;importorg.apache.thrift.TExceptio;importorg.sprigframework.beas.factory.aotatio.Autowired;importorg.sprigframework.stereotype.Service;importthrift.domai.WmCreateAccoutRequest;importthrift.domai.WmCreateAccoutRespoe;@Service("testService")publicclassTestService{@AutowiredWmCreateAccoutService.IfacewmCreateAccoutService;publicvoidgetRemoteRpc()throwsTExceptio{WmCreateAccoutRequestrequest=ewWmCreateAccoutRequest();//request.setSource(10);request.setAccoutType(1);request.setParterId(1);request.setParterType(1);request.setParterName("你好");request.setPoiFlag(1);WmCreateAccoutRespoerespoe=wmCreateAccoutService.getRPC(request);System.out.pritl(respoe);}}就这么简单一个高性能的RPC框架就诞生了。WmCreateAccoutService是thrift自动生成的,作为使用者而言不需要做任何事情,只需要在sprigbea中注入xxx.Iface即可。
2.客户端异步调用
刚刚我们看了客户端的同步调用方式,下面我们一起来看看异步的使用方式,首先在你的xml里面配置一下引用
<?xmlversio="1.0"ecodig="UTF-8"?><beasxmls="https://www.sprigframework.org/schema/beas"xmls:xsi="https://www.w3.org/2001/XMLSchema-istace"xmls:koalas="https://www.koalas.com/schema/ch"xsi:schemaLocatio="https://www.sprigframework.org/schema/beashttps://www.sprigframework.org/schema/beas/sprig-beas-4.2.xsdhttps://www.koalas.com/schema/chhttps://www.koalas.com/schema/ch.xsd"><koalas:clietid="wmCreateAccoutService2"serviceIterface="thrift.service.WmCreateAccoutService"zkPath="127.0.0.1:2181"asyc="true"/></beas>和同步的区别asyc=true,代表异步使用,接下来就是在java里面的异步远程调用了
packagethrift.service;importcliet.asyc.KoalasAsycCallBack;importorg.apache.thrift.TExceptio;importorg.sprigframework.beas.factory.aotatio.Autowired;importorg.sprigframework.stereotype.Service;importthrift.domai.WmCreateAccoutRequest;importthrift.domai.WmCreateAccoutRespoe;importjava.util.cocurret.ExecutioExceptio;importjava.util.cocurret.Future;@Service("testService")publicclassTestService2{@AutowiredWmCreateAccoutService.AsycIfacewmCreateAccoutService;publicvoidgetRemoteRpc()throwsTExceptio{KoalasAsycCallBack<WmCreateAccoutRespoe,WmCreateAccoutService.AsycCliet.getRPC_call>koalasAsycCallBack=ewKoalasAsycCallBack<>();WmCreateAccoutRequestrequest=ewWmCreateAccoutRequest();request.setAccoutType(1);request.setParterId(1);request.setParterType(1);request.setParterName("你好啊");request.setPoiFlag(1);wmCreateAccoutService.getRPC(request,koalasAsycCallBack);Future<WmCreateAccoutRespoe>future=koalasAsycCallBack.getFuture();try{//togetotherthigsSystem.out.pritl(future.get());}catch(IterruptedExceptioe){e.pritStackTrace();}catch(ExecutioExceptioe){e.pritStackTrace();}}}这次调用getRpc方法不会阻塞等待server同步结果了。而是可以去干一些自己的其他事情,然后在调用future.get()来获得返回resope,当然future.get()支持最大等待时间的,超时之后会抛出TimeOutExceptio,当然这仅仅是cliet超时而已不会影响server的执行结果。
3.服务端实现
<?xmlversio="1.0"ecodig="UTF-8"?><beasxmls="https://www.sprigframework.org/schema/beas"xmls:xsi="https://www.w3.org/2001/XMLSchema-istace"xmls:cotext="https://www.sprigframework.org/schema/cotext"xmls:koalas="https://www.koalas.com/schema/ch"xsi:schemaLocatio="https://www.sprigframework.org/schema/beashttps://www.sprigframework.org/schema/beas/sprig-beas-4.2.xsdhttps://www.sprigframework.org/schema/cotexthttps://www.sprigframework.org/schema/cotext/sprig-cotext-4.2.xsdhttps://www.koalas.com/schema/chhttps://www.koalas.com/schema/ch.xsd"><koalas:serverid="WmCreateAccoutService"serviceIterface="thrift.service.WmCreateAccoutService"serviceImpl="wmCreateAccoutServiceImpl"port="8001"zkpath="127.0.0.1:2181"/></beas>服务端只需要指定暴露的端口,zk服务地址和服务端实现即可。
@ServicepublicclassWmCreateAccoutServiceImplimplemetsWmCreateAccoutService.Iface{@OverridepublicWmCreateAccoutRespoegetRPC(WmCreateAccoutRequestwmCreateAccoutRequest)throwsTExceptio{WmCreateAccoutRespoewmCreateAccoutRespoe=ewWmCreateAccoutRespoe();wmCreateAccoutRespoe.setCode(1);wmCreateAccoutRespoe.setMessage("你好");if(ewRadom().extIt(5)>100){throwewRutimeExceptio("测试错误");}System.out.pritl("getRPCstart...."+wmCreateAccoutRequest+"------"+atomicIteger.icremetAdGet());returwmCreateAccoutRespoe;}}只需要实现xxxx.Iface即可
3:注解配置方式有的小伙伴会觉得配置xml有点麻烦,koalas-rpc也提供了纯注解的使用方式
1.客户端调用
xml中的配置
<?xmlversio="1.0"ecodig="UTF-8"?><beasxmls="https://www.sprigframework.org/schema/beas"xmls:xsi="https://www.w3.org/2001/XMLSchema-istace"xmls:koalas="https://www.koalas.com/schema/ch"xsi:schemaLocatio="https://www.sprigframework.org/schema/beashttps://www.sprigframework.org/schema/beas/sprig-beas-4.2.xsdhttps://www.koalas.com/schema/chhttps://www.koalas.com/schema/ch.xsd"><koalas:aotatiopackage="thrift.aotatio.cliet.impl"/></beas>一个扫描标签就行了,如果你在sprigbea里想通过调用rpc远程服务,那么扫描一下就行了
java中使用
@Service("testServiceSyc")publicclassTestServiceSyc{@KoalasCliet(zkPath="127.0.0.1:2181",readTimeout=5000*1000)WmCreateAccoutService.IfacewmCreateAccoutService;publicvoidgetRemoteRpc()throwsTExceptio{WmCreateAccoutRequestrequest=ewWmCreateAccoutRequest();//request.setSource(10);request.setAccoutType(1);request.setParterId(1);request.setParterType(1);request.setParterName("你好啊-我是注解实现的");request.setPoiFlag(1);WmCreateAccoutRespoerespoe=wmCreateAccoutService.getRPC(request);System.out.pritl(respoe);}}只需要在你想远程调用的类上加一个@KoalasCliet注解就可以了,远程调用就这么简单,当然异步使用方式也类似
@Service("testServiceAsyc")publicclassTestServiceAsyc{@KoalasCliet(zkPath="127.0.0.1:2181",readTimeout=5000*1000)WmCreateAccoutService.AsycIfacewmCreateAccoutService;publicvoidgetRemoteRpc()throwsTExceptio{KoalasAsycCallBack<WmCreateAccoutRespoe,WmCreateAccoutService.AsycCliet.getRPC_call>koalasAsycCallBack=ewKoalasAsycCallBack<>();WmCreateAccoutRequestrequest=ewWmCreateAccoutRequest();//request.setSource(10);request.setAccoutType(1);request.setParterId(1);request.setParterType(1);request.setParterName("你好啊-我是注解实现的");request.setPoiFlag(1);wmCreateAccoutService.getRPC(request,koalasAsycCallBack);Future<WmCreateAccoutRespoe>future=koalasAsycCallBack.getFuture();try{System.out.pritl(future.get());}catch(IterruptedExceptioe){e.pritStackTrace();}catch(ExecutioExceptioe){e.pritStackTrace();}}}注意和同步调用不同的是自定义注解注入的接口是xxxx.AsycIface,同步是xxxx.Iface。KoalasAsycCallBack回调使用方式和上面的xml一样。有一点需要说明
<koalas:aotatiopackage="thrift.aotatio.cliet.impl"/>如果package属性设置为空,那么所有的@KoalasCliet都会生效,也就是说所有在sprigbea中的自定义注解@KoalasCliet都会自动注入。这里说另外一种用法
privateWmCreateAccoutService.IfacewmCreateAccoutService;@KoalasCliet(zkPath="127.0.0.1:2181",readTimeout=5000*1000)publicvoidsetWmCreateAccoutService(WmCreateAccoutService.IfacewmCreateAccoutService){this.wmCreateAccoutService=wmCreateAccoutService;}直接注入方法的方式也是可以的。
2.服务端实现
xml中的配置
<?xmlversio="1.0"ecodig="UTF-8"?><beasxmls="https://www.sprigframework.org/schema/beas"xmls:xsi="https://www.w3.org/2001/XMLSchema-istace"xmls:koalas="https://www.koalas.com/schema/ch"xsi:schemaLocatio="https://www.sprigframework.org/schema/beashttps://www.sprigframework.org/schema/beas/sprig-beas-4.2.xsdhttps://www.koalas.com/schema/chhttps://www.koalas.com/schema/ch.xsd"><koalas:aotatiopackage="thrift.aotatio.server.impl"/></beas>配置和cliet中一样只需要配置一个自定义标签即可,java中的使用方式如下:
packagethrift.aotatio.server.impl;importaotatio.KoalasServer;importorg.apache.thrift.TExceptio;importthrift.domai.WmCreateAccoutRequest;importthrift.domai.WmCreateAccoutRespoe;importthrift.service.WmCreateAccoutService;importjava.util.Radom;importjava.util.cocurret.atomic.AtomicIteger;@KoalasServer(port=8801,zkpath="127.0.0.1:2181")publicclassWmCreateAccoutServiceNettyImplimplemetsWmCreateAccoutService.Iface{privateAtomicItegeratomicIteger=ewAtomicIteger(0);@OverridepublicWmCreateAccoutRespoegetRPC(WmCreateAccoutRequestwmCreateAccoutRequest)throwsTExceptio{WmCreateAccoutRespoewmCreateAccoutRespoe=ewWmCreateAccoutRespoe();wmCreateAccoutRespoe.setCode(1);wmCreateAccoutRespoe.setMessage("你好啊");if(ewRadom().extIt(5)>100){try{Thread.sleep(5000);}catch(IterruptedExceptioe){e.pritStackTrace();}}System.out.pritl("getRPCstart...."+wmCreateAccoutRequest+"------"+atomicIteger.icremetAdGet());returwmCreateAccoutRespoe;}}这样服务实现就会主从注册到zookeeper中提供给cliet端使用了。值得说明的是被扫描到并且类上有@KoalasServer的类会被加载到sprig上下文中,可以当成一个普通的sprigbea来处理,还有一点如果你不指定package,配置成如下情况
<koalas:aotatiopackage=""/>这样配置会以sprig的bea为基础实现,那么使用方式需要改成
packagethrift.aotatio.server.impl;importaotatio.KoalasServer;importorg.apache.thrift.TExceptio;importthrift.domai.WmCreateAccoutRequest;importthrift.domai.WmCreateAccoutRespoe;importthrift.service.WmCreateAccoutService;importjava.util.Radom;importjava.util.cocurret.atomic.AtomicIteger;@KoalasServer(port=8801,zkpath="127.0.0.1:2181")@ServicepublicclassWmCreateAccoutServiceNettyImplimplemetsWmCreateAccoutService.Iface{privateAtomicItegeratomicIteger=ewAtomicIteger(0);@OverridepublicWmCreateAccoutRespoegetRPC(WmCreateAccoutRequestwmCreateAccoutRequest)throwsTExceptio{WmCreateAccoutRespoewmCreateAccoutRespoe=ewWmCreateAccoutRespoe();wmCreateAccoutRespoe.setCode(1);wmCreateAccoutRespoe.setMessage("你好啊");if(ewRadom().extIt(5)>100){try{Thread.sleep(5000);}catch(IterruptedExceptioe){e.pritStackTrace();}}System.out.pritl("getRPCstart...."+wmCreateAccoutRequest+"------"+atomicIteger.icremetAdGet());returwmCreateAccoutRespoe;}}就这么简单即可。
3.泛化调用
为什么需要泛化调用?1:有一个通用压测平台,想去压测不同的server。那么现在就有一个问题了,不可能让压测平台服务端去依赖所有的下游服务,这样依赖会很繁杂,这时候如果说只配置serviceName,request模型和request请求jso就可以进行远程调用,那么将大大的减少头疼的依赖。2:假设php同事对java代码不熟悉,不可能让他们去依赖sprig,一共一套简单的api来使用是很有必要的。3:上游服务不想依赖下游服务的数据模型。
对于泛化调用来说,dubbo已经提供,soft-rpc也有提供。当然koalas-rpc也不会例外,并且支持xml,注解和javaapi的使用方式。下面几个例子来说明一下使用方式。更多demo去源码中查看,作者已经写好,开箱即用。
xml使用方式
<koalas:clietid="wmCreateAccoutService3"serviceIterface="thrift.service.WmCreateAccoutService"zkPath="127.0.0.1:2181"geeric="true"readTimeout="50000000"/>@Autowired@Qualifier("wmCreateAccoutService3")GeericService.IfacewmGeericService;publicvoidgetGeericRpc()throwsTExceptio{GeericRequestrequest=ewGeericRequest();request.setMethodName("getRPC");request.setClassType(ewArrayList<Strig>(){{add("thrift.domai.WmCreateAccoutRequest");}});request.setRequestObj(ewArrayList<Strig>(){{add("{\"accoutType\":1,\"parterId\":1,\"parterName\":\"你好\",\"parterType\":1,\"poiFlag\":1,\"source\":0}");}});Strigstr=wmGeericService.ivoke(request);System.out.pritl(str);}简单说明一下,GeericService.Iface是通用服务,有三个参数,第一个是方法名称,第二个是请求体类型集合,第三个是请求体内容。直接调用即可,返回值是server端的jso类型,使用jso工具为阿里巴巴的Fast-jso
注解使用方式
@KoalasCliet(zkPath="127.0.0.1:2181",readTimeout=5000*1000,geericService="thrift.service.WmCreateAccoutService")GeericService.IfacegeericService;publicvoidgetGeericRemoteRpc()throwsTExceptio{GeericRequestrequest=ewGeericRequest();request.setMethodName("getRPC");request.setClassType(ewArrayList<Strig>(){{add("thrift.domai.WmCreateAccoutRequest");}});request.setRequestObj(ewArrayList<Strig>(){{add("{\"accoutType\":1,\"parterId\":1,\"parterName\":\"你好\",\"parterType\":1,\"poiFlag\":1,\"setAccoutType\":true,\"setParterId\":true,\"setParterName\":true,\"setParterType\":true,\"setPoiFlag\":true,\"setSource\":false,\"source\":0}");}});Strigstr=geericService.ivoke(request);System.out.pritl(str);}唯一区别的是注解要指定geericService,当geericService不为空时,默认开启泛化调用当然,javaapi方式也是支持的。
KoalasClietProxykoalasClietProxy=ewKoalasClietProxy();koalasClietProxy.setServiceIterface("thrift.service.WmCreateAccoutService");koalasClietProxy.setZkPath("127.0.0.1:2181");koalasClietProxy.setGeeric(true);koalasClietProxy.setReadTimeout(50000000);koalasClietProxy.afterPropertiesSet();GeericService.IfacegeericService=(GeericService.Iface)koalasClietProxy.getObject();GeericRequestrequest=ewGeericRequest();request.setMethodName("getRPC");request.setClassType(ewArrayList<Strig>(){{add("thrift.domai.WmCreateAccoutRequest");}});request.setRequestObj(ewArrayList<Strig>(){{add("{\"accoutType\":1,\"parterId\":1,\"parterName\":\"你好\",\"parterType\":1,\"poiFlag\":1,\"setAccoutType\":true,\"setParterId\":true,\"setParterName\":true,\"setParterType\":true,\"setPoiFlag\":true,\"setSource\":false,\"source\":0}");}});Strigstr=geericService.ivoke(request);System.out.pritl(str);koalasClietProxy.destroy();特别注意的是KoalasClietProxy对象非常非常重,一定要在服务关闭的时候执行koalasClietProxy.destroy();方法,并且需要带应用程序中缓存该对象,千万不要每次使用都要创建,这样会极大的浪费资源,每个服务对应一个KoalasClietProxy,同步和异步也是不同的对象,这些使用者需要注意。








评论