Nameko - invoking RPC method from another service

匿名 (未验证) 提交于 2019-12-03 01:09:02

问题:

I am trying to understand how nameko works for basic RPC. I am looking to define microservices in separate files and being able to run them from command shell. With this structure service2 is not being able to invoke service1's RPC method. What is missing to get this working?

I have the following file structure:

-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 

Content of files are:

$ 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 

And I am not being able to understand how to invoke hello method in Microservice 1 from Microservice 2:

$ ./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// 

But invoking nameko shell and running rpc method from microservice1 works:

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

Added information

Following Matt's answer I have edited service2.py as follows:

# -*- 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 

Now both services run, But still does not work, when I run a namejo shell and invoke toctoc method from Microservice2:

$ 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' >>> 

Last working code

With the help provided in the answers, a working version of this would be (in case it clarifies/helps others):

$ 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 

回答1:

there's an example of service-to-service rpc in the docs

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) 


回答2:

The problem is that service2.py isn't valid. You can't invoke the RPC proxy outside of a service method.

If you want to call a running service from an external script, use the standalone proxy.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!