1

我试图了解 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

而且我无法理解如何从微服务 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//

但是从 microservice1 调用 nameko shell 并运行 rpc 方法可以:

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

添加信息

按照马特的回答,我编辑了 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
4

2 回答 2

3

文档中有一个服务到服务 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)
于 2017-12-15T10:38:53.423 回答
2

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

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

于 2017-12-15T07:35:55.703 回答