Coherence開発環境作成

これは昨年からの備忘録です。。

開発対象のインフラターゲットは、RHEL+WebLogic12 + Coherence + OracleDB 12cという構成

開発環境
Windows7, Oracle Enterprise Pack for Eclipse(OEPE Luna)
OracleDB(開発用にOracleXE)は別途インストール

WebLogicは、管理サーバ自体にアプリケーションをデプロイするようになってました。
(管理対象サーバ追加の仕方がよくわからなかったので・・)

OracleのWebからOEPEをダウンロード
インストール後、
WLSの起動時の環境設定バッチ setDomainEnv.cmd に下記を追加

↓Coherence設定ファイル等を外出しにする為、WebLogic起動時の引数として設定してます
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dtangosol.coherence.distributed.localstorage=false
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dtangosol.coherence.override=c:\dev\bin\tangosol-coherence-override.xml
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dtangosol.coherence.cacheconfig=c:\dev\bin\cache-config.xml
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dtangosol.pof.enabled=true -Dtangosol.pof.config=c:\dev\bin\pof-config.xml

set CLASSPATH=%CLASSPATH%;C:\Oracle\Middleware\Oracle_Home\coherence\lib\coherence.jar

↑Coherenceがインストールされた場所にあるライブラリを指定

インフラターゲット側では管理対象サーバで動かすので、WebLogicコンソールから上記をJVM実行引数として追加すればOKでした

カテゴリー: Java

今どきのJavaRMI

とあるシステムのプロトタイプを去年作りました。
システム構成はAPサーバ(Weblogic)が複数台構成で、ある特定の処理を同期処理で1台のサーバだけで行わないといけないというもので、言語と実行環境はオールJAVAとの指定です。
その特定の処理を行うサーバとAPサーバ間の通信をどうしようかなと考えましたが、プロトタイプとはいえ、かなりミッションクリティカルかつ応答性能を求めるシステムで、また、拡張性や他の言語からの呼び出しなどは無視してよかったので、シンプルかつ、ミドルウェアレベルで昔から使われているRMIを採用してみました。実は最近の方式をよく知らないだけだったりしますが・・

こんな構成です。

RMI
ソース的には3つに分かれます

①インターフェースをクライアントとなるAPサーバと、「とある処理」サーバで動作させるモジュールのソースに含みます。ここでは処理要求・応答はByte配列を引数・戻りとして、クライアントからサーバへ処理要求を行います。

/**
* とある処理のRMIインターフェース
* */
public interface RequestReciever extends Remote {
  /** 処理要求
  * @param b 送信バイト配列
  * @return 応答結果バイト配列
  * */
  public byte[] req(byte[] b) throws RemoteException;

以下必要な処理をつらつら書いてますが省略

②APサーバ側の呼び出し部分抜粋です。

Registry registry;
registry = LocateRegistry.getRegistry({とある処理サーバのIPアドレス}, {待受ポート番号});
RequestReciever stub = (RequestReciever) registry.lookup("{とある処理を示す名前}");
{結果バイト配列} = stub.req({渡すバイト配列});

必要なのはこれだけ

③「とある処理」サーバ側のソースです

public class toaruPrcServer extends UnicastRemoteObject implements RequestReciever {
・・・中略
 public toaruPrcServer() throws RemoteException {
  public static void main(String[] args) {
   ・・・中略
   toaruPrcServer server = new toaruPrcServer();
   //Start RMI server
   Registry registry = LocateRegistry.createRegistry({待受ポート番号});
   registry.rebind("{とある処理を示す名前}", server);
  }
  @Override
  public byte[] req(byte[] b) throws RemoteException{
   byte[] res;
   ここに処理を書きます
   return res;
  }
以下、省略
 }
}

これだけでホントにシンプルです。
昔はリモートオブジェクトのエクスポートとかRMIレジストリ起動とか訳が解らないいろいろな前提があったみたいなんですが、今(使っているのはjdk1.8)ではずいぶんすっきりしているみたいです。
が、古い情報が混在していていまいち何が必要かやってみないとわかりません。

なお、「とある処理」のJVM起動時に
-Djava.security.policy=ポリシーファイル
-Djava.rmi.server.hostname=待受対象となるIP(NICが複数ある場合)
を指定しないと動きませんでした。(ポリシーは要らないかもしれない・・)

ポリシーファイルは
java.net.SocketPermission
について許可すればよかったはず。

後で負荷テストしたら秒間千件を超えるRMI呼び出しを行うと「Too many open files」エラーが多発しました。
調べたところ、Linuxのファイルディスクリプタ制限が影響していて、open filesの値を大きくしなきゃならないみたい。