我尝试将一些数据作为参数发送到使用Nameko和rabbitmq到微服务的远程过程时遇到奇怪的行为:
在名为project
的目录下构建3个文件的问题的简化:
serializer.py ,自定义json编码/解码对象
from enum import Enum
import json
from project.service import CustomEnum
class CustomEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, CustomEnum):
# return {'__enum__': str(o)}
return {'__enum__': o.name}
return {'__{}__'.format(o.__class__.__name__): o.__dict__}
class CustomDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
json.JSONDecoder.__init__(self,
object_hook=self.object_hook,
*args, **kwargs)
def object_hook(self, o):
if '__enum__' in o:
return CustomEnum[o['__enum__']]
# name, member = o['__enum__'].split('.')
# return getattr(ENUMS[name], member)
return o
service.py ,基本的微服务
from enum import Enum
from nameko.rpc import rpc
import json
from project.serializer import CustomDecoder
class CustomEnum(Enum):
A = 0
B = 1
class Service(object):
name = "service"
@rpc
def get_enum(self, enum_type):
enum_type = json.loads(enum_type, cls=CustomDecoder)
if enum_type == CustomEnum.A:
return "A"
elif enum_type == CustomEnum.B:
return "B"
return "NO ENUM"
Nameko shell 在按照以下步骤启动RabbitMQ docker实例和nameko运行服务后试用:
$ docker run -d --hostname rabbit --name my-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management
$ nameko run project.service --broker amqp://guest:guest@localhost
$ nameko shell --broker amqp://guest:guest@localhost
测试后的shell输出:
In [1]: import json
In [2]: from project.serializer import CustomEncoder
In [3]: from project.service import CustomEncoder
In [4]: serialized = json.dumps(CustomEnum.A, cls=CustomEncoder)
In [5]: n.rpc.service.get_enum(serialized)
NO ENUM
似乎在远程过程type(enum_type) == type(CustomEnum)
上反序列化后给出 False ,在nameko shell中尝试它时,它完全序列化并反序列化枚举子类类型。
它可能与nameko本身序列化已经序列化的数据有关吗?我知道我应该将自定义序列化程序注册到kombu.serialization.register
,但我仍然坚持这一点,我想知道为什么会这样。