我在尝试使用 Nameko 和 rabbitmq 序列化一些数据以作为参数发送到远程过程到微服务时遇到了一种奇怪的行为:
在名为 的目录下将问题简化为 3 个文件project
:
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"
在启动 rabbitMQ docker 实例和 nameko 运行服务后,请按照以下步骤试用Nameko shell :
$ 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 中尝试它时,它完美地序列化和反序列化 enum 子类类型。这可能与nameko本身对已序列化数据的序列化有关吗?我知道我应该将自定义序列化程序注册到,kombu.serialization.register
但我坚持这一点,我想知道为什么会发生这种情况。