当前位置:网站首页 > Java教程 > 正文

thrift教程 java



如果有homebrew的话,直接执行以下命令即可,brew会处理相关依赖(https://thrift.apache.org/docs/install/)。

 

或者可以从源码安装。
下载tar包 https://thrift.apache.org/download
参考 https://thrift.apache.org/docs/BuildingFromSource

先写一个例子,目录结构如下:

 

pom.xml中添加以下依赖:

 

thrift目录下创建两个thrift文件:

Common.thrift

 

ShopService.thrift

 

Thrift提供了多个语言的生成器实现,按照thrift文件生成java类,生成代码命令的用法如下:

 

其中即recursive,如果在文件中通过include关键字引用了其他文件,选项可以一并生成被引用的文件。

例如上面ShopService.thrift中的:

 

默认情况下,代码会在gen-<language>目录下生成,生成目录可以通过指定。

生成后再拷贝有点麻烦,直接生成到代码目录下,在工程目录下执行以下命令:

 

执行后src/main/java/目录下生成me/kavlez/thrift/service/目录,以及4个java文件。

在service目录下创建impl,提供接口实现:

 

构建Server,也就是为Server指定Transparent、Protocol、Processor:

 

相应地,构建Client:

 

依次运行Server和Client,输出正常。

提供服务的第一步是用IDL编写Thrift文件,IDL几乎可以描述接口所需的所有元素,接口定义中包括以下内容:

每个thrift文件都在自己的命名空间中,多个thrift文件可以用同一个命名空间作为标识,并指定要使用的语言的generator。

例如:

 
 

类型说明 bool 布尔类型 i8 (byte) 8-bit 有符号整型,对应java的byte i16 16-bit 有符号整型,对应java的short i32 32-bit 有符号整型,对应java的int i64 64-bit 有符号整型,对应java的long double 64-bit 浮点类型,对应java的double string 字符串 binary Blob (byte array)

用于定义一个对象类型。

字段默认为optional,可以声明required。
字段可以设置默认值。
结构体之间可以互相引用。
0.9.2开始可以引用自身。

 
 

值是可选项,枚举不能嵌套;基本上就是K、V的形式,不能描述太复杂的枚举类。

 
 

可以自定义常量,像Map、List这样的复杂结构可以用json表示。

 
 

类型说明 map<t1,t2> Map from one type to another list<t1> Ordered list of one type set<t1> Set of unique elements of one type

语法上和struct相似,生成后的代码,不同语言各有各的实现方式。

 
 

一个函数集合,语法和java定义接口的语法类似,下面是一些例子。

 
 

用Thrift构建服务和客户端,架构如下:

 

生成的接口类中大致包括三样,分别是Iface、Client、Processor。
另外还有Server、Transport、Protocol。

不如说Transport是多种IO的抽象,其不仅限于网络IO。

比如,基础的TIOStreamTransport,以及其两个子类,TSocket和TZlibTransport。

TSocket在上面的例子中作为TBinaryProtocol依赖的transport类型,与Server的TServerSocket进行通信。

但后者是封装了InflaterInputStream和DeflaterOutputStream,其InputStream并不要求是SocketInputStream。

从开发角度来讲,如果将一个TMemoryBuffer对象传入Protocol,并以此创建某个service对应的Client,再调用相应接口。

整个过程在代码上并没有什么限制,只是运行时抛出org.apache.thrift.TApplicationException。

protocol依赖transport,决定双方以什么协议通信,同时也是通信内容的载体。

org.apache.thrift.protocol.TProtocol中的方法声明里,一系列readXX和writeXX,在具体实现中通常都是通过transport来完成。

以TJSONProtocol为例,其实现的TProtocol的所有write方法都是以几个私有的write方法组织起来。

比如,writeI32和writeI64都是通过私有方法writeJSONInteger,而writeJSONInteger则是由实例化时传入的trasnport进行write。

Server通过Processor执行业务逻辑代码,文件中描述的每个函数作为ProcessFunction子类进行实例化,放入Processor的processMap中。

  • 从protocol读入请求参数,构建参数对象;
  • 传入参数,本地执行业务方法。假设方法名为"getItems",调用结果则为getItems_success;
  • 将结果写入protocol,调用protocol.writeXX;

 

在send_queryShopInfo,构建该函数对应的xx_args对象,将其写入oprot,并通过oprot.tranport进行flush;

相应地,recv_queryShopInfo就是从iport中读取函数的返回值,构建该函数对应的queryShopInfo_result对象。

将Transport、Protocol和Processor集合在一起就是一个完整的Server,父类TServer提供了唯一的抽象方法——serve()。

以TSimpleServer为例,serve中通过java.lang.ServerSocket的accept获取client Socket并转为client Transport,以此获取相应的Processor、创建相应的inputTransport、outputTransport和iProt、oProt。

(p.s. 默认的TProcessorFactory没有子类,其getProcessor(Transport)和并没有通过transport来获取processor。可以用来扩展,比如用一个server提供多版本服务之类的。)

剩下的工作由Processor进行处理,从iPort读入请求信息并构造TMessage,找到相应的ProcessFunction并执行其process方法,这个在上面说过。

Thrift为TServer提供了3种实现:

  • TSimpleServer: 单线程ServerSocket实现,仅用于测试;
  • TThreadPoolServer: 封装了ThreadPoolExecutor,用内部类WorkerProcess表示单个请求,通过每个WorkerProcess对象的transport获取相应的Processor和Protocol,调用业务代码并返回;
  • AbstractNonblockingServer: 非阻塞server抽象类,其serve()方法即整个过程的skeleton,serve()中调用的方法交给其子类提供具体实现。
     
      

AbstractNonblockingServer的3个子类,分别为:

  • TNonblockingServer: 实现父类的startThreads(),启动selector线程(也就是SelectAcceptThread,父类声明了protected final Selector selector),开始轮询SelectedKeys,检查状态并进行相应处理:
     
      

    另外,使用TNonblockingServer时transport必须为TFramedTransport,以此保证能正确读取单次方法调用。

  • THsHaServer: "HsHa",即"Half-Sync/Half-Async",是TNonblockingServer的子类。

    工作流程和TNonblockingServer相似,主要区别在与handleRead()
    handleRead中完成读取后,另外一项重要的工作就是requestInvoke(buffer),也就是执行processor.process(iProt,oProt)。

    线程池参数的默认值如下:

     
      
  • TThreadedSelectorServer: 进一步加强HsHaServer,用一个AcceptThread接收所有连接请求,并担任负载均衡的角色。

最后,把之前的例子修改一下,看看效果。

AbstractTServerHolder.java

 

ThreadedSelectorServerHolder.java

 

Launcher.java

 

  • 上一篇: java 图像 教程
  • 下一篇: java教程字符编码
  • 版权声明


    相关文章:

  • java 图像 教程2025-03-10 15:26:06
  • java26集教程2025-03-10 15:26:06
  • java报表导出教程2025-03-10 15:26:06
  • java file教程2025-03-10 15:26:06
  • java299教程2025-03-10 15:26:06
  • java教程字符编码2025-03-10 15:26:06
  • java快速教程 vamei pdf2025-03-10 15:26:06
  • java教程课件2025-03-10 15:26:06
  • java myeclipse 教程2025-03-10 15:26:06
  • java鼠标控制教程2025-03-10 15:26:06