在 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)
}
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
只是任意数据结构的占位符。但是,我可能会补充一点,特别是对于 "service directory" 场景,已经有一些经过实战检验的产品,例如 Apache ZooKeeper,它们做得很好。但我想你明白了。
那么多路复用呢?
没那么多,真的。事实上,您无需多路复用即可实现上述所有功能。当您想要在多个服务之间共享一个 Thrift protocol/transport 堆栈时,多路复用就会发挥作用。这可能是一个套接字,它通过同一连接提供多种服务。
既然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)
}
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
只是任意数据结构的占位符。但是,我可能会补充一点,特别是对于 "service directory" 场景,已经有一些经过实战检验的产品,例如 Apache ZooKeeper,它们做得很好。但我想你明白了。
那么多路复用呢?
没那么多,真的。事实上,您无需多路复用即可实现上述所有功能。当您想要在多个服务之间共享一个 Thrift protocol/transport 堆栈时,多路复用就会发挥作用。这可能是一个套接字,它通过同一连接提供多种服务。