1. 概述  

  thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Go,Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。Thrift允许定义一个简单的定义文件中的数据类型和服务接口,以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。thrift最初由facebook开发用做系统内各语言之间的RPC通信 。2007年由facebook贡献到apache基金 ,08年5月进入apache孵化器 。

2. thrift 的跨语言特性

  thrift通过一个中间语言IDL(接口定义语言)来定义RPC的数据类型和接口,这些内容写在以.thrift结尾的文件中,然后通过特殊的编译器来生成不同语言的代码,以满足不同需要的开发者,比如java开发者,就可以生成java代码,c++开发者可以生成c++代码,生成的代码中不但包含目标语言的接口定义,方法,数据类型,还包含有RPC协议层和传输层的实现代码。

3. thrift 的协议栈结构

thrift是一种c/s的架构体系.在最上层是用户自行实现的业务逻辑代码.第二层是由thrift编译器自动生成的代码,主要用于结构化数据的解析,发送和接收。TServer主要任务是高效的接受客户端请求,并将请求转发给Processor处理。Processor负责对客户端的请求做出响应,包括RPC请求转发,调用参数解析和用户逻辑调用,返回值写回等处理。从TProtocol以下部分是thirft的传输协议和底层I/O通信。TProtocol是用于数据类型解析的,将结构化数据转化为字节流给TTransport进行传输。TTransport是与底层数据传输密切相关的传输层,负责以字节流方式接收和发送消息体,不关注是什么数据类型。底层IO负责实际的数据传输,包括socket、文件和压缩数据流等。

4. thrift java 实例

4.1 创建一个服务HelloWorld

(1)创建文件Hello.thrift,代码如下:
namespace java org.wavemelody.thrift.demo

service  HelloWorldService {
string sayHello(:string username)
}

这里定义了一个HelloWorldService 服务,包含一个sayHello方法,入参和返回值都是一个string类型的参数。

(2)thrift生成代码
thrift-0.11..exe -r -gen java HelloWorldService.thrift
thrift-0.11.0.exe是官网提供的windows下编译工具,运用这个工具生成相关代码,生成后的目录结构如下:
thrift-0.11.0.exe
HelloWorldService.thrift
gen-java
  |--org
    |--wavemelody
      |--thrift
        |--demo
          |--HelloWorldService.java

将生成的 HelloWorldService.java 拷贝到自己的工程中,注意包路径。

(3)实现Iface

 HelloWorldServiceImpl.java

package org.wavemelody.thrift.demo;

import org.apache.thrift.TException;

/**
* Created by Andy on 2018/8/14.
*/
public class HelloWorldServiceImpl implements HelloWorldService.Iface{
@Override
public String helloString(String para) throws TException {
return "Hello " + para;
}
}
(4) 创建TSimpleServer服务端

创建服务器端实现代码,将 HelloServiceImpl 作为具体的处理器传递给 Thrift 服务器,代码如下:

HelloServiceServer.java

package org.wavemelody.thrift.demo;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException; /**
* Created by Andy on 2018/8/14.
*/
public class HelloServiceServer {
public void startServer(){
try {
        
System.out.println("HelloWorldServer start ... ");
TServerSocket serverTransport = new TServerSocket(8888);
TServer.Args tArgs = new TServer.Args(serverTransport);
TProcessor tProcessor = new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldServiceImpl());
tArgs.processor(tProcessor);
tArgs.protocolFactory(new TBinaryProtocol.Factory());
// tArgs.protocolFactory(new TCompactProtocol.Factory());
// tArgs.protocolFactory(new TJSONProtocol.Factory());
TServer server = new TSimpleServer(tArgs);
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
HelloServiceServer serviceServer = new HelloServiceServer();
serviceServer.startServer();
}
}
(5)编写客户端Client代码
HelloServiceClient.java
package org.wavemelody.thrift.demo;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException; /**
* Created by Andy on 2018/8/14.
*/
public class HelloServiceClient {
public void startClient(String username){
TTransport tTransport = null;
try {
tTransport = new TSocket("localhost",8888,30000);
// 协议要和服务端一致
TProtocol protocol = new TBinaryProtocol(tTransport);
// TProtocol protocol = new TCompactProtocol(tTransport);
// TProtocol protocol = new TJSONProtocol(tTransport);
HelloWorldService.Client client = new HelloWorldService.Client(protocol);
tTransport.open();
String result = client.helloString(username);
System.out.println("Thrify client result = " + result);
} catch (TTransportException ex) {
ex.printStackTrace();
} catch (TException ex) {
ex.printStackTrace();
}finally {
if(tTransport != null){
tTransport.close();
}
}
}
public static void main(String[] args){
HelloServiceClient client = new HelloServiceClient();
client.startClient(" world");
}
}
(6)测试远程调用

启动服务端,日志如下:

启动客户端,日志如下:

调用成功,符合预期结果。

4.2 TThreadPoolServer 服务模型

线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。

ThreadPoolHelloServiceServer.java

package org.wavemelody.thrift.demo;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException; /**
* Created by Andy on 2018/8/14.
*/
public class ThreadPoolHelloServiceServer {
public void startServer(){
try {
System.out.println("HelloWorldServer start ... ");
TServerSocket serverTransport = new TServerSocket(8888);
TThreadPoolServer.Args tArgs = new TThreadPoolServer.Args(serverTransport);
TProcessor tProcessor = new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldServiceImpl());
tArgs.processor(tProcessor);
tArgs.protocolFactory(new TBinaryProtocol.Factory());
// 线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。
TThreadPoolServer server = new TThreadPoolServer(tArgs);
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
ThreadPoolHelloServiceServer serviceServer = new ThreadPoolHelloServiceServer();
serviceServer.startServer();
}
}

客户端和之前的代码一样,测试结果如下:

4.3  TNonblockingServer 服务模型

使用非阻塞式IO,服务端和客户端需要指定 TFramedTransport 数据传输的方式。

服务端代码 TNonblockingHelloServiceServer.java

package org.wavemelody.thrift.demo;

import org.apache.thrift.TMultiplexedProcessor;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TTransportException; /**
* Created by Andy on 2018/8/14.
*/
public class TNonblockingHelloServiceServer {
public void startServer(){
try {
System.out.println("HelloWorldServer start ... ");
TNonblockingServerSocket tnbSocket = new TNonblockingServerSocket(8888);
TNonblockingServer.Args tArgs = new TNonblockingServer.Args(tnbSocket);
TProcessor tProcessor = new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldServiceImpl());
tArgs.processor(tProcessor);
tArgs.protocolFactory(new TBinaryProtocol.Factory());
tArgs.transportFactory(new TFramedTransport.Factory());
// 线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。
TNonblockingServer server = new TNonblockingServer(tArgs);
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
TNonblockingHelloServiceServer serviceServer = new TNonblockingHelloServiceServer();
serviceServer.startServer();
}
}

客户端代码:TNonblockingHelloServiceClient.java

package org.wavemelody.thrift.demo;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException; /**
* Created by Andy on 2018/8/14.
*/
public class TNonblockingHelloServiceClient {
public void startClient(String username){
TTransport tTransport = null;
try {
tTransport = new TFramedTransport(new TSocket("localhost",8888,30000));
// 协议要和服务端一致
TProtocol protocol = new TBinaryProtocol(tTransport);
// TProtocol protocol = new TCompactProtocol(tTransport);
// TProtocol protocol = new TJSONProtocol(tTransport);
HelloWorldService.Client client = new HelloWorldService.Client(protocol);
tTransport.open();
String result = client.helloString(username);
System.out.println("Thrify client result = " + result);
} catch (TTransportException ex) {
ex.printStackTrace();
} catch (TException ex) {
ex.printStackTrace();
}finally {
if(tTransport != null){
tTransport.close();
}
}
}
public static void main(String[] args){
TNonblockingHelloServiceClient client = new TNonblockingHelloServiceClient();
client.startClient(" world");
}
}

测试结果:

Thrift 入门教程的更多相关文章

  1. Thrift入门 (一)

    Install Go to thrift page download thrift. 1 2 3 4 brew install boost ./configure --without-python s ...

  2. Thrift入门初探(2)--thrift基础知识详解

    昨天总结了thrift的安装和入门实例,Thrift入门初探--thrift安装及java入门实例,今天开始总结一下thrift的相关基础知识. Thrift使用一种中间语言IDL,来进行接口的定义, ...

  3. CMake快速入门教程-实战

    http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/ http://blog.csdn.net/dbzhang800/article/detai ...

  4. 转:CMake快速入门教程-实战

    CMake快速入门教程:实战 收藏人:londonKu     2012-05-07 | 阅:10128  转:34    |   来源   |  分享               0. 前言一个多月 ...

  5. 一条数据的HBase之旅,简明HBase入门教程-Write全流程

    如果将上篇内容理解为一个冗长的"铺垫",那么,从本文开始,剧情才开始正式展开.本文基于提供的样例数据,介绍了写数据的接口,RowKey定义,数据在客户端的组装,数据路由,打包分发, ...

  6. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

  7. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

  8. wepack+sass+vue 入门教程(一)

    一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...

  9. Content Security Policy 入门教程

    阮一峰文章:Content Security Policy 入门教程

随机推荐

  1. 算法与数据结构(七) AOV网的拓扑排序(Swift版)

    今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...

  2. [Swift]LeetCode79. 单词搜索 | Word Search

    Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from l ...

  3. Jquery的详细解析和用法

    一.Jquery简介 Jquery是一个优秀的Javascrīpt框架.它是轻量级的js库(压缩后只有21k) ,它兼容CSS3,还兼容各种浏览器 (IE 6.0+, FF 1.5+, Safari  ...

  4. 起底区块链人脸识别黑马,一个没有人像的人脸识别:iFace Chain(爱妃链)

    近几年来,人脸识别技术可谓在移动互联网中得到了空前广泛应用,从银行APP免密转账,人脸快捷支付到证券人脸开户,人脸识别技术已经应用到了移动互联的诸多应用场景.互联网无处不在的今天,便捷与安全貌似是一个 ...

  5. 细说javascripe事件传播流程

    当我们使用js时,经常会遇到事件传播流程的问题,下面我说一下我的观点. 在js触发某个事件时会相应生成一个事件对象,而这个事件对象则会根据DOM事件流的方向进传递,而传递的顺序如下图所示: 事件对象会 ...

  6. 【从零开始自制CPU之学习篇00】开篇

    从今天开始决定用面包板制作一个8位的CPU,实现几个简单的指令.我给自己分两大部分计划,第一部分是学习制作CPU的理论知识,第二部分是实践.并打算实施计划的同时用博客的方式记录下来.理论知识的部分重点 ...

  7. 如何为ASP.NET Core的强类型配置对象添加验证

    原文: Adding validation to strongly typed configuration objects in ASP.NET Core 作者: Andrew Lock 译文: La ...

  8. Chorme浏览器渲染MathJax时出现竖线的解决方法

    Chorme浏览器渲染MathJax时出现竖线的原因分析与解决方法 查资料知,Chorme中显示MathJax时出现竖线的原因如下: 新版的Chorme浏览器在解析css时,会对其中的值进行向上取整( ...

  9. Spring RestTemplate中几种常见的请求方式

    https://github.com/lenve/SimpleSpringCloud/tree/master/RestTemplate在Spring Cloud中服务的发现与消费一文中,当我们从服务消 ...

  10. IntelliJ IDEA部署tomcat时Edit Configuration Deployment无artifact选项

    IntelliJ IDEA,IntelliJ Idea创建web项目之后在配置web项目时,选择Edit Configration部署Tomcat,Deployment里点击添加无artifact选项 ...