Thrift 初认识 & Thrift 和Dubbo 的区别

【thirft 简介】

维基百科:
Thrift是一种接口描述语言和二进制通讯协议,[1]它被用来定义和创建跨语言的服务。[2]它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。它通过一个代码生成引擎联合了一个软件栈,来创建不同程度的、无缝的跨平台高效服务,可以使用C#、C++(基于POSIX兼容系统[3])、Cappuccino、[4]Cocoa、Delphi、Erlang、Go、Haskell、Java、Node.js、OCaml、Perl、PHP、Python、Ruby和Smalltalk。[5]虽然它以前是由Facebook开发的,但它现在是Apache软件基金会的开源项目了。该实现被描述在2007年4月的一篇由Facebook发表的技术论文中,该论文现由Apache掌管

简单来说thrift就是Facebook 开发的一个语言中立、平台中立的RPC 框架。

mac 环境使用brew 安装:

brew install thrift
PRC

先简要说一下什么是RPC。

RPC,即Remote Procedure Call,意为远程过程调用,什么是远程过程调用?举个简单的例子:

假设你和兄弟住在同一个房间,你在外面时突然想起衣服忘洗了,于是打电话让兄弟把衣服洗了

在这个例子中你和兄弟就相当于两个应用A/B,你在外面就相当于两个不同的服务环境,洗衣服就相当于一个服务。

A 应用想调用B应用的服务,但因为不在同一个环境所以无法操作成功,就相当于你在外面不能洗衣服,而兄弟可以。于是你打电话给兄弟,让他帮你洗衣服,就是一次远程过程调用。

远程过程调用需要在A、B之间建立一个通信通道,就相当于你给兄弟打电话需要通讯信号,手机的那一套的东西,RPC 框架就是把那一套给你屏蔽了,就相当于你只需要买个手机、电话卡就行了。电话与电话之间怎么链接的你就不用管了。

Thrift 语言中立

thrift 通过一个中间语言IDL(接口定义语言)来定义RPC的数据类型和接口,以.thrift 结尾,然后可以根据需求编译成想要的文件。

比如创建一个服务Hello,创建文件Hello.thrift,代码如下:

namespace java service.demo
service Hello{
    string helloString(1:string para)
}

然后通过命令生成java 代码:

thrift -r -gen java Hello.thrift

生成的代码中不但包含目标语言的接口定义、方法、数据类型,还包含有RPC协议层和传输层的实现代码:

/**
 * Autogenerated by Thrift Compiler (0.13.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package com.thrift;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.13.0)", date = "2020-02-20")
public class Hello {

  public interface Iface {

    public String helloString(String para) throws org.apache.thrift.TException;

  }

  public interface AsyncIface {

    public void helloString(String para, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws org.apache.thrift.TException;

  }

  public static class Client extends org.apache.thrift.TServiceClient implements Iface {
    public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
      public Factory() {}
      public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
        return new Client(prot);
      }
      public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
        return new Client(iprot, oprot);
      }
    }

    public Client(org.apache.thrift.protocol.TProtocol prot)
    {
      super(prot, prot);
    }

    public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
      super(iprot, oprot);
    }

    public String helloString(String para) throws org.apache.thrift.TException
    {
      send_helloString(para);
      return recv_helloString();
    }

    public void send_helloString(String para) throws org.apache.thrift.TException
    {
      helloString_args args = new helloString_args();
      args.setPara(para);
      sendBase("helloString", args);
    }

    public String recv_helloString() throws org.apache.thrift.TException
    {
      helloString_result result = new helloString_result();
      receiveBase(result, "helloString");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "helloString failed: unknown result");
    }

  }
  ...

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AgIG8Rbh-1582208172872)(http://note.youdao.com/yws/res/10552/54EC0AF180E64D34B7D2262F2376D39A)]

当然也可以生产c++ 或者其他的开发语言看自己的需求。

Thirft demo该博客需要把thrift maven版本升级到0.12.0,不然会找不到annotation 类的错误

Thrift 协议栈

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dc3Kx6sE-1582208172874)(http://note.youdao.com/yws/res/10559/A8D89B272593441BBDA9F808FEA27A77)]
Thrift是一种c/s的架构体系。Server主要任务是高效的接受客户端请求,并将请求转发给Processor处理。

  • 最上层是用户自行实现的业务逻辑代码;
  • Processor是由thrift编译器自动生成的代码,它封装了从输入数据流中读数据和向数据流中写数据的操作,它的主要工作是:从连接中读取数据,把处理交给用户实现impl,最后把结果写到连接上。
  • TProtocol(协议层),定义数据传输格式,例如:
    • TBinaryProtocol:二进制格式;
    • TCompactProtocol:压缩格式;
    • TJSONProtocol:JSON格式;
    • TSimpleJSONProtocol:提供JSON只写协议, 生成的文件很容易通过脚本语言解析;
    • TDebugProtocol:使用易懂的可读的文本格式,以便于debug
  • TTransport(传输层),定义数据传输方式,可以为TCP/IP传输,内存共享或者文件共享等)被用作运行时库。
    • TSocket:阻塞式socker;
    • TFramedTransport:以frame为单位进行传输,非阻塞式服务中使用;
    • TFileTransport:以文件形式进行传输;
    • TMemoryTransport:将内存用于I/O,java实现时内部实际使用了简单的ByteArrayOutputStream;
    • TZlibTransport:使用zlib进行压缩, 与其他传输方式联合使用,当前无java实现
  • 底层IO负责实际的数据传输,包括socket、文件和压缩数据流等。
  • Thrift支持的服务模型
    • TSimpleServer:简单的单线程服务模型,常用于测试;
    • TThreadPoolServer:多线程服务模型,使用标准的阻塞式IO;
    • TNonblockingServer:多线程服务模型,使用非阻塞式IO(需使用TFramedTransport数据传输方式);

【Thrift 与Dubbo 的区别】

转载自参考博客:https://blog.csdn.net/JustKian/article/details/102495650

透明化服务调用

Thrift:通过IDL(接口定义语言)实现,Thrift是支持跨语言的,而要实现跨语言机制,就需要一种中间语言来完成,那就是IDL。首先定义好了IDL之后(即定义好了一个service),由于server和Client都需要持有这个与之语言相对应的服务接口,那就需要thrift来将IDL编译成与之语言相对应的接口类,比如server端是java,client端是C#,则server端需要编译成java类,client编译成C#类。然后server端负责接口的具体实现,client只需要持有这个对象接口,进行调用即可,然后通过网络通信传给server。server负责解析client传递过来的数据,由于服务对象接口统一为IDL(thrift格式),所以统一了解析形式,只和本地的开发语言有关。

Dubbo:通过java反射和动态代理实现这一功能,由于只支持Java,所以Client和Server端开发语言机制一样,所以它们能够通过spring框架进行依赖,server端一般将对象方法接口注册发布到Zookeper中,然后Client可以直接从Zookeper中获取server端发布的对象方法接口,这样Client可以通过Spring进行自动装配获得server端发布的对象方法服务接口。

网络通信

thrift 参考上文

Thrift实际上是实现了C/S模式,通过代码生成工具将thrift文生成服务器端和客户端代码(可以为不同语言),从而实现服务端和客户端跨语言的支持。用户在Thirft文件中声明自己的服务,这些服务经过编译后会生成相应语言的代码文件,然后客户端调用服务,服务器端提服务便可以了。

dubbo网络通讯层主要实现了以下功能:

  • 多种网络通讯框架的抽象封装(netty,mina,grizzly)
  • 每个客户端主机和服务端保存单个长链接通信
  • 异步调用转同步
  • tcp链接的心跳和自动重连
  • 基于header头通讯协议,请求的编解码器

dubbo的网络通信基于NIO框架,一般基于事件的NIO网络框架都涉及到 channel , channelHandle核心概念,网络数据buffer, 网络数据编解码器,dubbo为了能够适配多种NIO框架,将以上概念全部又抽象了一层接口。如果有netty开发经验或者了解netty helloworld demo程序对于理解这个章节非常有帮助。

参考链接:

https://www.jianshu.com/p/1e0c8c08e89d

https://www.jianshu.com/p/1a1404ce2201

https://blog.csdn.net/qq418517226/article/details/51906357

序列化

thrift只支持对thrift协议描述的IDL进行序列化,包含如下几种序列化格式:

  • TBinaryProtocol:二进制格式;
  • TCompactProtocol:压缩格式;
  • TJSONProtocol:JSON格式;
  • TSimpleJSONProtocol:提供JSON只写协议, 生成的文件很容易通过脚本语言解析;
  • TDebugProtocol:使用易懂的可读的文本格式,以便于debug

dubbo支持各种协议的序列化(实际上,dubbo没有IDL这一机制,因为实际上他就是通过java服务对象接口进行交互的)
例如他也可支持thrift协议,只需要thrift将IDL转换为一个java服务对象接口,那么dubbo就可以使用了

【附录】

  • 基本类型:
    • bool:布尔值,true 或 false,对应 Java 的 boolean
    • byte:8 位有符号整数,对应 Java 的 byte
    • i16:16 位有符号整数,对应 Java 的 short
    • i32:32 位有符号整数,对应 Java 的 int
    • i64:64 位有符号整数,对应 Java 的 long
    • double:64 位浮点数,对应 Java 的 double
    • string:utf-8编码的字符串,对应 Java 的 String
  • 结构体类型:
    • struct:定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean
  • 容器类型:
    • list:对应 Java 的 ArrayList
    • set:对应 Java 的 HashSet
    • map:对应 Java 的 HashMap
  • 异常类型:
    • exception:对应 Java 的 Exception
  • 服务类型:
    • service:对应服务的类
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值