Ice がクロスプラットフォーム RPC において歴史的に高い地位を占めていることは否定できませんが、Dubbo、protobuf、および ws プロトコルがますます成熟するにつれて、ice が排除されるのは避けられません。多くの実装を読んできました。将来の最適化スペースのために ws レストフル モードによって氷が絞られているように感じます。現段階では、duboo の残りの利点は、監視と分散クラスターの利点、および protobuf シリアル化の利点に加えてあります。この種の高い-visibility rpc は非表示になり、多くの使用価値があります。(個人的な意見), 以下は、ice 3.6 以降のクライアント最適化ツールの実装です。
package com.launch.lc_ice_pas.utils ; import Ice.Communicator ; import Ice.ObjectPrx ; import java.lang.reflect.Method ; import java.util.HashMap ; import java.util.Map ; /** * Ice使用側レジスタservice */ public class IceClientUtil { //エンティティ インスタンスに接続します。 private static volatile Communicator communication = null; //プロキシ インスタンスのコレクション。 プライベート静的 Map<Class , ObjectPrx> classObjectPrxMap =new HashMap<>() ; //コミュニケーターを使用する最も多くの時間。 private static volatile long lastAccessTimeTarge ; //子スレッドはコミュニケータの破棄を制御します。 private static volatile MonitorThread thread1 ; //100 秒以内に呼び出さずにコミュニケータを破棄します private static long idleTimeOutSeconds = 100 ; //静的属性を読み取る必要があり、これは接続する必要がある URL と IP、および接続の値ですDefault -h ... -p ...または IceGrid/Locator:tcp -h -p /**などのメソッド * ここは、依然として Ice を使用する必要がある同僚のための単なる意見参考です。 * @return */ public static Communicator getIceCommunictor () { if (コミュニケーター== null ) { synchronized (IceClientUtil.class ) { if ( communicationator == null ) { Ice.InitializationData initData = new Ice.InitializationData() ; // プロパティを設定 Ice communicationator Ice.Properties props = Ice.Util.createProperties ( ) ; //props.setProperty("Ice.Warn.Connections", "0"); ネットワーク接続と追跡を閉じます //props.setProperty("Ice.Trace.Protocol", "0"); ネットワーク接続と追跡 プロパティを閉じます.setProperty( "Ice.ThreadPool.Client.Size" ,"10" ) ; props.setProperty( "Ice.ThreadPool.Client.SizeMax" , "30" ) ; props.setProperty( "Ice.ThreadPool.Client.SizeWarn" , "20" ) ; initData。プロパティ= 小道具; コミュニケーター = Ice.Util. 初期化(initData) ; createMonitorThread () ; lastAccessTimeTarge = システム。_ currentTimeMillis () ; リターンコミュニケーター; } /** * コミュニケーターが重かったので監視します。使用しないときは閉じてください。閉じなければ、 * @param RemoveIf * / public static void closeCommunicator ( boolean RemoveIf ) と書かない こと で1mのスレッドメモリ{ synchronized (IceClientUtil.class) { if ( communicationator != null ) { safaShuatdown () ; thread1 .interrupt() ; if (removeIf && ! classObjectPrxMap .isEmpty()) { classObjectPrxMap .clear() ; } private static void safaShuatdown () { communicationator.shutdown() ; communicationator.destroy ( ) ; なく でき利用は3.6 * 作成のアダプテーション アダプタ;null =communicator なり ました、 * @param serviceCls pre class * @return * @throws IllegalAccessException * / public static ObjectPrx getServicePrx (文字列アドレス, クラスserviceCls) { ObjectPrxプロキシ = classObjectPrxMap .get(serviceCls) ; if (プロキシ != null ) { lastAccessTimeTarge = システム。currentTimeMillis () ; プロキシ を返します。 コミュニケーター com = getIceCommunictor () ; プロキシ = createIceProxy (アドレス、 com 、サービスCls) ; classObjectPrxMap .put(serviceCls , proxy) ; lastAccessTimeTarge = システム。現在の時間ミリス() ; プロキシ を返します。 } /** * * * @param ic1 には初期コミュニケーターがあります * @param serviceClsはオブジェクト prx を作成します * @return * @throws IllegalAccessException */ private static ObjectPrx createIceProxy (String address , Communicator ic1 , Class serviceCls) { ObjectPrx prx = null; // 文字列 claName = serviceCls.getName() ; // オブジェクト パスを取得 ObjectPrx base = ic1.stringToProxy(address) ; // プロキシ名を登録 try { /** * ここで、特定の ObjectHelper は ObjectPrx のサブクラスに属していますが、 * 親クラスにキャスト メソッドは ありません 。したがって、エンティティ Get all theメソッド in、つまり unchecekeCast では、通常の状況では、プロキシとして checkcast を使用します。 ※ checkcast はチェック受信が必要なオブジェクトのオブジェクト受信と変換を指定する必要があります。 ※しかし、内部で直接変換する過程で、自分でメソッドを書き直して変換を実行し、変換例外エラーを報告してしまいました。 * そのキャストメソッドでは、catch 例外の後、uncheckecast を使用して強制変換が行われ、hepler と prx を注入して checkcast に返す必要があります。 * 通常のプロキシに戻ります。 ※また、ここでは強制変換受信に特定の型を使用することができないため、uncheckeedcastを使用する必要があります。Objectprx インターフェイスにキャストして * を受け取り、自分で呼び出した場所に転送します。 */ prx = (ObjectPrx) クラス.forName(claName + "ヘルパー" ).newInstance() ; // ヘルパー メソッド m1 = null を取得します。 m1 = prx.getClass() . getDeclaredMethod( "uncheckedCast" , ObjectPrx.class ) ; prx = (ObjectPrx) m1.invoke(prx , Base) ; prx を返します。 } catch (例外 e) { e.printStackTrace() ; prx を返します。 } /** * この場所はコミュニケーターを破棄するために使用します */ private static void createMonitorThread () { スレッド 1 =新しいMonitorThread() ; thread1 .setDaemon( true ) ; thread1 .start() ; } static class MonitorThread extends Thread { @Override public void run () { while (!Thread. currentThread ().isInterrupted()) { try { Thread. スリープ( 10000 ) ; if ( lastAccessTimeTarge + idleTimeOutSeconds * 1000 < システム。currentTimeMillis ()) { closeCommunicator ( true ) ; catch InterruptedExceptione) { e.printStackTrace( ) ; } } } } }