贝博恩创新科技网

Thrift如何助力互联网公司高效开发?

Thrift 最初由 Facebook 开发,现在是 Apache 软件基金会下的一个开源项目,它是一种跨语言的、高性能的、用于实现 RPC(远程过程调用)的框架,在互联网公司中,它扮演着至关重要的角色,尤其是在构建大型、分布式服务架构时。

Thrift如何助力互联网公司高效开发?-图1
(图片来源网络,侵删)

为什么互联网公司选择 Thrift?

互联网公司的核心业务通常由大量微服务组成,这些服务可能使用不同的编程语言开发(如 Java、Python、Go、C++ 等),并且需要高效、可靠地进行通信,Thrift 正好解决了这些痛点。

核心优势:

  1. 跨语言支持

    • 这是 Thrift 最核心的优势,它支持多达 20 多种编程语言,包括 Java, C++, Python, PHP, Ruby, Go, Node.js, C# 等。
    • 应用场景:一个用 Go 编写的推荐服务可以轻松地调用一个用 Java 编写的用户画像服务,而一个用 Python 编写的数据分析服务也可以查询 Go 服务的接口,这种语言无关性让团队可以根据业务需求选择最合适的语言,而无需受限于通信协议。
  2. 高性能

    Thrift如何助力互联网公司高效开发?-图2
    (图片来源网络,侵删)
    • Thrift 使用二进制协议进行数据传输,相比基于文本的协议(如 JSON、XML),它更紧凑、解析速度更快。
    • 它支持多种传输层协议(如 Socket、HTTP)和多种序列化方式(如 Binary, Compact, JSON)。Binary 和 Compact 协议在性能上表现优异,能显著降低网络传输的延迟和带宽消耗。
    • 应用场景:在需要高并发、低延迟的核心业务场景(如广告竞价、实时推荐)中,Thrift 的高性能是关键。
  3. 代码自动生成

    • 这是 Thrift 的“杀手级”特性,开发者只需要使用 Thrift 的接口定义语言(IDL)来定义服务的接口和数据结构。
    • 通过 Thrift 编译器,可以自动生成所有支持语言的客户端和服务端代码,这极大地减少了手动编写网络通信代码的工作量,并保证了客户端和服务端接口的一致性。
    • 应用场景:当一个服务的接口需要修改时,只需修改 .thrift 文件,然后重新生成所有语言的代码,即可完成整个系统的升级,避免了人工同步接口的繁琐和错误。
  4. 丰富的数据类型

    Thrift IDL 支持丰富的数据类型,包括基本类型(int, string, bool)、容器类型(list, set, map)和自定义结构体,这使得它可以灵活地描述复杂的数据模型。


Thrift 在互联网公司中的典型应用场景

  1. 构建微服务架构

    Thrift如何助力互联网公司高效开发?-图3
    (图片来源网络,侵删)
    • 场景:一个大型电商网站的后端系统被拆分为多个微服务,如用户服务、商品服务、订单服务、支付服务等。
    • 应用:这些服务之间通过 Thrift 进行通信,订单服务在创建订单时,需要调用用户服务来获取用户信息,调用商品服务来检查库存,由于这些服务可能由不同团队使用不同语言开发,Thrift 提供了完美的跨语言解决方案。
  2. 内部 API 网关

    • 场景:许多公司会构建一个统一的 API 网关,作为所有外部或内部客户端访问后端服务的统一入口。
    • 应用:API 网关本身可以是一个 Thrift 服务,它接收来自前端的请求,然后根据路由规则,将请求转发给相应的后端 Thrift 微服务,网关可以处理认证、限流、日志等通用逻辑,而后端服务则专注于业务逻辑。
  3. 数据同步与 ETL(提取、转换、加载)

    • 场景:需要将业务数据库中的数据同步到数据仓库(如 HDFS, S3)或搜索引擎(如 Elasticsearch)中。
    • 应用:可以编写一个数据抽取服务,它作为 Thrift 服务端,暴露数据接口,一个用 Python 或 Java 编写的 ETL 任务作为 Thrift 客户端,定期从服务端拉取数据,进行处理后写入目标系统。
  4. 实时计算与流处理系统

    • 场景:在实时推荐或风控系统中,需要从多个数据源(如用户行为日志、用户画像)中快速获取信息。
    • 应用:一个流处理任务(如 Flink, Spark Streaming)在处理每一条数据时,可以通过 Thrift 实时调用用户画像服务,获取用户的标签信息,以便进行实时计算。
  5. 客户端与服务端通信

    • 场景:公司的移动 App、桌面客户端、Web 前端需要与后端服务器交互。
    • 应用:虽然现在更常见的是使用 RESTful API + JSON,但对于对性能要求极高的客户端(如游戏客户端),使用 Thrift 可以获得更低的延迟和更高的吞吐量,客户端会包含一个 Thrift 生成的库,用于与后端进行高效通信。

Thrift 的核心组成部分

要理解 Thrift 的工作方式,需要了解它的三个主要组成部分:

  1. Thrift IDL (接口定义语言)

    • 文件扩展名为 .thrift

    • 用于定义数据结构(struct)和服务的接口(service)。

    • 示例 (user_service.thrift):

      namespace java com.example.user
      // 定义一个数据结构
      struct User {
          1: i32 id,
          2: string name,
          3: string email
      }
      // 定义一个服务
      service UserService {
          // 获取用户信息
          User getUser(1: i32 userId),
          // 创建用户
          User createUser(1: User user)
      }
  2. Thrift 编译器

    • 一个命令行工具,读取 .thrift 文件。
    • 根据指定的目标语言(参数 -gen <language>),生成对应语言的客户端存根和服务端骨架代码。
    • 命令示例: thrift -gen java user_service.thrift
  3. 运行时库

    • 为每种语言提供的一套库,包含了处理底层的网络传输、数据序列化和反序列化的逻辑。
    • 开发者需要引入这些库,并基于编译器生成的代码来实现具体的业务逻辑。

Thrift vs. gRPC vs. RESTful API

在互联网公司,Thrift 并不是唯一的选择,它常常与 gRPC 和 RESTful API 进行比较。

特性 Thrift gRPC RESTful API (JSON)
协议 二进制 (Binary, Compact) 二进制 (HTTP/2 + Protobuf) 文本 (JSON, XML)
性能 非常高 非常高 较低 (文本解析开销大)
跨语言 非常好 (20+种) 非常好 (10+种) 非常好 (任何能解析HTTP的语言)
数据定义 Thrift IDL Protocol Buffers IDL 无需定义,基于 HTTP 方法
Web 友好 较差 (非浏览器原生支持) 较差 (需要特殊客户端) 极佳 (浏览器原生支持)
生态/工具 成熟,但生态略逊于 gRPC 非常活跃 (Google 主导) 极其庞大 (Web 生态标准)
主要用途 内部服务间通信,高性能 RPC 内部服务间通信,云原生 对外 API,Web/Mobile 前端

总结选择:

  • 选择 Thrift:当你主要在公司内部构建高性能的微服务,且服务团队使用多种编程语言时,Thrift 是一个成熟、稳定且高效的选择。
  • 选择 gRPC:当你同样需要内部服务间高性能通信,并且希望利用更现代的 HTTP/2 协议和更活跃的社区生态时,gRPC 目前是许多新项目的首选。
  • 选择 RESTful API:当你需要为外部开发者、Web 或移动 App 提供服务时,它的 Web 友好性和通用性是无与伦比的。

知名公司的使用案例

  • Facebook (创造者):内部广泛使用 Thrift 构建其庞大的服务架构。
  • Evernote:是其核心的跨服务通信框架。
  • Hadoop:HDFS 的 NameNode 和 DataNode 之间使用 Thrift 进行通信。
  • 阿里巴巴、腾讯、百度等国内大厂:在其早期或部分核心系统中,Thrift 也被大量采用,尤其是在 C++ 和 Java 混合的系统中,随着技术演进,许多公司也在逐步转向 gRPC。

面临的挑战与趋势

  • 挑战
    • Web 友好性差:浏览器无法直接调用 Thrift 服务,需要额外的代理层(如 HTTP
分享:
扫描分享到社交APP
上一篇
下一篇