定义和访问RPC方法
Nameko的RPC是通过AMQP实现的。就像之前最小RPC服务示例中所展示的,一个RPC服务就是一个普通的类,其中需要使用name
属性来定义这个RPC服务的名称,并且使用@rpc
修饰器来修饰要暴露出去的方法。定义好的RPC服务类就可以通过Nameko的命令行托管运行了。例如有以下RPC服务的定义。
from nameko.rpc import rpc, RpcProxy
class ServiceB:
name = 'service_b'
@rpc
def remote_method(self, value):
return f'From ServiceB give you {value}'
class ServiceA:
name = 'service_a'
b = RpcProxy('service_b')
@rpc
def calling_another(self, value):
greeting = f'Greeting from ServiceA, {value}'
return self.b.remote_method(greeting)
对于RPC方法的访问一般有两种方法。第一种是使用RpcProxy
类创建一个目标RPC服务的代理,有这个代理来执行RPC方法。这种使用RpcProxy
类代理的方法通常在RPC服务类中使用,可以建立一个RPC服务对于其他RPC服务的依赖。另一种功能方法则是使用独立的代理类来调用RPC方法,这通常用在非RPC服务类中。这种独立的代理类还支持向一个RPC服务集群调用指定RPC方法。
在前面的示例中,已经在ServiceA
中使用了RpcProxy
类创建了ServiceB
的代理,并通过这个代理调用了ServiceB
暴露出来的方法。
对于独立代理类,Nameko在nameko.standalone.rpc
模块中提供了ClusterRpcProxy
和ServiceRpcProxy
两个类来使用RPC服务。ClusterRpcProxy
可以对存在与目前暴露在AMQP消息队列上的所有RPC服务进行代理,在建立代理时不需要指定RPC服务的名称。而ServiceRpcProxy
则是针对指定的一个RPC服务进行代理。这两个类在创建时都需要一个配置对象,其中至少要指定AMQP消息队列的连接。RPC服务代理进行RPC方法调用时,有同步和异步两种调用方式,具体使用方法请参考以下两种代理的使用示例。
from nameko.standalone.rpc import ClusterRpcProxy, ServiceRpcProxy
config = {
'AMQP_URI': 'amqp://guest:guest@localhost'
}
with ClusterRpcProxy(config) as cluster_rpc:
# 同步调用
result = cluster_rpc.service_a.calling_another('hello')
# 异步调用
calling = cluster_rpc.service_a.calling_another.call_async('hello')
result = calling.result() # .result()方法会一直阻塞到取得结果。
with ServiceRpcProxy('service_a', config) as service_rpc:
# 同步调用
result = service_rpc.calling_another('hello')
# 异步调用
calling = service_rpc.calling_another('hello')
result = calling.result()
需要注意的是,Nameko在进行RPC调用时,默认不会设置超时时间,如果目标RPC服务没有运行,那么整个RPC调用就会一直阻塞等待下去。如果使用timeout
参数设置了超时秒数,那么如果按时没有从目标RPC服务获得调用结果,就会抛出RpcTimeout
异常。如果调用了不存在的RPC服务,则会直接抛出UnknownService
异常。