Thrift 入门教程
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 入门教程的更多相关文章
- Thrift入门 (一)
Install Go to thrift page download thrift. 1 2 3 4 brew install boost ./configure --without-python s ...
- Thrift入门初探(2)--thrift基础知识详解
昨天总结了thrift的安装和入门实例,Thrift入门初探--thrift安装及java入门实例,今天开始总结一下thrift的相关基础知识. Thrift使用一种中间语言IDL,来进行接口的定义, ...
- CMake快速入门教程-实战
http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/ http://blog.csdn.net/dbzhang800/article/detai ...
- 转:CMake快速入门教程-实战
CMake快速入门教程:实战 收藏人:londonKu 2012-05-07 | 阅:10128 转:34 | 来源 | 分享 0. 前言一个多月 ...
- 一条数据的HBase之旅,简明HBase入门教程-Write全流程
如果将上篇内容理解为一个冗长的"铺垫",那么,从本文开始,剧情才开始正式展开.本文基于提供的样例数据,介绍了写数据的接口,RowKey定义,数据在客户端的组装,数据路由,打包分发, ...
- wepack+sass+vue 入门教程(三)
十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...
- wepack+sass+vue 入门教程(二)
六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...
- wepack+sass+vue 入门教程(一)
一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...
- Content Security Policy 入门教程
阮一峰文章:Content Security Policy 入门教程
随机推荐
- 【XSS】利用 onload 事件监控流量劫持
说到跨站资源监控,首先会联想到『Content Security Policy』.既然 CSP 好用,我们何必自己再搞一套呢.那就先来吐槽下 CSP 的缺陷. 目前的 CSP 日志不详细 用过 CSP ...
- 接口调试之Postman 使用方法详解
一.Postman背景介绍 用户在开发或者调试网络程序或者是网页B/S模式的程序的时候是需要一些方法来跟踪网页请求的,用户可以使用一些网络的监视工具比如著名的Firebug等网页调试工具.今天给大家介 ...
- 【RL-TCPnet网络教程】第9章 RL-TCPnet网络协议栈移植(uCOS-III)
第9章 RL-TCPnet网络协议栈移植(uCOS-III) 本章教程为大家讲解RL-TCPnet网络协议栈的uCOS-III操作系统移植方式,学习了第6章讲解的底层驱动接口函数之后,移 ...
- 基于Java实现简化版本的布隆过滤器
一.布隆过滤器: 布隆过滤器(Bloom Filter)是1970年由布隆提出的.它实际上是一个很长的二进制向量和一系列随机映射函数.布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率 ...
- Python 远程开机
用 Python 关机你肯定听过或者实践过,那么用 Python 开机呢?这是一个神奇的方法,教你如何用 Python 来开机. 本文目标 远程开机原理 Python 远程开机代码实现 Python ...
- [Swift]LeetCode87. 扰乱字符串 | Scramble String
Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrin ...
- [Swift]LeetCode675. 为高尔夫比赛砍树 | Cut Off Trees for Golf Event
You are asked to cut off trees in a forest for a golf event. The forest is represented as a non-nega ...
- [Swift]LeetCode725. 分隔链表 | Split Linked List in Parts
Given a (singly) linked list with head node root, write a function to split the linked list into k c ...
- [Swift]LeetCode865. 具有所有最深结点的最小子树 | Smallest Subtree with all the Deepest Nodes
Given a binary tree rooted at root, the depth of each node is the shortest distance to the root. A n ...
- 手把手的教你安装PyCharm --Pycharm安装详细教程(一)(非常详细,非常实用)
简介 Jetbrains家族和Pycharm版本划分: pycharm是Jetbrains家族中的一个明星产品,Jetbrains开发了许多好用的编辑器,包括Java编辑器(IntelliJ IDEA ...