ORACLE JAPAN Server Release 6.1

 

  |  

  WebLogic Server ホーム   |     WebLogic RMI   |   前へ   |   次へ   |   目次   |   索引   |   PDF 版

プログラミングの考慮事項

 

以下の節では、WebLogic Server で使用するための RMI のプログラミングで用いる WebLogic RMI の機能について説明します。

 


WebLogic RMI コンパイラ

WebLogic RMI コンパイラ(weblogic.rmic) は、クライアントサイドでカスタム リモート オブジェクト インタフェースのための動的プロキシを生成し、サーバサイド オブジェクトにホット コード生成を提供します。RMI オブジェクトがデプロイされている場合は、rmic を実行すると、実行時にホット コード生成機能によってバイトコードが動的に生成されます。

注意: クラスタ対応クライアントまたは IIOP クライアントの場合は、明示的に rmic を実行するだけです(WebLogic RMI over IIOP を使用すると、クライアントは、Internet Inter-ORB Protocol(IIOP)を介して RMI リモート オブジェクトにアクセスできるため、RMI プログラミング モデルが拡張されます)。RMI over IIOP の使用方法の詳細については、『WebLogic RMI over IIOP プログラマーズ ガイド』を参照してください。

動的プロキシ クラスは、クライアントに渡されるシリアライズ可能クラスです。ホット コード生成は、バイトコードを生成する RMI の機能です。このバイトコードは、クライアントの動的プロキシからの要求を処理するサーバサイド クラスです。クラスの実装は、Weblogic Server の RMI レジストリ内の名前に関連付けられます。

クライアントは、レジストリでクラスをルックアップすることによって、そのクラスのプロキシを取得します。クライアントは、あたかもローカルなクラスであるかのようにプロキシのメソッドを呼び出します。プロキシは、要求をシリアライズして WebLogic Server に送ります。動的に生成されたバイトコードはクライアント要求をデシリアライズし、実装クラスに対して実行します。次に結果をシリアライズしてクライアントのプロキシへ送り返します。

動的プロキシとバイトコード

WebLogic Server 6.1 より前のバージョンでは、rmic を実行すると、クライアントにはスタブが、サーバサイドにはスケルトン コードが生成されました。今回のバージョンでは、rmic は実行時にロードされる XML デプロイメント記述子を生成します。スタブの代わりに、クライアントは動的プロキシを使用してリモート オブジェクトと通信します。スケルトン クラスは必要時にメモリ内に作成されます。これにより、クラスの生成が不要になりました。

バージョン 6.1 より前の WebLogic RMI オブジェクトをバージョン 6.1 以降の WebLogic Server で実行できるようにするには、それらのオブジェクトに対して rmic を再度実行します。これにより、デプロイ済みの RMI オブジェクトを有効にする、必要なプロキシおよびバイトコードが生成されます。

リモート オブジェクトが EJB の場合は、weblogic.ejbc を再度実行すると、バージョン 6.1 より前の WebLogic Server オブジェクトがバージョン 6.1 以降で動作するようになります。weblogic.ejbc の使用方法の詳細については、『ebLogic エンタープライズ JavaBeans プログラマーズ ガイド』を参照してください。

リモート オブジェクトに対して weblogic.rmic または weblogic.ejbc を再度実行すると、そのオブジェクトのデプロイメント記述子ファイルが生成されます。

WebLogic RMI コンパイラのオプション

WebLogic RMI コンパイラは、Java コンパイラがサポートしているオプションをすべて受け入れます。たとえば、コマンド ラインのコンパイラ オプションに -d \classes examples.hello.HelloImpl を追加できます。ほかにも、Java コンパイラがサポートしているすべてのオプションを使用でき、これらのオプションは直接 Java コンパイラに渡されます。

次の表に、java weblogic.rmic オプションを示します。これらのオプションは、java weblogic.rmic の後、リモート クラス名の前に入力します。

表2-1 WebLogic RMI コンパイラのオプション

オプション

説明

-callRouter <callRouterClass>

-clusterable と組み合わせた場合だけ使用可能。ルーティング メソッド呼び出し用に使われるクラスを指定する。このクラスは weblogic.rmi.cluster.CallRouter を実装する必要がある。指定した場合、各メソッド呼び出しの前にそのクラスのインスタンスが呼び出され、そのメソッド パラメータに基づいてルーティングするサーバを指定できる。サーバ名または null が返される。null は現在のロード アルゴリズムが使用されることを示す。

-clusterable

そのサービスをクラスタ化可能(WebLogic クラスタ内の複数のサーバがホストできる)として指定する。各ホスティング オブジェクト、またはレプリカは、共通名でネーミング サービスにバインドされる。そのサービス プロキシがネーミング サービスから取り出される場合、それはレプリカのリストを保持するレプリカ対応参照を含み、レプリカ間のロード バランシングやフェイルオーバを行う。

-commentary

注釈を出力する。

-dispatchPolicy <queueName>

サービスが WebLogic Server の実行スレッドを取得するために使う、コンフィグレーション済みの実行キューを指定する。詳細については、「実行キューによるスレッド使用の制御」を参照。

-help

オプションの説明を表示する。

-idl

リモート インタフェース用の IDL を生成する。

-idlOverwrite

既存の IDL ファイルを上書きする。

-idlVerbose

IDL情報についての冗長な情報を表示する。

-idlStrict

OMG 規格に従って IDL を生成する。

-idlNoFactories

valuetype のファクトリ メソッドを生成しない。

-idlDirectory <idlDirectory>

IDL ファイルを作成するディレクトリを指定する(デフォルトはカレント ディレクトリ)。

-iiop

サーバから IIOP プロキシを生成する。

-iiopDirectory

IIOP プロキシ クラスが作成されるディレクトリを指定する。

-keepgenerated

WebLogic RMI コンパイラを実行するときに、生成したプロキシ クラスとバイトコードのソースを保持できる。

-loadAlgorithm <algorithm>

-clusterable と組み合わせた場合だけ使用可能。ロード バランシングおよびフェイルオーバに使用する特定のアルゴリズムのサービスを指定する(デフォルトは weblogic.cluster.loadAlgorithm)。ラウンドロビン、ランダム、重みベースの中から 1 つ選択できる。

-methodsAreIdempotent

-clusterable と組み合わせた場合だけ使用可能。このクラスのメソッドが多重呼び出し不変であることを示す。これにより、リモート メソッドが呼び出される前に起きた障害かどうか保証できなくても、通信障害があれば、プロキシはその復旧を試みることができるようになる。_デフォルトでは(このオプションが使われなければ)、プロキシはリモート メソッドが呼び出された前に起きたことが保証されている障害に関してだけ再試行する。

-nomanglednames

コンパイル時にリモート クラスに固有のプロキシが作成される。

-replicaListRefreshInterval <seconds>

-clusterable と組み合わせた場合だけ使用可能。クラスタのレプリカ リストをリフレッシュする試みの最小間隔を指定する(デフォルトは 180 秒)。

-stickToFirstServer

-clusterable と組み合わせた場合だけ使用可能。セッション維持型ロード バランシングを有効にする。最初の要求をサービスするために選ばれたサーバが、後続のすべての要求にも使用される。

-version

バージョン情報を出力する。

表2-2 クラスタ固有の WebLogic RMI コンパイラ オプション

オプション

説明

-callRouter <callRouterClass>

-clusterable と組み合わせた場合だけ使用可能。ルーティング メソッド呼び出し用に使われるクラスを指定する。このクラスは weblogic.rmi.cluster.CallRouter を実装する必要がある。指定した場合、各メソッド呼び出しの前にそのクラスのインスタンスが呼び出され、そのメソッド パラメータに基づいてルーティングするサーバを指定できる。サーバ名または null が返される。null は現在のロード アルゴリズムが使用されることを示す。

-clusterable

そのサービスをクラスタ化可能(WebLogic クラスタ内の複数のサーバがホストできる)として指定する。各ホスティング オブジェクト、またはレプリカは、共通名でネーミング サービスにバインドされる。そのサービス プロキシがネーミング サービスから取り出される場合、それはレプリカのリストを保持するレプリカ対応参照を含み、レプリカ間のロード バランシングやフェイルオーバを行う。

-loadAlgorithm <algorithm>

-clusterable と組み合わせた場合だけ使用可能。ロード バランシングおよびフェイルオーバに使用する特定のアルゴリズムのサービスを指定する(デフォルトは weblogic.cluster.loadAlgorithm)。ラウンドロビン、ランダム、重みベースの中から 1 つ選択できる。

ロード アルゴリズム名は、-clusterable と組み合せた場合だけ使用可能。ロード バランシングとフェイルオーバを処理するプロキシによって使用されるサービス固有のアルゴリズムを指定する。この引数を指定しない場合、Administration Console で指定されたデフォルトのロード バランシング アルゴリズムが使用される。たとえば、重みベースのロード バランシングを指定するには、次のコマンドを使用する。

$ java weblogic.rmic -clusterable -loadAlgorithm=weight-based

-methodsAreIdempotent

-clusterable と組み合せた場合だけ使用可能。同じメソッドを何度も実行することになる場合でも、フェイルオーバの後に再試行ができることをプロキシに指示する。このフラグを指定しない場合、このプロキシ用のメソッドは多重呼び出し不変とは見なされない。これによって扱われる例外については、「クラスタ化されたオブジェクトのフェイルオーバ」を参照。

-replicaListRefreshInterval <seconds>

-clusterable と組み合わせた場合だけ使用可能。クラスタのレプリカ リストをリフレッシュする試みの最小間隔を指定する(デフォルトは 180 秒)。

-stickToFirstServer

-clusterable と組み合わせた場合だけ使用可能。セッション維持型ロード バランシングを有効にする。最初の要求をサービスするために選ばれたサーバが、後続のすべての要求にも使用される。

クラスタにおけるスタブのレプリケーション

レプリケートされないスタブをクラスタ内に生成することもできます。このようなスタブは、「固定」サービスと呼ばれています。これらのスタブは登録されたホストからのみ使用可能であり、透過的なフェイルオーバやロード バランシングは提供しません。

weblogic.rmic でクラスタ化オプションを使用して RMI オブジェクトをコンパイルし、3 ノードのサーバ クラスタ(A、B、C)の 2 つのノード(A および B)にオブジェクトをデプロイし、バインドを 3 つのノードすべてにレプリケートする場合、各サーバから同じビューが得られます。3 つのノードすべてに対して JNDI ルックアップを行うと同じスタブが得られ、メソッド呼び出しを行うと、サーバは最初の 2 つのノード間でロード バランシングを実行します。

したがって、クラスタ化可能オプションを指定して RMI オブジェクトをコンパイルし、バインド セットのレプリケーションを「false」に設定してそれらのオブジェクトを JNDI ツリーにバインドする場合、JNDI ルックアップを行うと次の結果が得られます。

サーバ A に対してリモート呼び出しを行い、サーバが使用不可になっていることによって呼び出しが失敗する場合、クラスタ化可能スタブは再ルックアップを実行し、呼び出しのルーティング先に応じて次のいずれかの結果が発生します。

クラスタ非対応の RMI オブジェクトを、バインド セットのレプリケーションを false に設定して JNDI ツリーにバインドする場合、JNDI ルックアップを行うと、固定スタブが返されフェイルオーバは行われません。固定サービスは、レプリケートされたクラスタ全体の JNDI ツリーにバインドされるため、クラスタ全体で利用可能です。ただし、固定サービスのホストである個別のサーバで障害が発生すると、クライアントは別のサーバへのフェイルオーバを行うことができません。

クラスタ非対応の RMI オブジェクトを、バインド セットのレプリケーションを true に設定して JNDI ツリーにバインドすると、バインドは失敗します。その理由は、オブジェクトがクラスタ非対応であり、クラスタ内でクラスタ非対応のサービスを提供できるのは 1 つのサーバに限られるためです。

 


WebLogic RMI フレームワーク

WebLogic RMI はクライアントとサーバのフレームワークに分けられています。実行時のクライアントはサーバのソケットを持たないため、接続をリスンしていません。クライアントはサーバを介して接続を取得します。サーバだけがクライアントのソケットを認識します。このため、クライアントにあるリモート オブジェクトをホストする場合、クライアントは WebLogic Server に接続していなければなりません。WebLogic Server はクライアントへのリクエストを処理して、クライアントへ情報を渡します。つまり、クライアントサイドの RMI オブジェクトには、クラスタ内であっても単一の WebLogic Server を介してのみアクセスできます。クライアント サイドの RMI オブジェクトが JNDI ネーミング サービスにバインドされている場合、そのオブジェクトへのアクセスは、そのバインドを実行したサーバにアクセスできる場合に限り可能です。

WebLogic RMI コンパイラのその他の機能

WebLogic RMI コンパイラには、他にも以下のような機能があります。

 


RMI の動的プロキシ

動的プロキシまたはプロキシは、リモート オブジェクトのクライアントが使用するクラスです。このクラスは、作成されるときに、実行時に指定されたインタフェースのリストを実装します。

RMI では、動的に生成されたバイトコードとプロキシ クラスが使用されます。プロキシ クラスは、クライアントの Java 仮想マシン(JVM)で呼び出されるインスタンスです。プロキシ クラスは、呼び出されたメソッド名とその引数をマーシャリングして、リモートの JVM に転送します。リモート呼び出しが終了して返された後に、プロキシ クラスはクライアント上でその結果のマーシャリングを解除します。生成されたバイトコードはリモート JVM に存在し、リモート JVM 上で呼び出されたメソッドと引数のマーシャリングを解除し、リモート オブジェクトのインスタンスのメソッドを呼び出した後、結果をマーシャリングしてクライアントに返します。

WebLogic RMI コンパイラとプロキシの使い方

WebLogic RMI コンパイラは、デフォルトの動作により、リモート インタフェース用のプロキシと、そのプロキシを共有するリモート クラス用のプロキシを作成します。プロキシは、リモート オブジェクトのクライアントが使用するクラスです。RMI では、動的に生成されたバイトコードとプロキシ クラスが使用されます。

たとえば、WebLogic RMI コンパイラでは、example.hello.HelloImplcounter.example.CiaoImpl は、一対のプロキシ クラスとバイトコード、つまりリモート オブジェクト(このサンプルでは example.hello.Hello)によって実装されたリモート インタフェースに適合するプロキシで表わされます。

リモート オブジェクトが複数のインタフェースを実装する場合、プロキシの名前とパッケージは 1 組のインタフェースをエンコードすることによって決定されます。WebLogic RMI コンパイラの -nomanglednames というオプションを使って、デフォルトの動作をオーバーライドできます。このオプションを使用すると、コンパイル時にリモート クラスに固有のプロキシが作成されます。クラス固有のプロキシが検出された場合は、そのプロキシはインタフェース固有のプロキシに優先します。

さらに、WebLogic RMI のプロキシ クラスでは、プロキシは final ではありません。同じ場所に配置されたリモート オブジェクトへの参照は、プロキシではなくオブジェクトそのものへの参照です。

 


ホット コード生成

rmic を実行すると、WebLogic Server のホット コード生成機能により、メモリ内にサーバ クラス用のバイトコードが自動生成されます。バイトコードは、リモート オブジェクトの必要に応じて、動的に生成されます。現在のバージョンの WebLogic Server では、weblogic.rmic を実行しても、オブジェクトのスケルトン クラスは生成されません。

 


WebLogic RMI レジストリ

WebLogic Server は、RMI レジストリのホストとなり、RMI クライアント用のサーバ インフラストラクチャを提供します。レジストリ トラフィックは JDBC などのトラフィックと同じ接続で多重化されるので、RMI レジストリとサーバの通信オーバーヘッドは最小限に抑えられます。クライアントは RMI 用に単一のソケットを使用します。このため、WebLogic 環境での RMI クライアントのスケーラビリティは直線的です。

WebLogic RMI レジストリは WebLogic Server の起動時に作成され、新しいレジストリを作成するための呼び出しを行うだけで既存のレジストリの位置を見つけることができます。レジストリにバインドされているオブジェクトには、標準の rmi:// のほかに、http:// や https:// などのクライアント プロトコルを使ってアクセスできます。実際のところ、すべてのネーミング サービスで JNDI が使用されます。

 


WebLogic RMI 実装の機能

一般に、java.rmi パッケージに含まれているすべてのメソッドと同じ機能のメソッドが WebLogic RMI で提供されています(RMIClassLoader 内のメソッドと java.rmi.server.RemoteServer.getClientHost() メソッドを除く)。

他のすべてのインタフェース、例外、およびクラスは WebLogic RMI でサポートされています。以下の節に、特定の実装に関する注意事項を示します。

JNDI

WebLogic RMI では、オブジェクトのネーミングの望ましいメカニズムとして、Java Naming and Directory Interface(JDNI)を使用します。JNDI は、Java アプリケーションにネーミング サービスを提供するアプリケーション プログラミング インタフェース(API)です。JNDI は、Sun Microsystems の Java 2 Enterprise Edition(J2EE)技術の不可欠なコンポーネントです。ネーミング サービスは名前をオブジェクトに関連付けて、指定された名前に基づいてオブジェクトを見つけます(RMI レジストリは、ネーミング サービスの一例です)。

RMI で JNDI を使用すると、より効率的に分散プログラミングを行うことができます。ただし、リモート クライアントとサーバ間の往復回数には注意する必要があります。クライアントとサーバ間で JNDI ルックアップが繰り返されると、パフォーマンス上の問題が発生する場合があります。

rmi.RMISecurityManager

rmi.RMI SecurityManager は非最終クラスとして実装され、すべてのパブリック メソッドが WebLogic RMI でサポートされます。制約のある JavaSoft 参照実装とは異なり、まったく制約がありません。WebLogic RMI のセキュリティはより大きな WebLogic 環境の重要な一部で、SSL (Secure Socket Layer)と ACL (アクセス制御リスト)がサポートされています。

rmi.registry.LocateRegistry

rmi.registry.LocateRegistry は最終クラスとして実装され、すべてのパブリック メソッドがサポートされます。ただし、LocateRegistry.createRegistry(int port) を呼び出すと、レジストリが同じ場所に作成されるのではなく、JNDI を実装するサーバサイド インスタンスへの接続が試みられます。JNDI には属性によってホストとポートが指定されます。WebLogic RMI では、クライアントは、このメソッドを呼び出して WebLogic Server 上の JNDI ツリーを検索できます。

注意: デフォルト(rmi)以外のプロトコルを使うことも可能で、次に示すように方式、ホスト、およびポートを URL として使うこともできます。

LocateRegistry.getRegistry(https://localhost:7002);

この例では、標準 SSL WebLogic プロトコルを使用してローカル ホスト上のポート 7002 にある WebLogic Server レジストリの位置を検索します。

rmi.server クラス

rmi.server.LogStream は、write(byte[]) メソッドが WebLogic Server のログ ファイルを通してメッセージを記録する点で JavaSoft 参照実装とは異なります。

rmi.server.RemoteObject は、UnicastRemoteObject と同じ型を保存するために WebLogic RMI に実装されますが、その機能は WebLogic RMI の基本クラスである proxy によって提供されます。

rmi.server.RemoteServer は、rmi.server.UnicastRemoteObject の抽象スーパークラスとして実装され、getClientHost() を除くすべてのパブリック メソッドが WebLogic RMI でサポートされています。

rmi.server.UnicastRemoteObject は、リモート オブジェクトの基本クラスとして実装され、このクラスのすべてのメソッドは WebLogic RMI の基本クラスである Proxy という名前で実装されます。この結果、プロキシは final ではない Object メソッドをオーバーライドでき、実装についてまったく条件を付けずにこれらのメソッドを実装したのと同じ状態になります。

WebLogic RMI では、呼び出し側のオブジェクトが RMI オブジェクトと同じ Java 仮想マシン(JVM)内に存在しない場合、メソッド パラメータはすべて値渡しです。存在する場合、メソッド パラメータは参照渡しです。

注意: WebLogic RMI は、クライアントからのクラスのアップロードをサポートしません。つまり、リモート オブジェクトに渡されるどのクラスも、サーバの CLASSPATH 内に存在しなければなりません。

setSecurityManager

setSecurityManager() メソッドは、コンパイルの互換性を保持するためだけに WebLogic RMI に組み込まれています。WebLogic RMI は WebLogic Server 内のより一般的なセキュリティ モデルに依存しているため、このメソッドにはセキュリティは関連付けられていません。セキュリティ マネージャを設定する場合、1 つしか設定できません。セキュリティ マネージャを設定する前に、セキュリティ マネージャが既に設定されているかどうかをテストする必要があります。セキュリティ マネージャを重複して設定しようとすると、例外が送出されます。次に例を示します。

if (System.getSecurityManager() == null)

使用されないクラス

System.setSecurityManager(new RMISecurityManager());

以下のクラスは、実装されていますが、WebLogic RMI では使用されません。

 


RMI と T3 プロトコル

WebLogic Server における RMI 通信では、T3 プロトコルが使用されます。T3 は、WebLogic Server とそれ以外の Java プログラム (クライアントや他の WebLogic Server など) の間でのデータ転送に用いられる最適化されたプロトコルです。 サーバ インスタンスは、接続先の各 Java 仮想マシン (JVM) の動作を追跡し、JVM のすべてのトラフィックを伝送するための T3 接続を 1 つだけ作成します。

たとえば、Java クライアントが WebLogic Server 上のエンタープライズ Bean や JDBC 接続プールにアクセスする場合、WebLogic Server の JVM とクライアントの JVM との間に単一のネットワーク接続が確立されます。T3 プロトコルでは、単一接続上のパケットが目に見えない形で多重化されるため、あたかも専用のネットワーク接続を独占的に使用しているかのように、EJB サービスや JDBC サービスを記述することができます。

有効な T3 接続が確立された任意の 2 つの Java プログラム (たとえば、2 つのサーバ インスタンスや、サーバ インスタンスと Java クライアント) では、ポイント ツー ポイントの定期的な「ハートビート」を使用して、自分が引き続き利用可能であることの通知や、相手が利用可能かどうかの判断を行います。各エンドポイントでは、ピア (通信相手) に定期的にハートビートを送ると共に、ピアから引き続きハートビートを受信しているかどうかでピアがまだ利用可能かどうかを判断します。

サーバ インスタンスがハートビートを出す頻度は、ハートビート間隔で決まります。デフォルトでは 60 秒です。

ピアから何回ハートビートが届かなかったらピアが利用できないとサーバ インスタンス側が判断するかは、ハートビート タイムアウト期間で決まります。デフォルトでは 4 です。

したがって、各サーバ インスタンスでは、ピアからメッセージ (ハートビートかそれ以外の通信) がない場合、最大 240 秒間すなわち 4 分間待ってから、ピアが到達不能と判断します。

タイムアウトのデフォルト設定を変更することはお勧めしません。

 

back to top previous page next page