thrift with java

894 阅读3分钟

thrift是啥

The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages.

Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。它通过一个代码生成引擎联合了一个软件栈,来创建不同程度的、无缝的跨平台高效服务,可以使用C#、C++(基于POSIX兼容系统)。

架构图

架构图

Thrift支持的通讯协议

  • TBinaryProtocol – 一种简单的二进制格式,简单,但没有为空间效率而优化。比文本协议处理起来更快,但更难于调试。
  • TCompactProtocol – 更紧凑的二进制格式,处理起来通常同样高效。
  • TDebugProtocol – 一种人类可读的文本格式,用来协助调试。
  • TDenseProtocol – 与TCompactProtocol类似,将传输数据的元信息剥离。
  • TJSONProtocol – 使用JSON对数据编码。
  • TSimpleJSONProtocol – 一种只写协议,它不能被Thrift解析,因为它使用JSON时丢弃了元数据。适合用脚本语言来解析。

支持的传输协议

  • TFileTransport – 该传输协议会写文件。
  • TFramedTransport – 当使用一个非阻塞服务器时,要求使用这个传输协议。它按帧来发送数据,其中每一帧的开头是长度信息。
  • TMemoryTransport – 使用存储器映射输入输出。(Java的实现使用了一个简单的ByteArrayOutputStream。)
  • TSocket – 使用阻塞的套接字I/O来传输。
  • TZlibTransport – 用zlib执行压缩。用于连接另一个传输协议。

Thrift还提供众多的服务类型

  • TNonblockingServer – 一个多线程服务器,它使用非阻塞I/O(Java的实现使用了NIO通道)。TFramedTransport必须跟这个服务器配套使用。
  • TSimpleServer – 一个单线程服务器,它使用标准的阻塞I/O。测试时很有用。
  • TThreadPoolServer – 一个多线程服务器,它使用标准的阻塞I/O。

在intelliJ IDEA上编写thrift

IDEA

安装插件

thrift support插件

新建一个maven项目

新建一个maven项目

引入必须的包

  • org.apache.thrift:libthrift:0.9.3
  • org.slf4j:slf4j-api:1.7.21
  • Simple Logging Facade for Java:1.7.21

引入必须的包

配置编译环境

  • 9584 brew install boost
  • 9588 brew install libevent
  • 9611 brew install thrift
  • 9622 brew install bison
  • 9629 brew link bison –force
  • 9633 brew install ant
    配置编译环境
    配置输出

异步Client

public class ThriftClientSearchAlbums implements onGetData{
    public static void main(String[] args) {
        try {
            TAsyncClientManager clientManager = new TAsyncClientManager();
            TNonblockingTransport transport = new TNonblockingSocket("127.0.0.1", 8191, 5000);
            TProtocolFactory tprotocol = new TCompactProtocol.Factory();
            searchAlbums.AsyncClient asyncClient = new searchAlbums.AsyncClient(tprotocol, clientManager, transport);
            CountDownLatch latch = new CountDownLatch(5);
            AsynCallback callBack = new AsynCallback(latch);
            asyncClient.searchAlbumsByKeyword("郭德纲",callBack);
            boolean wait = latch.await(30, TimeUnit.SECONDS);
        } catch (TTransportException e) {
            e.printStackTrace();
        } catch (TException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void onGetDataListener() {
    }
}

异步Server

/**
 * Created by bigmercu on 2016/11/25.
 * Email:bigmercu@gmail.com
 */
public class ThriftServerSearchAlbums {
    @SuppressWarnings("unchecked")
    public void startServer() {
        try {
            TProcessor tprocessor = new searchAlbums.AsyncProcessor(new searchAlbumsImpl());
            TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(8191);
            TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(tnbSocketTransport);
            tnbArgs.processor(tprocessor);
            tnbArgs.transportFactory(new TFramedTransport.Factory());
            tnbArgs.protocolFactory(new TCompactProtocol.Factory());
            // 使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式
            TServer server = new TNonblockingServer(tnbArgs);
            server.serve();
        } catch (TTransportException e) {
            System.out.println("Starting Thrift Server......Error!!!");
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        ThriftServerSearchAlbums server = new ThriftServerSearchAlbums();
        server.startServer();
    }

AsynCallback

/**
 * Created by bigmercu on 2016/11/27.
 * Email:bigmercu@gmail.com
 */
public class AsynCallback implements AsyncMethodCallback {
    private CountDownLatch latch;
    private AlbumsEntity mAlbumsEntity;
    public AsynCallback(CountDownLatch latch) {
        this.latch = latch;
    }
    @Override
    public void onComplete(searchAlbumsByKeyword_call response) {
        System.out.println(latch.getCount());
        try {
            System.out.println("AsynCall result:" + response.getResult().toString());
        } catch (TException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            latch.countDown();
        }
    }
    @Override
    public void onError(Exception exception) {
        System.out.println("onError :" + exception.getMessage());
        latch.countDown();
    }