由于现在Apache Thrift支持服务多路复用,我想知道是否可以组成这样的服务
service A {
int methodA(1: int param)
}
service B
{
A serviceAProxy,
int methodB(1: int param)
}
是否有办法针对生成的客户端代码实现此效果,即。第二项服务只能通过拨打第一项服务来检索?
ServiceBClient.GetServiceAProxy().MethodA()
答案 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)
}
AccessToken
和Credentials
等等的外观完全取决于您。它们只是上面的占位符,它们甚至可能只包含一个普通的字符串字段。
在某些情况下,内部服务可能会随着时间的推移位于不同的物理服务器上。这可能是出于各种原因,例如实现某种负载平衡,或建立集中的服务目录,客户端事先不知道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协议/传输堆栈。这可以是一个套接字,它通过同一个连接提供多种服务。