CLOVER🍀

That was when it all began.

Infinispan 10のServerNGを試す

これは、なにをしたくて書いたもの?

Infinispan 10.0.0.Beta4がリリースされました。

Infinispan: Infinispan 10.0.0.Beta4

いくつか注目したくなる機能があるのですが、今回からInfinispan Serverで採用される、新しいServerモジュールに着目したいと思います。

"ServerNG"と呼ばれていたもの

Infinispan Serverの新しいServerモジュールは、"ServerNG"と呼ばれていました。個人的にも、何度かPull Requestで名前を見たことが
あるので、「Serverを新しくするんだろうなー」くらいに思っていました。

まあ、モジュールを見に行くと、今でも"ServerNG"なのですが。

infinispan/server/runtime at 10.0.0.Beta4 · infinispan/infinispan · GitHub

Infninispan Serverは、Infinispan 5.3以降WildFly(この当時はJBoss AS 7)ベースで構築されていましたが、WildFlyが提供する機能が
便利な反面、統合するコードを維持するのが大変らしく、これに対して生まれた薄いサーバー基盤が"ServerNG"です。

[ISPN-8124] ServerNG: Initial implementation - JBoss Issue Tracker

現在でもWildFlyベースのServerは利用可能ですが、「レガシー」という扱いになり、新たな機能追加、改善はなくなるようです。

ServerNGは、以下の特徴を持ちます。

  • 36MBの小さいサイズ(WildFlyベースだと130MB)
  • 起動時に20MB程度の、少ないメモリ使用量(WildFlyベースだと40MB)
  • Hot Rod、RESTで使用するポートを、シングルポート化(Memcachedは別ポート)
  • セキュリティ機能は、WildFly Elytronを使って実装
  • Embedded形式を拡張したServer設定
  • CacheおよびCounterをHot RodおよびRESTから動的に作成、管理する

紹介はこんな感じにして、試していってみましょう。

なお、この時点ではInfinispanのバージョンは10.0.0.Beta4なので、10.0.0.Finalまでにいろいろ変わる可能性があると思うので、
参考程度に。

環境

今回の環境は、こちらです。OSはUbuntu Linux。

$ java -version
openjdk version "11.0.3" 2019-04-16
OpenJDK Runtime Environment (build 11.0.3+7-Ubuntu-1ubuntu218.04.1)
OpenJDK 64-Bit Server VM (build 11.0.3+7-Ubuntu-1ubuntu218.04.1, mixed mode, sharing)

起動してみる

Infinispanのダウンロードページより、Serverを選ぶと、すでにServerNGで構成されたアーカイブをダウンロードできます。

Download - Infinispan

と言いつつ、wgetで取得。

$ wget https://downloads.jboss.org/infinispan/10.0.0.Beta4/infinispan-server-10.0.0.Beta4.zip

展開。

$ unzip infinispan-server-10.0.0.Beta4.zip

サイズを見てみましょう。zipで36MBでした。

$ du -sh *
41M infinispan-server-10.0.0.Beta4
36M infinispan-server-10.0.0.Beta4.zip

展開されたディレクトリ内へ。

$ cd infinispan-server-10.0.0.Beta4

ディレクトリ構成は、こんな感じです。

$ ls -l
合計 24
drwxr-xr-x 2 xxxxx xxxxx  4096  7月 12 17:25 bin
drwxr-xr-x 4 xxxxx xxxxx  4096  7月 12 17:25 docs
drwxr-xr-x 2 xxxxx xxxxx 12288  7月 12 17:25 lib
drwxr-xr-x 3 xxxxx xxxxx  4096  7月 12 17:25 server

lib、docディレクトリを除くと、こんな感じの構成になっています。ファイルがめちゃくちゃ少ないですね。

$ find -type f | grep -vE '/(lib|doc)'
./bin/server.sh
./bin/server.conf
./server/conf/users.properties
./server/conf/infinispan.xml
./server/conf/groups.properties
./server/conf/logging.properties

「bin/server.sh」で起動するようなので、これを使用して起動。

$ bin/server.sh 
=========================================================================
  Bootstrap Environment
  ISPN_HOME: /path/to/infinispan-server-10.0.0.Beta4
  JAVA: /usr/lib/jvm/default/bin/java
  JAVA_OPTS:  -server -Xms64m -Xmx512m -XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=64m -Djava.net.preferIPv4Stack=true -Djava.awt.headless=true
=========================================================================
22:02:19,875 INFO  [org.infinispan.SERVER] (main) ISPN080000: Infinispan Server starting
22:02:19,973 INFO  [org.infinispan.SERVER] (main) ISPN080017: Server configuration: /path/to/infinispan-server-10.0.0.Beta4/server/conf/infinispan.xml
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.thoughtworks.xstream.core.util.Fields (file:/path/to/infinispan-server-10.0.0.Beta4/lib/xstream-1.4.11.jar) to field java.util.TreeMap.comparator
WARNING: Please consider reporting this to the maintainers of com.thoughtworks.xstream.core.util.Fields
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
22:02:23,306 INFO  [org.infinispan.factories.GlobalComponentRegistry] (main) ISPN000128: Infinispan version: Infinispan 'N/A' 10.0.0.Beta4
22:02:23,817 INFO  [org.infinispan.SERVER] (ForkJoinPool.commonPool-worker-7) ISPN080018: Protocol HotRod (internal)
22:02:23,889 WARN  [org.infinispan.transaction.lookup.GenericTransactionManagerLookup] (ForkJoinPool.commonPool-worker-5) ISPN000104: Falling back to EmbeddedTransactionManager from Infinispan
22:02:24,038 INFO  [org.infinispan.SERVER] (main) ISPN080018: Protocol REST (internal)
22:02:24,278 INFO  [org.infinispan.SERVER] (ForkJoinPool.commonPool-worker-5) ISPN080004: Protocol Memcached listening on 127.0.0.1:11221
22:02:24,325 INFO  [org.infinispan.SERVER] (main) ISPN080004: Protocol SINGLE_PORT listening on 127.0.0.1:11222
22:02:24,325 INFO  [org.infinispan.SERVER] (main) ISPN080001: Infinispan Server 10.0.0.Beta4 started in 4351ms

起動スクリプトがシェルスクリプトしかないですし、まだWindowsでは動かせないんでしょうね。ispn-cliに相当するものや、ユーザーを
管理するスクリプトもなさそうです。このあたりは、今後追加されるのでしょうか?そうでもないのでしょうか?

ちなみに、まだドキュメントはなさげなので、リポジトリにあるREADME.mdを読むとよいでしょう。

infinispan/server/runtime at 10.0.0.Beta4 · infinispan/infinispan · GitHub

WildFlyベースのサーバーを振り返る

ここで、少しだけWildFlyベースの方のInfinispan Serverを見てみましょう。

ダウンロードページでは「Legacy WildFly-based server 」というリンクがひっそりとあり、こちらからWildFlyベースのInfinispan Serverを
ダウンロードすることができます。すでにレガシー扱いですね。

$ wget https://downloads.jboss.org/infinispan/10.0.0.Beta4/infinispan-wildfly-server-10.0.0.Beta4.zip
$ unzip infinispan-wildfly-server-10.0.0.Beta4.zip

ファイルサイズ。zipで約130MBありますね。

$ du -sh *
150M    infinispan-wildfly-server-10.0.0.Beta4
128M    infinispan-wildfly-server-10.0.0.Beta4.zip

展開したディレクトリ内へ。

$ cd infinispan-wildfly-server-10.0.0.Beta4

ディレクトリ内は、こんな感じでしたね。

$ ls -l
合計 536
-rw-r--r-- 1 xxxxx xxxxx  26530  7月 12 17:26 LICENSE.txt
-rw-r--r-- 1 xxxxx xxxxx   2612  7月 12 17:26 README.txt
drwxr-x--x 4 xxxxx xxxxx   4096  7月 12 17:26 bin
drwxr-xr-x 3 xxxxx xxxxx   4096  7月 12 17:26 client
-rw-r--r-- 1 xxxxx xxxxx   2451  7月 12 17:26 copyright.txt
drwxr-xr-x 6 xxxxx xxxxx   4096  7月 12 17:26 docs
drwxr-x--x 5 xxxxx xxxxx   4096  7月 12 17:26 domain
-rw-r--r-- 1 xxxxx xxxxx 479889  7月 12 17:26 jboss-modules.jar
drwxr-xr-x 3 xxxxx xxxxx   4096  7月 12 17:26 modules
drwxr-xr-x 2 xxxxx xxxxx   4096  7月 12 17:26 rest
drwxr-x--x 8 xxxxx xxxxx   4096  7月 26 22:17 standalone

スタンドアロンで起動。

$ bin/standalone.sh

クラスタリングを有効にして起動。

$ bin/standalone.sh -c clustered.xml

とまあ、簡単にWildFlyベースのInfinispan Serverはこんな感じです、と見返してみました。

Serverを構成するファイルを見る

"ServerNG"の方に戻りましょう。

まずは、Infinispan Serverの設定ファイルを見てみます。「infinispan.xml」がありましたね。
server/conf/infinispan.xml

<infinispan
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:infinispan:config:10.0 http://www.infinispan.org/schemas/infinispan-config-10.0.xsd
                            urn:infinispan:server:10.0 http://www.infinispan.org/schemas/infinispan-server-10.0.xsd"
        xmlns="urn:infinispan:config:10.0"
        xmlns:server="urn:infinispan:server:10.0">

   <cache-container/>

   <server xmlns="urn:infinispan:server:10.0">
      <interfaces>
         <interface name="public">
            <loopback/>
         </interface>
      </interfaces>

      <socket-bindings default-interface="public" port-offset="${infinispan.socket.binding.port-offset:0}">
         <socket-binding name="default" port="11222"/>
         <socket-binding name="memcached" port="11221"/>
      </socket-bindings>

      <security>
         <security-realms>
            <security-realm name="default">
               <properties-realm groups-attribute="Roles">
                  <user-properties path="users.properties" relative-to="infinispan.server.config.path" plain-text="true"/>
                  <group-properties path="groups.properties" relative-to="infinispan.server.config.path" />
               </properties-realm>
               <server-identities>
                  <ssl>
                     <keystore path="application.keystore" relative-to="infinispan.server.config.path"
                               keystore-password="password" alias="server" key-password="password"
                               generate-self-signed-certificate-host="localhost"/>
                  </ssl>
               </server-identities>
            </security-realm>
         </security-realms>
      </security>

      <endpoints socket-binding="default" security-realm="default">
         <hotrod-connector name="hotrod"/>
         <rest-connector name="rest"/>
         <memcached-connector socket-binding="memcached"/>
      </endpoints>
   </server>
</infinispan>

小さい!

cache-containerの定義は…なにもなさそう。

   <cache-container/>

この状態だとCacheが利用できないので、例えば以下のようにCacheを定義してあげる必要があります。

   <cache-container>
      <local-cache name="default"/>
   </cache-container>

設定ファイルの書き方は、これまでのEmbeddedなInfinispanの設定がわかっていれば、そう困らないと思います。

その他のファイルも見てみましょう。

binディレクトリ内にある設定ファイル。これは、起動スクリプトの設定になるみたいですね。
bin/server.conf

## -*- shell-script -*- ######################################################
##                                                                          ##
##  Server bootstrap Script Configuration                                   ##
##                                                                          ##
##############################################################################

#
# This file is optional; it may be removed if not needed.
#

#
# Specify the maximum file descriptor limit, use "max" or "maximum" to use
# the default, as queried by the system.
#
# Defaults to "maximum"
#
#MAX_FD="maximum"

#
# Specify the profiler configuration file to load.
#
# Default is to not load profiler configuration file.
#
#PROFILER=""

#
# Specify the location of the Java home directory.  If set then $JAVA will
# be defined to $JAVA_HOME/bin/java, else $JAVA will be "java".
#
#JAVA_HOME="/opt/java/jdk"

# tell linux glibc how many memory pools can be created that are used by malloc
# MALLOC_ARENA_MAX="5"

#
# Specify the exact Java VM executable to use.
#
#JAVA=""

# Uncomment the following line to prevent manipulation of JVM options
# by shell scripts.
#
#PRESERVE_JAVA_OPTS=true

#
# Specify options to pass to the Java VM.
#
if [ "x$JAVA_OPTS" = "x" ]; then
   JAVA_OPTS="-Xms64m -Xmx512m -XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=64m -Djava.net.preferIPv4Stack=true"
   JAVA_OPTS="$JAVA_OPTS -Djava.awt.headless=true"
else
   echo "JAVA_OPTS already set in environment; overriding default settings with values: $JAVA_OPTS"
fi

# Sample JPDA settings for remote socket debugging
#JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n"

# Sample JPDA settings for shared memory debugging
#JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_shmem,server=y,suspend=n,address=infinispan"

# Uncomment this out to control garbage collection logging
# GC_LOG="true"

WildFlyの時は「LAUNCH_JBOSS_IN_BACKGROUND」という環境変数を使って、スクリプトのPIDをトラップしてServerプロセスに
シグナルを送ったりできましたが、これは「LAUNCH_ISPN_IN_BACKGROUND」という名前になるみたいですね。

while true; do
   if [ "x$LAUNCH_ISPN_IN_BACKGROUND" = "x" ]; then
      # Execute the JVM in the foreground
      eval \"$JAVA\" $JAVA_OPTS \
         -Djava.util.logging.manager=org.jboss.logmanager.LogManager \
         -Dinfinispan.server.home.path=\""$ISPN_HOME"\" \
         -jar "$BOOTSTRAP_JAR" \
         "$SERVER_OPTS"
      ISPN_STATUS=$?
   else
      # Execute the JVM in the background
      eval \"$JAVA\" $JAVA_OPTS \
         -Djava.util.logging.manager=org.jboss.logmanager.LogManager \
         -Dinfinispan.server.home.path=\""$ISPN_HOME"\" \
         -jar "$BOOTSTRAP_JAR" \
         "$SERVER_OPTS" "&"
      ISPN_PID=$!
      # Trap common signals and relay them to the server process
      trap "kill -HUP  $ISPN_PID" HUP
      trap "kill -TERM $ISPN_PID" INT
      trap "kill -QUIT $ISPN_PID" QUIT
      trap "kill -PIPE $ISPN_PID" PIPE
      trap "kill -TERM $ISPN_PID" TERM

Serverを増やしてみる

zipから展開したServerをコピーして、Serverを増やしてみましょう。

$ cp -R infinispan-server-10.0.0.Beta4 infinispan-server-10.0.0.Beta4-2
$ cp -R infinispan-server-10.0.0.Beta4 infinispan-server-10.0.0.Beta4-3

2つ目のServer側を起動してみます。

$ cd infinispan-server-10.0.0.Beta4-2
$ bin/server.sh 
=========================================================================
  Bootstrap Environment
  ISPN_HOME: /path/to/infinispan-server-10.0.0.Beta4-2
  JAVA: /usr/lib/jvm/default/bin/java
  JAVA_OPTS:  -server -Xms64m -Xmx512m -XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=64m -Djava.net.preferIPv4Stack=true -Djava.awt.headless=true
=========================================================================
22:20:59,157 INFO  [org.infinispan.SERVER] (main) ISPN080000: Infinispan Server starting
22:20:59,172 INFO  [org.infinispan.SERVER] (main) ISPN080017: Server configuration: /path/to/infinispan-server-10.0.0.Beta4-2/server/conf/infinispan.xml
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.thoughtworks.xstream.core.util.Fields (file:/path/to/infinispan-server-10.0.0.Beta4-2/lib/xstream-1.4.11.jar) to field java.util.TreeMap.comparator
WARNING: Please consider reporting this to the maintainers of com.thoughtworks.xstream.core.util.Fields
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
22:21:00,769 INFO  [org.infinispan.factories.GlobalComponentRegistry] (main) ISPN000128: Infinispan version: Infinispan 'N/A' 10.0.0.Beta4
22:21:01,206 INFO  [org.infinispan.SERVER] (ForkJoinPool.commonPool-worker-5) ISPN080018: Protocol HotRod (internal)
22:21:01,233 WARN  [org.infinispan.transaction.lookup.GenericTransactionManagerLookup] (ForkJoinPool.commonPool-worker-7) ISPN000104: Falling back to EmbeddedTransactionManager from Infinispan
22:21:01,311 INFO  [org.infinispan.SERVER] (main) ISPN080018: Protocol REST (internal)
22:21:02,644 FATAL [org.infinispan.SERVER] (main) Error: java.util.concurrent.ExecutionException: io.netty.channel.unix.Errors$NativeIoException: bind(..) failed: アドレスは既に使用中です
    at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395)
    at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1999)
    at org.infinispan.server.Bootstrap.main(Bootstrap.java:111)
    at org.infinispan.server.Bootstrap.main(Bootstrap.java:21)
Caused by: io.netty.channel.unix.Errors$NativeIoException: bind(..) failed: アドレスは既に使用中です
    at io.netty.channel.unix.Errors.newIOException(Errors.java:122)
    at io.netty.channel.unix.Socket.bind(Socket.java:287)
    at io.netty.channel.epoll.AbstractEpollChannel.doBind(AbstractEpollChannel.java:684)
    at io.netty.channel.epoll.EpollServerSocketChannel.doBind(EpollServerSocketChannel.java:70)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:558)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.bind(DefaultChannelPipeline.java:1358)
    at io.netty.channel.AbstractChannelHandlerContext.invokeBind(AbstractChannelHandlerContext.java:501)
    at io.netty.channel.AbstractChannelHandlerContext.bind(AbstractChannelHandlerContext.java:486)
    at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:1019)
    at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:254)
    at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:366)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
    at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:326)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:834)

22:21:03,638 INFO  [org.infinispan.SERVER] (Thread-0) ISPN080002: Infinispan Server stopping
22:21:03,639 INFO  [org.infinispan.SERVER] (Thread-0) ISPN080003: Infinispan Server stopped

使用しているポートが最初のServerと重なるので、エラーになります。

ここで、「-o」オプション(もしくは「--port-offset」オプション)を使用すると、使用するポートを指定の値だけずらすことができます。

$ bin/server.sh -o 1000
=========================================================================
  Bootstrap Environment
  ISPN_HOME: /path/to/infinispan-server-10.0.0.Beta4-2
  JAVA: /usr/lib/jvm/default/bin/java
  JAVA_OPTS:  -server -Xms64m -Xmx512m -XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=64m -Djava.net.preferIPv4Stack=true -Djava.awt.headless=true
=========================================================================
22:29:17,824 INFO  [org.infinispan.SERVER] (main) ISPN080000: Infinispan Server starting
22:29:17,844 INFO  [org.infinispan.SERVER] (main) ISPN080017: Server configuration: /path/to/infinispan-server-10.0.0.Beta4-2/server/conf/infinispan.xml
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.thoughtworks.xstream.core.util.Fields (file:/path/to/infinispan-server-10.0.0.Beta4-2/lib/xstream-1.4.11.jar) to field java.util.TreeMap.comparator
WARNING: Please consider reporting this to the maintainers of com.thoughtworks.xstream.core.util.Fields
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
22:29:19,093 INFO  [org.infinispan.factories.GlobalComponentRegistry] (main) ISPN000128: Infinispan version: Infinispan 'N/A' 10.0.0.Beta4
22:29:19,544 INFO  [org.infinispan.SERVER] (ForkJoinPool.commonPool-worker-5) ISPN080018: Protocol HotRod (internal)
22:29:19,591 WARN  [org.infinispan.transaction.lookup.GenericTransactionManagerLookup] (ForkJoinPool.commonPool-worker-7) ISPN000104: Falling back to EmbeddedTransactionManager from Infinispan
22:29:19,645 INFO  [org.infinispan.SERVER] (main) ISPN080018: Protocol REST (internal)
22:29:19,887 INFO  [org.infinispan.SERVER] (ForkJoinPool.commonPool-worker-7) ISPN080004: Protocol Memcached listening on 127.0.0.1:12221
22:29:19,927 INFO  [org.infinispan.SERVER] (main) ISPN080004: Protocol SINGLE_PORT listening on 127.0.0.1:12222
22:29:19,928 INFO  [org.infinispan.SERVER] (main) ISPN080001: Infinispan Server 10.0.0.Beta4 started in 2082ms

WildFlyベースの時も、これはできましたね。

使用できるオプションを確認するには、「-h」(または「--help」)を使うか、

$ bin/server.sh -h
=========================================================================
  Bootstrap Environment
  ISPN_HOME: /home/kazuhira/study/java/clover/infinispan-getting-started/infinispan-server-10.0.0.Beta4-2
  JAVA: /usr/lib/jvm/default/bin/java
  JAVA_OPTS:  -server -Xms64m -Xmx512m -XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=64m -Djava.net.preferIPv4Stack=true -Djava.awt.headless=true
=========================================================================
Infinispan Server 10.0.0.Beta4 (N/A)
Usage:
  -b, --bind-address=<address>  Binds the server to the specified address.
  -o, --port-offset=<offset>    Adds the specified offset to all ports.
  -c, --server-config=<config>  Uses the specified configuration file. Defaults to 'infinispan.xml'.
  -h, --help                    Displays this message and exits.
  -s, --server-root=<path>      Uses the specified path as root for the server. Defaults to 'server'.
  -v, --version                 Displays version information and exits.
22:23:59,946 INFO  [org.infinispan.SERVER] (main) ISPN080000: Infinispan Server starting
22:23:59,948 INFO  [org.infinispan.SERVER] (main) ISPN080017: Server configuration: /path/to/infinispan-server-10.0.0.Beta4-2/server/conf/infinispan.xml
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.thoughtworks.xstream.core.util.Fields (file:/path/to/infinispan-server-10.0.0.Beta4-2/lib/xstream-1.4.11.jar) to field java.util.TreeMap.comparator
WARNING: Please consider reporting this to the maintainers of com.thoughtworks.xstream.core.util.Fields
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
22:24:01,202 INFO  [org.infinispan.factories.GlobalComponentRegistry] (main) ISPN000128: Infinispan version: Infinispan 'N/A' 10.0.0.Beta4
22:24:01,652 INFO  [org.infinispan.SERVER] (ForkJoinPool.commonPool-worker-5) ISPN080018: Protocol HotRod (internal)
22:24:01,706 WARN  [org.infinispan.transaction.lookup.GenericTransactionManagerLookup] (ForkJoinPool.commonPool-worker-7) ISPN000104: Falling back to EmbeddedTransactionManager from Infinispan
22:24:01,785 INFO  [org.infinispan.SERVER] (main) ISPN080018: Protocol REST (internal)
22:24:04,098 INFO  [org.infinispan.SERVER] (Thread-0) ISPN080002: Infinispan Server stopping
22:24:04,098 INFO  [org.infinispan.SERVER] (Thread-0) ISPN080003: Infinispan Server stopped

ServerNGのドキュメントを読みましょう。

infinispan/server/runtime at 10.0.0.Beta4 · infinispan/infinispan · GitHub

3つ目のServerも起動。

$ cd infinispan-server-10.0.0.Beta4-3
$ bin/server.sh -o 2000

ところが、この状態ではクラスタが構成されるわけではなく、スタンドアロンなServerが3つあるだけです。

ここで、Cacheの定義を変更して、Distributed Cacheを定義しましょう。

   <cache-container default-cache="default" statistics="false">
      <transport cluster="cluster" stack="udp"/>
      <distributed-cache name="default"/>
   </cache-container>

これは、デフォルトのudpスタック(JGroups)でクラスタを構成します。

スタック名を別にして、もうちょっと明示的に書くとこんな感じです。

   <jgroups>
      <stack-file name="default-udp" path="default-configs/default-jgroups-udp.xml"/>
    </jgroups>

   <cache-container default-cache="default" statistics="false">
      <transport cluster="cluster" stack="default-udp"/>
      <distributed-cache name="default"/>
   </cache-container>

全Serverの設定ファイルを変更し、再度起動すると以下のようにクラスタが構成されます。

22:46:37,631 INFO  [org.infinispan.CLUSTER] (main) ISPN000094: Received new cluster view for channel cluster: [xxxxx-43065|2] (3) [xxxxx-43065, xxxxx-60045, ikaruga-45864]
22:46:37,648 INFO  [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (main) ISPN000079: Channel cluster local address is xxxxx-45864, physical addresses are [192.168.0.2:49422]

Hot Rod Clientからアクセスしてみる

では、構成されたInfinispan Serverクラスタに、Hot Rod Clientからアクセスしてみましょう。

Maven依存関係は、こちら。

        <dependency>
            <groupId>org.infinispan</groupId>
            <artifactId>infinispan-client-hotrod</artifactId>
            <version>10.0.0.Beta4</version>
        </dependency>

単純に、RemoteCacheにput/getする、簡単なプログラムを作成。
src/main/java/org/littlewings/infinispan/App.java

package org.littlewings.infinispan;

import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.RemoteCacheManager;
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;

public class App {
    public static void main(String... args) {
        RemoteCacheManager cacheManager =
                new RemoteCacheManager(
                        new ConfigurationBuilder()
                                .addServers("localhost:11222;localhost:12222;localhost:13222")
                                .security()
                                .ssl()
                                .enable()
                                .trustStoreType("PKCS12")
                                .trustStoreFileName("/path/to/infinispan-server-10.0.0.Beta4/server/conf/application.keystore")
                                .trustStorePassword("password".toCharArray())
                                .build()
                );

        RemoteCache<String, String> cache = cacheManager.getCache("default");

        cache.put("key1", "value1");
        System.out.printf("key1 = %s%n", cache.get("key1"));

        cacheManager.stop();
    }
}

SSL/TLSを使わないといけなさそうなのですが、TrustStoreとしてInfinispan Server内のKeyStoreを利用。

                                .trustStoreType("PKCS12")
                                .trustStoreFileName("/path/to/infinispan-server-10.0.0.Beta4/server/conf/application.keystore")
                                .trustStorePassword("password".toCharArray())

実行結果。

7月 26, 2019 11:11:35 午後 org.infinispan.client.hotrod.impl.protocol.Codec20 readNewTopologyAndHash
INFO: ISPN004006: Server sent new topology view (id=18, age=0) containing 3 addresses: [127.0.0.1:11222]
7月 26, 2019 11:11:35 午後 org.infinispan.client.hotrod.impl.transport.netty.ChannelFactory updateTopologyInfo
INFO: ISPN004014: New server added(127.0.0.1:11222), adding to the pool.
7月 26, 2019 11:11:35 午後 org.infinispan.client.hotrod.impl.transport.netty.ChannelFactory updateTopologyInfo
INFO: ISPN004016: Server not in cluster anymore(localhost:12222), removing from the pool.
7月 26, 2019 11:11:35 午後 org.infinispan.client.hotrod.impl.transport.netty.ChannelFactory updateTopologyInfo
INFO: ISPN004016: Server not in cluster anymore(localhost:11222), removing from the pool.
7月 26, 2019 11:11:35 午後 org.infinispan.client.hotrod.impl.transport.netty.ChannelFactory updateTopologyInfo
INFO: ISPN004016: Server not in cluster anymore(localhost:13222), removing from the pool.
7月 26, 2019 11:11:35 午後 org.infinispan.client.hotrod.RemoteCacheManager actualStart
INFO: ISPN004021: Infinispan version: 10.0.0.Beta4
7月 26, 2019 11:11:35 午後 org.infinispan.client.hotrod.impl.protocol.Codec20 readNewTopologyAndHash
INFO: ISPN004006: Server sent new topology view (id=18, age=0) containing 3 addresses: [127.0.0.1:11222]
key1 = value1

OKそうですね。

なお、Infinispan 10.0.0.Beta4から、Cacheを扱うのに新しいAPIもリリースされているのですが、今回は対象外に。

新しいAPIは、また今度見ていきましょう。

まとめ

"ServerNG"と呼ばれる、新しいInfinispan Serverを試してみました。

ドキュメントがなかったりと、まだまだ途中な感じもしますが、だいぶスッキリとした構成になっていて良いと思います。

徐々に慣らしつつ、今後のリリースでの改善を見ていきましょう。

オマケ

2つ目のServerを起動した時に、スタックトレースにも出ていましたが、Infinispan ServerはNettyを基盤にしています。

https://github.com/infinispan/infinispan/blob/10.0.0.Beta4/server/runtime/src/main/java/org/infinispan/server/Bootstrap.java#L111

https://github.com/infinispan/infinispan/blob/10.0.0.Beta4/server/runtime/src/main/java/org/infinispan/server/Server.java

https://github.com/infinispan/infinispan/blob/10.0.0.Beta4/server/core/src/main/java/org/infinispan/server/core/transport/NettyTransport.java

あと、クラスタを構成する際に、Transportのスタックとして突如現れたこの「udp」というもの。

   <cache-container default-cache="default" statistics="false">
      <transport cluster="cluster" stack="udp"/>
      <distributed-cache name="default"/>
   </cache-container>

これは、Transport定義がないとデフォルトで作成されるものです。

https://github.com/infinispan/infinispan/blob/10.0.0.Beta4/core/src/main/java/org/infinispan/configuration/parsing/Parser.java#L890

https://github.com/infinispan/infinispan/blob/10.0.0.Beta4/core/src/main/java/org/infinispan/configuration/parsing/Parser.java#L121-L122

https://github.com/infinispan/infinispan/blob/10.0.0.Beta4/core/src/main/java/org/infinispan/remoting/transport/jgroups/BuiltinJGroupsChannelConfigurator.java#L15-L21

利用できるのは「udp」と「tcp」という名前のスタックで、実際の定義はこちら。

https://github.com/infinispan/infinispan/blob/10.0.0.Beta4/core/src/main/resources/default-configs/default-jgroups-udp.xml

https://github.com/infinispan/infinispan/blob/10.0.0.Beta4/core/src/main/resources/default-configs/default-jgroups-tcp.xml

ちょっとした、調べものでした。