Thrift RPC实战.初次体验Thrift

Posted 程序员小阳的代码人生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Thrift RPC实战.初次体验Thrift相关的知识,希望对你有一定的参考价值。

1.前言:

  Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码,主要特点:

开发速度快:

通过编写RPC接口IDL文件,利用编译生成器自动生成Server端骨架(Skeletons)和客户端Stubs,省去开发者自定义和维护接口编解码、消息传输、服务器多线程模型等基础工作;Server端开发者只需按照服务骨架,写好自己的业务处理程序(Handlers)即可,Client端程序只需创建IDL中定义的服务对象,然后就像调用本地对象的方法一样调用远端服务。

接口维护简单高效:

通过维护Thrift格式的IDL(Interface Description Language)文件(注意写好注释),即可作为给Clients使用的接口文档使用,也自动生成接口代码,始终保持代码和文档的一致性。且Thrift协议可灵活支持接口的可扩展性。

学习成本低:

因为其来自Google Protocol Buffers开发团队,所以其IDL文件风格类似Google Protocol Buffers,且更加易读易懂;特别是RPC服务接口的风格就像写一个一般的面向对象的Class一样简单。

初学者只需参照http://thrift.apache.org/几个小时即可理解和使用Thrift。

多语言/跨语言支持:

Thrift支持C++, Java, Python, php, Ruby, Erlang, Perl, Haskell, C#, Cocoa, javascript, Node.js, Smalltalk, OCaml and Delphi等多种语言,即可生成上述语言的服务器端和客户端程序。

对于我们经常使用的Java、PHP、Python、C++支持良好,虽然对ios环境的Objective-C(Cocoa)支持稍逊,但也完全满足我们的使用要求。

已验证成熟稳定:

Thrift在很多开源项目中已经被验证是稳定和高效的,例如Cassandra、Evernode等;在Facebook、Baidu等后台产品中也有使用。

2.基础知识

2.1 Thrift 软件栈

  Thrift对软件栈的定义非常的清晰, 使得各个组件能够松散的耦合, 针对不同的应用场景, 选择不同是方式去搭建服务.   

评注:   Transport: 传输层,定义数据传输方式,可以为TCP/IP传输,内存共享或者文件共享等   protocol: 协议层, 定义数据传输格式,可以为二进制或者XML等   Processor: 处理层, 这部分由定义的idl来生成, 封装了协议输入输出流, 并委托给用户实现的handler进行处理.   Server: 服务层, 整合上述组件, 提供网络模型(单线程/多线程/事件驱动), 最终形成真正的服务.

Thrift 对语言的支持

  Thrift和Google Protobuf相比, 都提供了可扩展序列化机制, 不但兼容性好而且压缩率高. 两者在这块各有长短, 性能上PB稍有优势. 但在语言的支持度上, Protobuf只支持c++/java/python这三种主流的语言, Thrift则几乎覆盖了大部分的语言, 从这点上来说, Thrift的优势非常的明显.

Thrift 支持的数据类型

基本类型:   bool: 布尔值   byte: 8位有符号整数   i16: 16位有符号整数   i32: 32位有符号整数   i64: 64位有符号整数   double: 64位浮点数   string: UTF-8编码的字符串   binary: 二进制串 结构体类型:   struct: 定义的结构体对象 容器类型:   list: 有序元素列表   set: 无序无重复元素集合   map: 有序的key/value集合 异常类型:   exception: 异常类型 服务类型:   service: 具体对应服务的类

3.小试牛刀

3.1定义thrift文件

 
   
   
 
  1. namespace java com.yangyang.thrift.api

  2. service HelloService {

  3.   string hello(1: string name);

  4. }

3.2使用thrift提供的代码生成工具生成代码

thrift -gen java -out ../java/ hello.thrift

3.3新建thrift-demo工程

在pom文件中加入thrift以及log4j的jar

 
   
   
 
  1. <dependency>

  2.    <groupId>org.apache.thrift</groupId>

  3.    <artifactId>libthrift</artifactId>

  4.    <version>0.9.3</version>

  5. </dependency>

  6. <dependency>

  7.      <groupId>log4j</groupId>

  8.      <artifactId>log4j</artifactId>

  9.      <version>1.2.17</version>

  10. </dependency>

  11. <dependency>

  12.      <groupId>org.slf4j</groupId>

  13.      <artifactId>slf4j-api</artifactId>

  14.      <version>1.7.5</version>

  15. </dependency>

  16. <dependency>

  17.      <groupId>org.slf4j</groupId>

  18.      <artifactId>slf4j-log4j12</artifactId>

  19.      <version>1.7.5</version>

  20. </dependency>

编写服务端代码:

 
   
   
 
  1. package com.yangyang.thrift.server;

  2. import com.yangyang.thrift.api.HelloService;

  3. import com.yangyang.thrift.com.yangyang.thrift.service.HelloServiceImpl;

  4. import org.apache.thrift.protocol.TBinaryProtocol;

  5. import org.apache.thrift.server.TServer;

  6. import org.apache.thrift.server.TThreadPoolServer;

  7. import org.apache.thrift.transport.TServerSocket;

  8. import org.apache.thrift.transport.TTransportException;

  9. import org.slf4j.Logger;

  10. import org.slf4j.LoggerFactory;

  11. /**

  12. * Created by chenshunyang on 2016/10/30.

  13. */

  14. public class ServerDemo {

  15.    public static void main(String[] args) throws TTransportException {

  16.        Logger logger = LoggerFactory.getLogger(ServerDemo.class);

  17.        int port= 9000 ;

  18.        // *) 传输层(Transport), 设置监听端口为9000

  19.        TServerSocket serverTransport = new TServerSocket(port);

  20.        // *) 协议层

  21.        TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory(true, true);

  22.        // *) 处理层(Processor)

  23.        HelloServiceImpl handler = new HelloServiceImpl();

  24.        HelloService.Processor<HelloServiceImpl> processor = new HelloService.Processor<HelloServiceImpl>(handler);

  25.        // *) 服务层(Server)

  26.        TServer server = new TThreadPoolServer(

  27.                new TThreadPoolServer.Args(serverTransport)

  28.                        .protocolFactory(protocolFactory)

  29.                        .processor(processor));

  30.        // *) 启动监听服务

  31.        server.serve();

  32.        logger.info("服务已经启动,端口为:"+port);

  33.    }

  34. }

编写客户端代码:

 
   
   
 
  1. package com.yangyang.thrift;

  2. import com.yangyang.thrift.api.HelloService;

  3. import org.apache.thrift.TException;

  4. import org.apache.thrift.protocol.TBinaryProtocol;

  5. import org.apache.thrift.protocol.TProtocol;

  6. import org.apache.thrift.transport.TSocket;

  7. import org.apache.thrift.transport.TTransport;

  8. /**

  9. * Created by chenshunyang on 2016/10/30.

  10. */

  11. public class ClientDemo {

  12.    public static void main(String[] args) throws TException {

  13.        // *) 传输层

  14.        TTransport transport = new TSocket("localhost", 9000);

  15.        transport.open();

  16.        // *) 协议层, 与服务端对应

  17.        TProtocol protocol = new TBinaryProtocol(transport);

  18.        // *) 创建RPC客户端

  19.        HelloService.Client client = new HelloService.Client(protocol);

  20.        // *) 调用服务

  21.        System.out.println(client.hello("chenshunyang"));

  22.        // *) 关闭句柄

  23.        transport.close();

  24.    }

  25. }

先运行服务端,后运行客户端,观察结果,可以看到客户端输出结果: hello chenshunyang


以上是关于Thrift RPC实战.初次体验Thrift的主要内容,如果未能解决你的问题,请参考以下文章

RPC 基本原理与 Apach Thrift 初体验

RPC框架之Thrift架构及源码解读

RPC框架之Thrift架构及源码解读

RPC框架之Thrift架构及源码解读

RPC框架 - thrift 服务端

RPC框架 - thrift 客户端