JBoss EAP 7でHAシングルトンデプロイ

こんにちは。平田です。

JBoss EAP 7からHAシングルトンデプロイが復活したので試してみました。

JBoss EAP 5ではHAシングルトンという機能があり、クラスタ環境下でデプロイメントを一つだけ動かすことができました。クラスタで可用性を担保しつつ、プログラムとしては同時に一つしか動かしたくないというケース(バッチなど)で使用します。

JBoss EAP 6では、このHAシングルトン機能がJava APIの提供に留まっていました(HAシングルトン相当の動きをさせたい場合、処理の続行・ブロック制御を自分で書く)が、EAP7からデプロイのオプションとして復活したようです。

EAP7に同梱されるejb-timerサンプルを使って「クラスタ全体で同時に一つだけ動くタイマー」をデプロイしてみます。

まず既存のejb-timerサンプルをコピーし、HAシングルトンデプロイ用の設定ファイルを配置し、ビルドします。

$ cd path/to/jboss-eap-7.0.0.GA-quickstarts
$ cp -R ejb-timer ejb-timer-ha-singleton
$ cd ejb-timer-ha-singleton
$ mkdir src/main/webapp/META-INF
$ echo '<singleton-deployment xmlns="urn:jboss:singleton-deployment:1.0"/>' > src/main/webapp/META-INF/singleton-deployment.xml
$ mvn -Dmaven.test.skip=true clean package

次にクラスタ環境を作ります。EAP7をドメイン起動し、ha-singleton-test-server1, ha-singleton-test-server2というサーバを作成します。二つともローカル環境に立てるため、ポートオフセットを指定して各種のポート番号をずらします。

$ cd $JBOSS_HOME/bin
$ ./domain.sh &
$ ./jboss-cli.sh
// ドメイン環境で作成済みのserver-one, server-two, server-threeを停止する。
[domain@localhost:9999 /] :stop-servers
// クラスタ対応プロファイル 'ha' のサーバグループ作成
[domain@localhost:9999 /] /server-group=ha-singleton-test:add(profile=ha, socket-binding-group=ha-sockets)
// サーバを二つ作成. 二つ目はポートを150ずらす.
[domain@localhost:9999 /] /host=master/server-config=ha-singleton-test-server1:add(group=ha-singleton-test, auto-start=false, socket-binding-port-offset=0)
[domain@localhost:9999 /] /host=master/server-config=ha-singleton-test-server2:add(group=ha-singleton-test, auto-start=false, socket-binding-port-offset=150)
[domain@localhost:9999 /] /server-group=ha-singleton-test:start-servers

先ほどのejb-timerをデプロイします。

[domain@localhost:9999 /] deploy path/to/ejb-timer-ha-singleton/target/jboss-ejb-timer.war --server=groups=ha-singleton-test

このサンプルプログラムは3秒ごとに動くジョブと、6秒ごとに動くジョブで構成されます。下のログを見ると、全てサーバ1で実行されています(ログの左端の部分にノード名が出ています)。

[Server:ha-singleton-test-server1] 18:18:39,002 INFO  [stdout] (EJB default - 3) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:18:39 JST
[Server:ha-singleton-test-server1] 18:18:42,002 INFO  [stdout] (EJB default - 5) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:18:42 JST
[Server:ha-singleton-test-server1] 18:18:42,003 INFO  [stdout] (EJB default - 4) ScheduleExample.doWork() invoked at 2016.07.12 西暦 at 18:18:42 JST
[Server:ha-singleton-test-server1] 18:18:45,006 INFO  [stdout] (EJB default - 6) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:18:45 JST
[Server:ha-singleton-test-server1] 18:18:48,002 INFO  [stdout] (EJB default - 7) ScheduleExample.doWork() invoked at 2016.07.12 西暦 at 18:18:48 JST
[Server:ha-singleton-test-server1] 18:18:48,003 INFO  [stdout] (EJB default - 8) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:18:48 JST
[Server:ha-singleton-test-server1] 18:18:51,006 INFO  [stdout] (EJB default - 9) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:18:51 JST
[Server:ha-singleton-test-server1] 18:18:54,002 INFO  [stdout] (EJB default - 10) ScheduleExample.doWork() invoked at 2016.07.12 西暦 at 18:18:54 JST

ここでサーバ1を停止します。

[domain@localhost:9990 /] /host=master/server-config=ha-singleton-test-server1:stop

すると、今度は2号機のデプロイメントが活性化し、ジョブが継続します。

[Server:ha-singleton-test-server2] 18:23:30,010 INFO  [stdout] (EJB default - 2) ScheduleExample.doWork() invoked at 2016.07.12 西暦 at 18:23:30 JST
[Server:ha-singleton-test-server2] 18:23:30,010 INFO  [stdout] (EJB default - 1) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:23:30 JST
[Server:ha-singleton-test-server2] 18:23:33,002 INFO  [stdout] (EJB default - 3) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:23:33 JST
[Server:ha-singleton-test-server2] 18:23:36,005 INFO  [stdout] (EJB default - 5) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:23:36 JST
[Server:ha-singleton-test-server2] 18:23:36,005 INFO  [stdout] (EJB default - 4) ScheduleExample.doWork() invoked at 2016.07.12 西暦 at 18:23:36 JST
[Server:ha-singleton-test-server2] 18:23:39,005 INFO  [stdout] (EJB default - 6) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:23:39 JST
[Server:ha-singleton-test-server2] 18:23:42,004 INFO  [stdout] (EJB default - 7) ScheduleExample.doWork() invoked at 2016.07.12 西暦 at 18:23:42 JST
[Server:ha-singleton-test-server2] 18:23:42,004 INFO  [stdout] (EJB default - 8) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:23:42 JST

ちなみに、HAシングルトンデプロイを有効にする前のejb-timerサンプルをデプロイすると、サーバ1と2の両方でジョブが実行されます。

[Server:ha-singleton-test-server1] 18:27:18,013 INFO  [stdout] (EJB default - 1) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:27:18 JST
[Server:ha-singleton-test-server1] 18:27:18,013 INFO  [stdout] (EJB default - 2) ScheduleExample.doWork() invoked at 2016.07.12 西暦 at 18:27:18 JST
[Server:ha-singleton-test-server2] 18:27:21,002 INFO  [stdout] (EJB default - 5) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:27:21 JST
[Server:ha-singleton-test-server1] 18:27:21,003 INFO  [stdout] (EJB default - 3) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:27:21 JST
[Server:ha-singleton-test-server2] 18:27:24,002 INFO  [stdout] (EJB default - 6) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:27:24 JST
[Server:ha-singleton-test-server2] 18:27:24,003 INFO  [stdout] (EJB default - 10) ScheduleExample.doWork() invoked at 2016.07.12 西暦 at 18:27:24 JST
[Server:ha-singleton-test-server1] 18:27:24,004 INFO  [stdout] (EJB default - 4) ScheduleExample.doWork() invoked at 2016.07.12 西暦 at 18:27:24 JST
[Server:ha-singleton-test-server1] 18:27:24,005 INFO  [stdout] (EJB default - 5) TimeoutExample.scheduler() EJB timer service timeout at 2016.07.12 西暦 at 18:27:24 JST

Java EE 7でバッチを書けるようになり、HAシングルトンを使う機会も出てくるかもしれません。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です