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

时间:2015-05-05 14:54:33

标签: thrift

由于现在Apache Thrift支持服务多路复用,我想知道是否可以组成这样的服务

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

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

是否有办法针对生成的客户端代码实现此效果,即。第二项服务只能通过拨打第一项服务来检索?

ServiceBClient.GetServiceAProxy().MethodA()

1 个答案:

答案 0 :(得分:1)

不,你不能这样做,至少不是那样。这是因为一方面服务和方法,另一方面数据结构是两种完全不同的动物。没有这样的内置数据类型允许您将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只是任意数据结构的占位符。我可能会补充一下,特别是对于“服务目录”场景,已经有一些经过实战考验的产品,比如Apache ZooKeeper,他们做得很好。但我认为你明白了。

那么多路复用呢?

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