何时以及为什么使用Thrift比使用简单的套接字/网络编程更好的解决方案?

时间:2014-01-21 18:24:03

标签: sockets network-programming rpc thrift

我想将Thrift用于一个项目但是我需要很多理由为什么它比仅仅使用通过网络发送的简单套接字和结构更好。我试图制作的每个参数总是归结为这样一个事实:对于小型应用程序,简单的套接字编程更容易,更快速地实现。显然,是否使用它在很大程度上取决于项目,但我的情况特别是c / c ++中的linux应用程序与Windows服务应用程序(c ++或c#)交谈。我正在尝试编译一个优缺点列表(主要是专业人员)使用thrift而不仅仅是一个简单的套接字发送函数。以下是我迄今为止编辑的关于节俭的信息(我承认其中一些可能不准确或可能需要我更多的解释/澄清)(我在http://martin.kleppmann.com/2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html上找到的很多信息):

  

另一个RPC和序列化框架选项Thrift包含一个用于处理分布式对象通信/ RPC和序列化的库,以及一个编译器。 Thrift是Apache License 2.0下的免费开源框架,它允许软件用户自由地将软件用于任何目的,分发,修改软件,以及分发修改后的软件版本。许可条款,不考虑特许权使用费。此外,只要合并作品的许可证也是GPL 3.0,它就可以与GPL 3.0许可内容结合使用。 Thrift是一个相当新的框架,它源于Facebook开发的RPC框架,然后作为开源发布。它自2008年左右开始存在,并拥有蓬勃发展的用户群。

     

默认情况下,Thrift使用行业标准JSON或其他内置协议选项来定义数据类型和协议;但它也支持自定义备用接口描述语言。 Thrift库本身可以用多种语言编译(独立于平台),Thrift编译器可以从多种语言的接口/配置文件中自动生成类,服务器,客户端和存根/框架代码。 Thrift具有阻止/非阻塞服务器选项可供选择。如果使用Thrift,则需要编写有限的网络代码,因为它包含在内。需要编写IDL文件来定义用于序列化/反序列化的数据包数据/命令。

     

Thrift支持以下原始类型:

     
      
  • bool:布尔值(true或false)
  •   
  • byte:8位有符号整数
  •   
  • i16:16位有符号整数
  •   
  • i32:32位有符号整数
  •   
  • i64:64位有符号整数
  •   
  • double:64位浮点数
  •   
  • string:使用UTF-8编码
  • 编码的文本字符串   
     

以及以下复杂类型:

     
      
  • 记录
  •   
  • 结构
  •   
  • 容器
  •   
  • 例外
  •   
  • 服务
  •   
     

Thrift支持长期模式演变,允许对模式进行修改(例如新字段和数据类型/属性),而不会丢失旧接口文件之间的任何向后兼容性。当然,仍然需要修改客户端/服务器逻辑以支持模式更改中的新功能。消息/命令标记有标识符,因此接收端可以将它们与模式匹配。编译存根/框架代码以处理接口文件中定义的消息需要额外的编译步骤。

     

使用Thrift获得架构更改之间的向后兼容性(允许软件更新而不破坏旧的现场系统),平台独立性和插件RPC和服务器,除了如何处理发送回的命令/数据之外,不需要编写任何代码客户端和服务器之间。

2 个答案:

答案 0 :(得分:2)

当然,节俭是好的,但不适用于所有类型的项目。优点:

  • 节省异步套接字编程:在异步引擎中只有一种工作方式,在thrift中你可以选择最适合你的方式(单线程,并行或异步)
  • thrift是一个框架。您编写的样板代码较少。您没有实现传输,协议等。
  • thrift基于定义,形成一种自我记录。当新人加入您的团队时,这在大型项目中非常有用。查看定义可以让您了解系统内部的内容
  • thrift支持20多种语言。这意味着如果您已有thrift定义文件,则可以提供所有语言客户端。此外,如果您想要更改服务器的平台(例如c ++ - > java或其他),那么这对您的所有基础架构都会自动透明(工作量少得多)。

缺点:

  • 节俭比google的protobuffers稍慢(基准测试表明它是10%,关于TBinary或TCompact协议)
  • thrift永远不会击败专门的异步引擎,如boost :: asio或python的扭曲。它不是为这个puprose设计的。

总结 - 如果您需要通过api提供具有复杂功能的服务,那么节俭是一个不错的选择。此外,如果您需要在不同平台上拥有客户端,那么节俭是一个很好的选择。但如果您需要非凡的性能,请将其与protobuf进行比较。如果你需要提供非常简单的结构(计算可能很复杂,但传输本身很容易),那么请考虑boost :: asio,twisted或者像那样。

您可以查看my presentation about thrift,其中有一部分内容涉及好处和限制。

答案 1 :(得分:1)

很难从你的文字或更好的“问题”中提炼出一个问题。这一切归结为“我应该使用高级框架吗?”,其次是一些避免高级框架的原因,因为从头开始实现它更容易。

对我而言,这种方法听起来更像是喜欢汇编程序而不是3GL +语言,因为这些编译器倾向于产生10万个二进制文件,其中汇编程序大师会在10k中执行相同的操作,具有两倍的功能。

在任何一种情况下,如果产品工作并满足所有要求,那么无论你怎么做都没关系。那么什么是一个好的决策基础?

当今软件开发的关键是生产力和生产力的折衷:稳定性,可维护性(特别是源代码的可访问性)以及改变或扩展事物的灵活性。

如果组装大师是唯一理解他的代码的人,或者他需要三周而不是五天来完成它,那么很可能你有问题。

您想要从二进制切换到JSON吗?您想要另一个API调用另一个结构,还有另外两个字段在Foobar结构中?您需要将传输从套接字更改为HTTP吗?您想通过某个MQ系统连接模块,但是尽可能保持它们之间的逻辑接口?你想要你的新同事在原始套接字编程方面没有那么多经验吗?设计时考虑到这些目标的高级框架可以使这些更改变得非常容易。

另一方面,您所选择的框架可能无法满足您当天的特定需求,这是正确的。因此,它或多或少是一种权衡,但在大多数情况下,与投资相比,你可以获得更多的权衡。

关于在Windows和Linux上连接C ++ / C#的问题:这正是Apache Thrift设计的场景之一。