我们正在使用LMAX消毒器构建一个应用程序。在使用事件源时,您通常希望持久化域模型的周期性快照(有些人称之为记忆图像模式)。
我需要一个更好的解决方案,而不是我们现在使用的在快照时序列化域模型的方法。我希望能够以可读的格式“打印”此快照,以便进行调试,并且我希望简化快照模式迁移。
目前,我们正在使用Google协议缓冲器将域模型序列化为一个文件。我们选择了这个解决方案,因为协议缓冲区比XML / JSON更紧凑,使用紧凑的二进制格式似乎是序列化大型Java域模型的好主意。
问题是,协议缓冲区是为相对较小的消息设计的,而且我们的域模型相当大。因此,域模型不适合于一个大的分层原型消息,我们最终将各种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原型消息,使用上一个快照版本的.proto模式--使用Dozer和一些映射代码将这个大原型消息转换为新版本的大原型消息--使用新版本的.proto模式在新文件中编写这个新的protobuf消息。
但是,由于我正在处理各种类型的protobuf消息流,所以我的工具需要以正确的顺序处理这个流。
所以,是的..。我想我的问题是:
发布于 2013-06-07 11:27:52
我定义问题解决方案的方法是将“规范”与“传输语法”分开。现在,我们已经定义了我们的消息规范,我们需要工作线线表示,这可能支持不同的需求,不同的机器效率和人的可读性;
解决方案必须提供可切换的行为。我们可以将我们的解决方案建立在ASN.1和相关工具集的基础上,该工具集与语言和平台无关,尽管Java提供了丰富的生态系统(Bouncycastle al)。我们已经在网络上使用了相当大的消息块,没有已知的问题:)
希望它能给出一些指点。
发布于 2013-06-03 20:51:35
从我的头顶(实际上不知道你的快照文件会有多大):
你试过谷歌的Gson库吗?它似乎同时为基于JSON的文档提供了版本控制(https://sites.google.com/site/gson/gson-user-guide#TOC-Versioning-Support)和流(https://sites.google.com/site/gson/streaming)。
现在我们讨论的是JSON,将快照存储在例如CouchDB (http://en.wikipedia.org/wiki/CouchDB)文档中如何?
JSON可能占用更多的空间,但它是可读的。
发布于 2013-06-07 02:21:30
我看到的最佳选项列表是:https://github.com/eishay/jvm-serializers/wiki。你必须做一些快速的测试,看看什么对你来说是快速的。关于流,我必须查看这个列表中的每个库。
我不确定我是否理解漂亮的印刷问题。用同样的技术解决高效的序列化和漂亮的打印似乎没有必要,因为漂亮的打印不一定要高效地完成。如果您已经有了一个javabean表示,那么我可能会将数据重新加载到bean中,然后使用Jackson将数据打印到JSON。
关于版本控制/迁移,您已经解决了如何启动运行新域模型的代码的新版本的问题了吗?如果是,那么为什么不只是在新版本启动后创建一个新快照呢?
https://stackoverflow.com/questions/16858850
复制相似问题