2016-11-29 5 views
0

私は、ネットワーク経由でサーバー間を移動する必要があるhashMapを持っています。ソケットバッファで提供される制限を超えてサイズが増加すると、次の例外がスローされます。 weblogic.socket.MaxMessageSizeExceededException:によって引き起こさWeblogic 11gサーバーのネットワーク上でhashMapを送信中に圧縮を実装します

サイズの受信メッセージ: '3002880' バイトの構成された最大値を超え: '3000000' はプロトコルのバイト: 'T3'

はそれをグーグルものの私は、ソケットのサイズを増やす必要があることを発見しましたが、これはそのような良い解決策ではないので、必要ではありません。

次に、 "DeflaterOutputStream/InflaterInputStream"を使用して送信する前に、HashMapを圧縮しようとしています。しかし、ここでの課題は、 "ObjectOutputStream"オブジェクトがweblogicクラスによって作成され、圧縮処理を行うためにObjectOutputStreamを作成しようとしているときにdeflater/Inflaterストリームが埋め込まれることです。

これを行う方法はありますか?

また、weblogicが自動的に圧縮を使用するt3プロトコルで圧縮を有効にする方法もあります。私はそれがt3プロトコルで可能かどうかについていくつかの研究を行ったが、t3プロトコルはこれをサポートしていないようだ。しかし、私はweblogicの新しいバージョンがこれをサポートするかどうかは分かりません。

また、「ソケットバッファサイズ」のチャンクにHashMapを分割することも考えていましたが、既存のデザインを変更する必要があり、今のところ好まれません。

ご意見をお寄せください。

+0

3000000はあなたのためにいくつかの聖なる限界ですか?もしそうでなければ、これを修正することができれば、 'System.setProperty(" weblogic.MaxMessageSize "、" BiggerValueAsString ")'を試すことができます。 https://blogs.oracle.com/LuzMestre/entry/how_to_fix_weblogic_socket – patrik

+0

@patrikの詳細については、実際に私たちのチームは解決策を求めていません。データが増えるたびにすぐにサイズを設定する必要があります。 –

答えて

1

HashMapに今後さらに多くのデータが含まれる可能性がある場合は、圧縮することも一時的な解決策にすぎません。永続的に解決する方法は、マップに項目が多すぎる場合は、リクエストを複数のリクエストに分割することです。

+0

私は90%まで圧縮することができます。だから、100 MBまでのデータは、ソケットバッファ上のメモリを要求せずに、バッファサイズが10 Mbのsソケット経由で送信することができます。 –

1

マップを別のオブジェクトにラップすることができます。すべての通信を圧縮オブジェクトの一部にすることができます。

public class Payload<T extends Serializable> { 
    private T payload; 
    public Payload(T payload) { 
     this.payload = payload; 
    } 
    private T get() { 
     return payload; 
    } 

    public static final boolean ENABLE_COMPRESSION = BooleanUtils.toBooleanDefaultIfNull(BooleanUtils.toBooleanObject(System.getProperty("serialization.gzip.enabled")), true); 

    private void writeObject(ObjectOutputStream oos) throws IOException { 
     if (ENABLE_COMPRESSION) { 
      GZIPOutputStream zos = new GZIPOutputStream(oos, 65536); 
      ObjectOutputStream sender = new ObjectOutputStream(zos); 
      sender.writeObject(payload); 
      sender.flush(); 
      zos.finish(); 
     } else { 
      oos.defaultWriteObject(); 
     } 
    } 

    @SuppressWarnings("unchecked") 
    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { 
     if (ENABLE_COMPRESSION) { 
      GZIPInputStream zis = new GZIPInputStream(ois, 65536); 
      ObjectInputStream receiver = new ObjectInputStream(zis); 
      payload = (T) receiver.readObject(); 
     } else { 
      ois.defaultReadObject(); 
     } 
    } 
} 

オブジェクトを送信すると、ペイロードオブジェクト内にラップされて送信され、圧縮されます。

public Payload<Map> someRemoteCall() { 
    Map map = new HashMap(); 
    populate(map); // do whatever needs to be done to fill up the map. 
    Payload<Map> payload = new Payload<Map>(map); 
    return payload; 
} 

明らかにそれは望ましくないかもしれインターフェースにいくつかの変更を伴うことが、これまでのところ、それは私がこれを見つけたのが最善です。

これが役に立ちます。

関連する問題