在不同机器上跨服务器 运行 转发 Thrift 服务请求

Forwarding Thrift service requests across servers running on different machines

我的 Mac 上有一个 Ubuntu 服务器 运行,Ubuntu 和 Mac 上都有 Thrift 服务器 运行。每个 Thrift 服务器提供的服务是不同的。

限制是我只需要向客户端公开 Mac Thrift 服务器 IP 和端口。

有什么方法可以将来自客户端的请求从 Mac thrift 服务器转发到 ubuntu 服务器?或者就此而言,是否可以让任何其他经纪人根据所请求的服务进行转发?

当然可以。我想到了至少三种方法。这主要取决于 API 的设计方式以及您是否能够更改它。

方法一:朴素的方法

如果您不能或不愿更改 API,则非常方便。每个请求处理函数只是将数据转发给另一个,但在其他方面完全相似的服务,它们共享相同的 Thrift IDL 定义。与响应相同。实现起来非常简单,但效率可能较低,因为消息需要在代理上解码和编码,这需要代理始终保持最新并了解旧版本 API.

方法 2:更通用

为了避免在代理上实现每个 API 功能只是为了做一些愚蠢的数据混洗,特别是当 API 将随着时间的推移而发展时,可以将所有请求和响应放在一起进入一些通用包装器 union,就像这样,让您只需要一个 API 调用,这也很容易在代理上实现:

union AllRequests {
  1: FooRequest foo
  2: BarRequest bar
  // more as needed
}


union AllResponses {
  1: FooResponse foo
  2: BarResponse bar
  // more as needed
}

service Fowarding {
    AllResponses  HandleRequest( 1: AllRequests request)
}

消息仍然需要在代理上进行解码和编码,另外还要考虑 IDL 版本控制的相同问题。此外,数据格式非常正式,但这其实未必是坏事。如果有一天您想要切换到 MQ 系统,或者如果您计划 record/playback 使用 Thrift 序列化进行服务调用,无论如何这都是可行的方法。

方法 3:嵌套序列化

有效负载消息可以序列化为 BLOB,然后发送到代理服务器,代理服务器将其转发到最终目的地。

service Fowarding {
    binary  HandleRequest( 1: binary request)
}

这里最大的好处是,代理不需要知道二进制数据中的内容。这对他来说是完全透明的。这也意味着,代理甚至不需要知道用于序列化这些数据的 IDL。最后同样重要的是,它还允许向二进制数据添加一些元数据,如果需要优化路由 and/or 处理:

struct BinaryRequest {
  1: binary data
  2: string preferredRoute
}

付出的代价显然是双重序列化开销。