#chiroito ’s blog

Java を中心とした趣味の技術について

HotRod ストアを使ったWildflyのセッションレプリケーション

これまでは、リモートストアを使用して HTTP セッションを Infinispan やその商用製品である Red Hat Data Grid へオフロードしていました。ですがその方法は Wildfly 14 (JBoss EAP 7.2)から古くなったようです。新しい方法は同バージョンから導入されたelytron サブシステムと統合する HotRod プロトコルをベースとするカスタムの最適化されたキャッシュストアを使います。

24.3.10. リモートストアを使用した HTTP セッションの Red Hat Data Grid への外部化

環境

  • Wildfly 19.1
  • Infinispan 9.4.18
  • Java EE 8

今回構築する構成は以下の様な構成です。1 つの Wildfly と 2 つの Infinispan を構築します。

f:id:chiroito:20200519172347p:plain

サンプルのソースコードはこちらにあります。

GitHub - chiroito/wildfly-session-sample

手順

Infinispan の設定は何も必要ありません。Wildfly の設定をしてアプリがそれを使えるように設定をすればセッションレプリケーションできます。

手順は以下のとおりです。

  1. 接続先となる Infinispan を定義する (下図の青)
  2. remote-cache-container と remote-cluster を定義する(下図の黄色)
  3. invalidation-cache を定義する (下図の赤)
  4. アプリでキャッシュを使うように設定する
  5. アプリをデプロイする

f:id:chiroito:20200521160717p:plain

0. Infinispan を起動する。

今回は 2 ノードの Infinispan を起動します。 ダウンロードした Infinispan の zip を 2 回別の名前で解凍します。 普通に実行すると使用しているポートが被ってしまいます。それを回避するため引数に-Djboss.socket.binding.port-offsetを付与します。それぞれのディレクトリで次の様に実行します。

1つ目

bin\standalone.bat -c clustered.xml -Djboss.node.name=nodeA

2つ目

bin\standalone.bat -c clustered.xml -Djboss.node.name=nodeB -Djboss.socket.binding.port-offset=100

1. 接続先となる Infinispan を定義する

これからの作業には jboss-cliを使用します。これはwlidflyのインストール先のbin\jboss-cli.batです。jboss-cli.bat -cで起動したら以下を実行します。

batch
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=infinispan-server1:add(host=127.0.0.1, port=11222)
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=infinispan-server2:add(host=127.0.0.1, port=11322)
run-batch

2. remote-cache-container と remote-cluster を定義する

こちらも同様に Jboss-cli で以下を実行します。

batch
/subsystem=infinispan/remote-cache-container=foo:add(default-remote-cluster=bar)
/subsystem=infinispan/remote-cache-container=foo/remote-cluster=bar:add(socket-bindings=[infinispan-server1, infinispan-server2])
run-batch

3. invalidation-cache を定義する

以前の方法とはここが変りました。以前はリモートストアを使っていましたが、今回はHotRodストアを使います。

これまでの方法では以下の様にstoreremoteでした。

/subsystem=infinispan/cache-container=web/invalidation-cache=infinispan/store=remote

これからの方法では以下の様にstorehotrodになります。

/subsystem=infinispan/cache-container=web/invalidation-cache=infinispan/store=hotrod

こちらも同様に Jboss-cli で以下を実行します。

batch
/subsystem=infinispan/cache-container=web/invalidation-cache=baz:add()
/subsystem=infinispan/cache-container=web/invalidation-cache=baz/component=transaction:add(mode=BATCH)
/subsystem=infinispan/cache-container=web/invalidation-cache=baz/component=locking:add(isolation=REPEATABLE_READ)
/subsystem=infinispan/cache-container=web/invalidation-cache=baz/store=hotrod:add(remote-cache-container=foo, fetch-state=false, purge=false, passivation=false, shared=true)
run-batch

4. アプリでキャッシュを使うように設定する

アプリケーションは以下の 2 つの設定ファイルを変更します。

  • WEB-INF/web.xml
  • WEB-INF/jboss-web.xml

WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <distributable/>
</web-app>

WEB-INF/jboss-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-web_13_0.xsd"
           version="13.0">

    <replication-config>
        <cache-name>web.baz</cache-name>
    </replication-config>

</jboss-web>

5. アプリをデプロイする

アプリケーションをビルドして Wildfly へデプロイします。ビルドには Maven などのビルドツールを使い、デプロイはこれまで同様にjboss-cliを使います。

cd wildfly-session-sample
mvn clean package
jboss-cli.bat -c
deploy target\wildfly-session-sample.war

確認

環境構築がうまくいってアプリがちゃんとできていると Wildfly が以下の様なメッセージを出力します。

[2020-05-19 03:19:43,748] Artifact wildfly-session-sample:war: Artifact is being deployed, please wait...
(略)
15:19:44,225 WARN  [org.wildfly.clustering.web.undertow] (MSC service thread 1-7) WFLYCLWEBUT0004: Legacy <replication-config/> overriding attached distributable session management provider for wildfly-session-sample.war
15:19:44,246 INFO  [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 102) WFLYCLINF0032: Getting remote cache named 'wildfly-session-sample.war'. If it does not exist a new cache will be created from configuration template named 'transactional'; null value uses default cache configuration on the Infinispan Server.
(略)
15:19:44,282 INFO  [org.infinispan.CLUSTER] (ServerService Thread Pool -- 102) [Context=wildfly-session-sample.war] ISPN100008: Updating cache members list [laptop-tlfueb3p], topology id 2
(略)
[2020-05-19 03:19:44,510] Artifact wildfly-session-sample:war: Artifact is deployed successfully
[2020-05-19 03:19:44,510] Artifact wildfly-session-sample:war: Deploy took 762 milliseconds

以下の URL へアクセスしてみてください。

以下の場合は各設定ファイルがきちんと書かれているか、デプロイしている war ファイル内のディレクトリ構成が正しいかを確認しましょう。私は IntelliJ IDEA の Enterprise Java で war ファイルを作ったところ後者に嵌まりました・・・

デプロイした時のログがこんな場合jboss-web.xmlの設定ができていません。

[2020-05-19 03:20:19,013] Artifact wildfly-session-sample:war: Artifact is being deployed, please wait...
(略)
15:20:19,613 INFO  [org.infinispan.configuration.cache.MemoryConfigurationBuilder] (MSC service thread 1-4) ISPN000152: Passivation configured without an eviction policy being selected. Only manually evicted entities will be passivated.
15:20:19,628 INFO  [org.infinispan.configuration.cache.MemoryConfigurationBuilder] (MSC service thread 1-4) ISPN000152: Passivation configured without an eviction policy being selected. Only manually evicted entities will be passivated.
(略)
[2020-05-19 03:20:19,905] Artifact wildfly-session-sample:war: Artifact is deployed successfully
[2020-05-19 03:20:19,905] Artifact wildfly-session-sample:war: Deploy took 892 milliseconds

このログの(略)に挟まれているログすら出ない場合は web.xmlの設定ができていません。

参考

24.3.9. HTTP セッションの Red Hat Data Grid への外部化