2011-02-02 1 views
3

JavaのRMIを使用してリモートメソッドを呼び出すことが非常に簡単ですが、シリアライズフォーマットの冗長性は大きなバズです(ありがとう、私はベンチマークしました)。 Sunのアーキテクトは、RPC(疎結合)コンポーネントを設計する際に明らかに正しいことをしたようだが、シリアライゼーションの実装には壮大な失敗を引き起こした。Java RMIのシリアル化を処理するためにサードパーティのライブラリを(簡単に)使用できますか?

逆に、シリアライズフォーマットを設計する際には明らかに正しいことがありましたが、 RPCメカニズムでは、不必要に畳み込まれた(または未熟な)もの、あるいはリモートメソッドを呼び出すものよりもデータ転送の方が優れているものを提供します(多くの目的では完璧ですが、私が探しているものではありません)。

RMIのメソッド呼び出しの魅力をどのように使用できますか?上記のライブラリの1つをワイヤプロトコルに使用するにはどうすればよいのでしょうか?これは多くの仕事なしで可能ですか?私は前述の図書館のうちの1つをあまりにも厳しく評価しています(NB私は非常に多くのコード生成を嫌い、一般的には不要な注釈を少し嫌いですが、XML設定はかなり多少なりともあります。理想的には、RMIのようにリモートオブジェクトのインタフェースを実装するだけです。

+0

私は、Kryoではなく、あなたが言及している多くのlibsの主な課題は、スキーマの定義を必要とすることで、POJO RPCの汎用的な使用を困難または不可能にしていることです。 – StaxMan

+0

高速シリアル化は、JDKシリアル化互換の再実装です。しかし、ObjectXXXputStreamクラスを置き換えるために必要なフックがあるかどうかはわかりません。 https://github.com/RuedigerMoeller/fast-serialization –

答えて

2

以前はいつも同じ要件がありました。私はrmiのメソッドの引数と型をbyte []に​​変更しました。

私は好みのシリアライザでオブジェクトをバイト配列にシリアル化した後、変更されたrmiメソッドと呼ばれていました。

あなたが言ったように、javaのシリアライゼーションはあまりにも冗長です。したがって、5年前に私はスペース効率の高いシリアライゼーションアルゴリズムを実装しました。非常に複雑なオブジェクトグラフを送信すると、あまりにも多くのスペースを節約できます。最近、DevモードのGWTシリアル化が非常に遅いため、このシリアル化実装を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 
    } 

はEDIT:

あなたはMessagePackをチェックする必要があります。それは有望に見えます。

+0

これは興味深いものです。もう少し詳しく説明できますか? – user359996

+0

(おそらく、ここではバイト[]とExternalizableのカスタムを比較するのが面白いかもしれませんが)パフォーマンスには妥当かもしれませんが、あなたのリモートインターフェースはバイトの[]になります。これは間違いなく、世界で最もフレンドリーなインターフェースではありません。 – Matt

+0

さて、あなたは正しいです。これは欠点です.. :)あなたがシリアライズしなければならないドメインクラスがあまりにも多い場合、外部化可能なインターフェースはオプションではありません。 –

1

私はRMIを再配線する方法はないと思いますが、それは具体的な代替プロジェクトかもしれません - 具体的にはDiRMIを考えていますか?そして/またはプロジェクトオーナーがこれを手助けすることに興味を持っているかもしれません(Brian、その作者はAmazon.comの非常に有能なs/wエンジニアです)。

もう1つの興味深いプロジェクトはProtostuffです。その著者もRPCフレームワークを構築しています(私は思っています)。それがなくても、印象的な範囲のデータ形式をサポートします。これを非常に効率的に実行します(https://github.com/eishay/jvm-serializers/wiki/)。

Btw、私は個人的には、ほとんどのプロジェクト(PB、Avroなど)がRPCとシリアル化の面を適切に分離していないという最大の間違いがあると思います。 プラグ可能なデータ形式やシリアル化プロバイダを使用してRPCを実行する能力は、私にとっては良い考えです。

+1

+1「私は個人的には、ほとんどのプロジェクト(PB、Avroなど)がRPCとシリアル化の側面を適切に分離していない最大の間違いを考える」 - マインド! – user359996

+0

Hehe。ごめんなさい! :) – StaxMan

+0

Externalizableインターフェイスを実装することで、RMIを若干再配線することができますが、これはややこしいことです。おそらくrmi-iiopも同様の利点を提供する可能性があります。 – nos

1

writeReplace()とreadResolve()はおそらくこれを行うための最良のコンボです。マイティは右手で強力です。

1

Javaのシリアライゼーションは、シリアライズするクラスとフィールドを説明するところでのみ冗長です。全体として、フォーマットはXMLとして「自己記述」しています。実際にはこれをオーバーライドして別のものに置き換えることができます。これは、writeClassDescriptorメソッドとreadClassDescriptorメソッドが対象となります。 Dirmiはこれらのメソッドをオーバーライドしているため、ワイヤオーバーヘッドの少ない標準オブジェクト直列化を使用できます。

動作の仕方は、セッションの仕組みに関連しています。両方のエンドポイントでオブジェクトのバージョンが異なる可能性があり、クラス記述子を放棄するだけでは機能しません。代わりに、シリアル化された記述子がセッション固有の識別子に置き換えられるように、追加のデータが(バックグラウンドで)交換されます。識別子を見ると、ルックアップテーブルが検査され、記述子オブジェクトが見つかる。データはバックグラウンドで交換されるため、セッションが作成された後、オブジェクトタイプが初めて書き込まれるたびに短いウォームアップ期間があります。

現在、Dirmiはワイヤフォーマットを置き換える方法がありません。

関連する問題