thrift详解

背景

thrift最早由facebook开发,后来贡献给了apache。thrift主要解决跨语言调用的问题。

thrift和protobuf有啥区别?

thrift和protobuf,都解决了一个问题就是夸语言数据结构的定义,json也解决了跨语言的数据结构定义,只不过json都是字符串的,传输的开销和解析的开销可能有些大。那么想传输二进制的话怎么办呢,可以自己定义数据结构,比如大家熟知的网络协议就是这么定出来的,前1个字节代表啥啥啥,第二个字节代表啥啥啥,然后客户端和服务端都遵守这个协议。在没有thrift或者profobuf之前好多cs程序就是这么干的。但是这么干很累啊,还得写文档,而且开发时候也不好记,不好交流。后来人们想出了个办法,就是用一个类似json格式的文件定义数据结构,然后自动生成代码去处理二进制的转换,这样人们既可以用好读的格式定义数据结构,又可以高效的使用,于是就诞生了protobuf和thrift这类东西。protobuf到此为止了,thrift又把服务端程序和客户端程序也顺手加进去可以自动生成了,这样程序员就只负责写业务逻辑,其他的传输啊神马的都自动生成了,这就是protobuf和thrift的区别。这样thrift就有了全套的RPC机制,

为什么要跨语言调用?

有人认为是团队需要,不同的人擅长不同的语言,我认为从架构的角度想,有2点好处

  1. 用适合的语言做适合的事情,比如一些复杂算法的部分,c语言比较合适,性能高冗余的事情干的少,PHP的话可能性能就慢很多,这时候可以考虑跨语言调用
  2. 对于大型项目的团队间的解耦,在大公司中可能不同的功能并不是一个组完成的,可能会跨组甚至跨部门,这时候把一个功能以服务的形势对其他部门提供,是一种比较好的方式。

为什么不直接用HTTP json交互多方便?

是的,可以用json,好多api都是用json形式的,现在也流行REST,其实也是蛮方便的,但是有几个缺点

  1. 不管用什么语言吧,都得有个http服务,java和php还好,像c这种就有点费劲。
  2. json很灵活,也好改,但是需要有良好的文档,自己用非常好,大团队可能会有些沟通上的问题,起码文档要写清楚json各个字段含义,值可能有哪些类型,不然你就给人家一个url说这个就是xxx的api,人家对接如果没文档基本是不可能接的了的。
  3. 鉴权和验签问题,之前做网站的get请求可以不考虑调用者的身份问题,因为反正给人家看的嘛,谁看不一样。但是作为api的时候特别是涉及增删改的时候,调用者的身份问题就得考虑了,不能谁都能调啊,所以一般http的api都要设计个签名规则,对接的人得按照你的验签规则去写程序,通常这是对接时候比较耗时和容易出问题的地方。 1.从传输量大小上,不如二进制省空间,对于

安装

thrift的安装分两部分

  1. 是thrift本身
  2. 是语言包

安装thrift 编译器

这个其实没必要编译安装的,直接下载windows版的就行。 在linux上编译安装也还比较好装,但是可能会缺这缺那,缺啥用yum装即可

1./configure 2make 3make install

安装语言lib

语言包都在源码的lib目录下,所以下载linux版本才有,windows版本那个只是个编译好的thrift编译器

比如java

1cd thrift源码/lib/java 2ant 3会生成libthrift-0.9.3.jar

再比如python

1cd thrift源码/lib/py 2python setup.py install

使用步骤:

  1. 准备:thrift编译器,服务端、客户端语言的lib

  2. 写thrift文件

    service HelloService{ string sayHello(1:string username) }

然后用thrift编译:

  • thrift.exe -r -gen java hello.thrift
  • thrift.exe -r -gen php hello.thrift
  • thrift.exe -r -gen py hello.thrift 要啥语言就生成啥
  1. 写实现

    import org.apache.thrift.TException;

    1public class helloImp implements HelloService.Iface { 2 3 @Override 4 public String sayHello(String username) throws TException { 5 System.out.println(username); 6 return username; 7 } 8 9}

这里这个HelloService就是thrift生成的java文件 3. 写服务端

1 import org.apache.thrift.TProcessor; 2 import org.apache.thrift.protocol.TBinaryProtocol; 3 import org.apache.thrift.server.TServer; 4 import org.apache.thrift.server.TSimpleServer; 5 import org.apache.thrift.transport.TServerSocket; 6 import org.apache.thrift.transport.TTransportException; 7 8 public class Server { 9 10 public void start() 11 { 12 TProcessor tpProcessor = new HelloService.Processor<HelloService.Iface>(new helloImp()); 13 TServerSocket serverTransport; 14 try { 15 serverTransport = new TServerSocket(8889); 16 TServer.Args args = new TServer.Args(serverTransport); 17 args.processor(tpProcessor); 18 args.protocolFactory(new TBinaryProtocol.Factory()); 19 TServer server = new TSimpleServer(args); 20 System.out.println("thrift server start"); 21 server.serve(); 22 23 } catch (TTransportException e) { 24 // TODO Auto-generated catch block 25 e.printStackTrace(); 26 } 27 28 } 29 30 public static void main(String[] args) { 31 Server server = new Server(); 32 server.start(); 33 } 34 35 } 36

4.写客户端 以python为列子

1import sys 2import glob 3 4from hello import HelloService 5 6from thrift import Thrift 7from thrift.transport import TSocket 8from thrift.transport import TTransport 9from thrift.protocol import TBinaryProtocol 10 11# Make socket 12transport = TSocket.TSocket('localhost', 8889) 13 14# Buffering is critical. Raw sockets are very slow 15transport = TTransport.TBufferedTransport(transport) 16 17# Wrap in a protocol 18protocol = TBinaryProtocol.TBinaryProtocol(transport) 19 20# Create a client to use the protocol encoder 21client = HelloService.Client(protocol) 22 23# Connect! 24transport.open() 25 26 27rs = client.sayHello('luyu') 28 29print rs

其他语言版本怎么写????

在源码的tutorial目录下有各种语言的例子

持续更新 未完待续...

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java将前端的json数组字符串转换为列表

记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang