我们正在使用LMAX Disruptor构建一个应用程序。使用Event Sourcing时,您通常希望保留域模型的定期快照(有些人称之为内存映像模式)。
在拍摄快照时,我需要一个比我们目前用来序列化域模型的解决方案更好的解决方案。我希望能够以可读格式“漂亮地打印”此快照以进行调试,并且我希望简化快照模式迁移。
目前,我们正在使用Google 的 Protocol Buffers将我们的域模型序列化为文件。我们选择了这个解决方案,因为协议缓冲区比 XML/JSON 更紧凑,并且使用紧凑的二进制格式似乎是序列化大型 Java 域模型的好主意。
问题是,Protocol Buffers 是为相对较小的消息设计的,而我们的域模型非常大。所以域模型不适合一个大的分层 protobuf 消息,我们最终将各种 protobuf 消息序列化到一个文件中,如下所示:
for each account {
write simple account fields (id, name, description) as one protobuf message
write number of user groups
for each user group {
convert user group to protobuf message, and serialize it
}
for each user {
convert user to protobuf message, and serialize it
}
for each sensor {
convert sensor to protobuf message, and serialize it
}
...
}
这很烦人,因为处理异构 protobuf 消息流很复杂。如果我们有一个包含我们所有域模型的大 protobuf 消息会容易得多,如下所示:
public class AggregateRoot {
List<Account> accounts;
}
--> convert to big hierarchical protobuf message using some mapping code:
message AggregateRootMessage {
repeated AccountMessage accounts = 1;
}
--> persist this big message to a file
如果我们这样做,很容易漂亮地打印快照:只需阅读大的 protobuf 消息,然后使用 protobuf 的TextFormat进行漂亮打印。使用我们当前的方法,我们需要一一读取各种 protobuf 消息,并漂亮地打印它们,这更难,因为流中 protobuf 消息的顺序取决于当前的快照模式,所以我们的漂亮打印工具需要意识到这一点。
当我们的域模型发展时,我还需要一个工具来将快照迁移到新的快照模式。我仍在研究这个工具,但这很难,因为我必须处理各种 protobuf 消息流,而不是只处理一个大消息。如果它只是一个大消息,我可以: - 获取快照文件 - 将文件解析为大 Java protobuf 消息,使用以前快照版本的 .proto 模式 - 将这个大 protobuf 消息转换为大 protobuf 消息新版本,使用 Dozer 和一些映射代码 - 将此新 protobuf 消息写入新文件,使用新版本的 .proto 模式
但是由于我正在处理各种类型的 protobuf 消息流,因此我的工具需要以正确的顺序处理此流。
所以,是的......我想我的问题是:
您是否知道任何可以将大型域模型序列化为文件的序列化工具,没有 protobuf 的限制,可能使用流式传输来避免 OutOfMemoryErrors?
如果你使用事件溯源或内存图像,你用什么来序列化你的域模型?JSON?XML?原型?还有什么?
我们做错了吗?你有什么建议吗?