在 Apache Thrift 中多路复用时 IDL 中的服务可组合性

Service composability in IDL when multiplexing in Apache Thrift

既然Apache Thrift支持服务多路复用,我想知道是否可以像这样组合服务

service A {
  int methodA(1: int param)
}

service B
{ 
   A serviceAProxy,
   int methodB(1: int param)
}

有没有办法针对生成的客户端代码实现这种效果,即。第二个服务只能通过调用第一个服务来检索?

ServiceBClient.GetServiceAProxy().MethodA()

不,你不能那样做,至少不能那样做。这是因为一方面是服务和方法,另一方面是数据结构是两种完全不同的动物。没有这样的内置数据类型允许您将 service 作为数据字段。

不过,东西并没有丢。您有很多选择来实现所需的行为。为了方便起见,我将在下面调用 service A 内部服务 service B 外部服务

示例:限制对内部服务的访问

设计内部服务,使每个方法调用都需要一个可以检查有效性的令牌。令牌仅在有限的时间范围内有效,必须先通过调用外部服务来获取:

service Outer {
   AccessToken IssueToken( 1: Credentials creds)
}

service Inner {
   void DoSomething( 1: AccessToken token, 2: other args) 
        throws (1: AccessDenied ade)
   i32  DoSomethingElse( 1: AccessToken token) 
        throws (1: AccessDenied ade, 2: MyOtherError moe)
}

AccessTokenCredentials 等看起来如何完全取决于您。它们只是上面的占位符,它们甚至可能只包含一个普通的字符串字段。

示例:获取内部服务的当前位置

在某些情况下,随着时间的推移,内部服务可能位于不同的物理服务器上。这可能出于各种原因,例如实现某种负载平衡,或建立集中式服务目录,其中客户端事先不知道 InnerService 的确切位置。他们只知道,去哪里问。

service Outer {
   LocationInfo QueryBestServiceLocation( 1: string serviceName) 
                throws (1 : UnknownService use)
   list<LocationInfo> QueryAllServiceLocations( 1: string serviceName) 
                throws (1 : UnknownService use)
}

service Inner {
   void DoSomething( ...)  throws ( ...)
   i32 DoSomethingElse( ...)  throws ( ...)
}

同样,LocationInfo 只是任意数据结构的占位符。但是,我可能会补充一点,特别是对于 "service directory" 场景,已经有一些经过实战检验的产品,例如 Apache ZooKeeper,它们做得很好。但我想你明白了。

那么多路复用呢?

没那么多,真的。事实上,您无需多路复用即可实现上述所有功能。当您想要在多个服务之间共享一个 Thrift protocol/transport 堆栈时,多路复用就会发挥作用。这可能是一个套接字,它通过同一连接提供多种服务。