Nameko - 从另一个服务调用RPC方法

时间:2017-12-15 01:00:24

标签: python-2.7 nameko

我试图了解nameko如何为基本RPC工作。 我希望在单独的文件中定义微服务,并能够从命令shell运行它们。使用此结构,service2无法调用service1的RPC方法。让这个工作缺少什么?

我有以下文件结构:

-rwxrwxr-x 1 user user 240 Dec 15 01:49 nameko.sh*
-rw-rw-r-- 1 user user 251 Dec 15 01:46 service1.py
-rw-rw-r-- 1 user user 305 Dec 15 01:47 service2.py

文件内容为:

$ cat nameko.sh
#!/bin/bash
/usr/local/bin/nameko run service1:Microservice1 &
nameko_id=$!
echo 'Microservice 1 PID: ' $nameko_id
/usr/local/bin/nameko run service2:Microservice2 &
nameko_id=$!
echo 'Microservice 2 PID: ' $nameko_id
wait 2> /dev/null


$ cat service1.py
# -*- coding: utf-8 -*-
from nameko.rpc import rpc, RpcProxy
class Microservice1(object):
    name = "microservice1"
    @rpc
    def hello(self):
        print 'Microservice1 hello method invoked'
        return True

$ cat service2.py
# -*- coding: utf-8 -*-
from nameko.rpc import rpc, RpcProxy
class Microservice2(object):
    name = "microservice2"
    microservice1 = RpcProxy('microservice1')
    microservice1.hello()
    @rpc
    def hello(self):
        print 'Microservice2 hello method invoked'
        return True

我无法理解如何从Microservice 2中调用微服务1中的hello方法:

$ ./nameko.sh
Microservice 1 PID:  14782
Microservice 2 PID:  14783
Traceback (most recent call last):
  File "/usr/local/bin/nameko", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python2.7/dist-packages/nameko/cli/main.py", line 66, in main
    args.main(args)
  File "/usr/local/lib/python2.7/dist-packages/nameko/cli/commands.py", line 85, in main
starting services: microservice1
    main(args)
  File "/usr/local/lib/python2.7/dist-packages/nameko/cli/run.py", line 179, in main
    import_service(path)
  File "/usr/local/lib/python2.7/dist-packages/nameko/cli/run.py", line 46, in import_service
    __import__(module_name)
  File "./service2.py", line 5, in <module>
    class Microservice2(object):
  File "./service2.py", line 11, in Microservice2
    microservice1.hello()
AttributeError: 'RpcProxy' object has no attribute 'hello'
Connected to amqp://guest:**@127.0.0.1:5672//

但调用nameko shell并从microservice1运行rpc方法有效:

Broker: pyamqp://guest:guest@localhost
>>> n.rpc.microservice1.hello()
True
  

添加了信息

根据Matt的回答,我编辑了service2.py,如下所示:

# -*- coding: utf-8 -*-
from nameko.rpc import rpc, RpcProxy
class Microservice2(object):
    name = "microservice2"

    @rpc
    def toctoc(self):
        print 'Microservice2 called hello method from Microservice1'
        m1 = RpcProxy('microservice1')
        m1.hello()
        return True

现在两个服务都运行了,但是当我运行一个namejo shell并从Microservice2调用toctoc方法时仍然无法运行:

$ nameko shell
Nameko Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] shell on linux2
Broker: pyamqp://guest:guest@localhost
>>> n.rpc.microservice2.toctoc()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/nameko/rpc.py", line 374, in 
__call__
    return reply.result()
  File "/usr/local/lib/python2.7/dist-packages/nameko/rpc.py", line 332, in 
result
    raise deserialize(error)
RemoteError: AttributeError 'RpcProxy' object has no attribute 'hello'
>>>
  

上一个工作代码

根据答案中提供的帮助,这将是一个工作版本(如果它澄清/帮助其他人):

$ cat nameko.sh
#!/bin/bash
/usr/local/bin/nameko run service1:Microservice1 &
nameko_id=$!
echo 'Microservice 1 PID: ' $nameko_id
/usr/local/bin/nameko run service2:Microservice2 &
nameko_id=$!
echo 'Microservice 2 PID: ' $nameko_id
wait 2> /dev/null


$ cat service1.py
# -*- coding: utf-8 -*-
from nameko.rpc import rpc, RpcProxy
class Microservice1(object):
    name = "microservice1"
    @rpc
    def hello(self):
        print 'Microservice1 hello method invoked'
        return True

$ cat service2.py
# -*- coding: utf-8 -*-
from nameko.rpc import rpc, RpcProxy
class Microservice2(object):
    name = "microservice2"
    microservice1 = RpcProxy('microservice1')
    @rpc
    def remote_hello(self):
        print 'Microservice2 invokes hello method from Microservice1'
        self.microservice1.hello()
        return True

2 个答案:

答案 0 :(得分:2)

the docs

中有服务到服务rpc的示例
class ServiceX:
    name = "service_x"

    # this _declares_ the dependency (and triggers nameko to set things up)
    y = RpcProxy("service_y")


    # note that the proxy isn't usable until a service worker is
    # running, i.e. until you're inside an executing method
    # y.foo() <- this doesn't work. 

    @rpc
    def remote_method(self, value):
        res = u"{}-x".format(value)

        # this _invokes_ the dependency
        return self.y.append_identifier(res)

答案 1 :(得分:1)

问题是service2.py无效。您无法在服务方法之外调用RPC代理。

如果要从外部脚本调用正在运行的服务,请使用standalone代理。