我(可以)轻松地使用第三方库来处理Java RMI的序列化吗?

时间:2011-02-02 21:40:16

标签: java serialization rmi rpc

我非常喜欢通过Java的RMI调用远程方法的简单性,但其序列化格式的冗长是一个主要的嗡嗡声(是的,我有基准测试,谢谢)。在设计RPC(松散地说)组件时,Sun的架构师似乎做了明显正确的事情,但在实现序列化时却引发了史诗般的失败。

相反,似乎Thrift,Avro,Kryo(特别是),协议缓冲区(不是很多),等。的架构师在设计序列化格式时通常做了明显正确的事情,但要么不提供RPC机制,提供一个不必要的复杂(或不成熟)的机制,或者一个比调用远程方法更适合数据传输的机制(完全可以用于许多目的,但不是我正在寻找的)。 / p>

所以,显而易见的问题是:我如何使用RMI的方法调用可爱,但是使用上述库中的一个用于有线协议?如果没有大量工作,这可能吗?我是否过于严厉地评估上述库中的一个( NB 我非常不喜欢代码生成,一般来说;我不喜欢不必要的注释,而且XML配置相当多;任何类型的“bean”都会我畏缩 - 我不需要重量;理想情况下,我希望只为远程对象实现一个接口,就像使用RMI一样。)

4 个答案:

答案 0 :(得分:2)

曾几何时,我确实有同样的要求。我更改了rmi方法参数并将类型返回到byte []。

我用首选的序列化程序将对象序列化为字节数组,然后调用我修改过的rmi方法。

好吧,正如你提到的java序列化过于冗长,因此5年前我确实实现了一个节省空间的序列化算法。如果你发送一个非常复杂的对象图,它可以节省太多空间。最近,我必须将这个序列化实现移植到GWT,因为在Dev模式下GWT序列化速度非常慢。

作为一个例子;

rmi方法

public void saveEmployee(Employee emp){
  //business code
 }

你应该改变它,如下所示,

public void saveEmployee(byte[] empByte) {
        YourPreferredSerializer serialier =   YourPreferredSerializerFactory.creteSerializer();
        Employee emp = (Employee) serializer.deSerialize(empByte);
        //business code
    }

编辑:

您应该检查MessagePack。它看起来很有希望。

答案 1 :(得分:1)

我认为没有办法重新连接RMI,但可能是特定的替换项目 - 我特别想到DiRMI - 可能吗?和/或项目所有者可能有兴趣帮助解决这个问题(Brian,其作者,是来自Amazon.com的非常称职的s / w工程师)。

另一个有趣的项目是Protostuff - 它的作者也在构建一个RPC框架(我认为);但即使没有它支持一系列令人印象深刻的数据格式;并且这非常有效(根据https://github.com/eishay/jvm-serializers/wiki/)。

Btw,我个人认为大多数项目所犯的最大错误(如PB,Avro)并没有在RPC和序列化方面保持适当的分离。 因此,使用可插拔数据格式或序列化提供程序执行RPC的能力对我来说似乎是一个好主意。

答案 2 :(得分:1)

writeReplace()和readResolve()可能是最好的组合。强大的力量在右手中。

答案 3 :(得分:1)

Java序列化只是详细描述了它序列化的类和字段。总的来说,格式与XML一样“自我描述”。你可以实际覆盖它并用其他东西替换它。这就是writeClassDescriptor和readClassDescriptor方法的用途。 Dirmi重写了这些方法,因此它能够使用标准对象序列化,减少线路开销。

它的工作方式与其会话的工作方式有关。两个端点可能具有不同版本的对象,因此简单地丢弃类描述符将不起作用。而是交换附加数据(在后台),以便用特定于会话的标识符替换序列化描述符。在看到标识符时,检查查找表以找到描述符对象。因为数据是在后台交换的,所以在创建会话后以及每次第一次写入对象类型时都会有一个简短的“预热期”。

此时Dirmi无法更换电线格式。