これは、なにをしたくて書いたもの?
WildFlyのドメインモードで、自分でサーバーグループとサーバーを追加しようとして、適当にやっていたらちょっと
ハマったのでちゃんと確認しておこうかなと思いまして。
WildFlyのドメインモード
WildFlyには、2つの動作モードがありスタンドアロンモードとドメインモードがあります。
ふだんはスタンドアロンモードしか使っていないんですけどね。
ドメインモードについては、こちら。
ドメインモードには、以下の構成要素があります。
これらが、各ホスト上で動作します。
この用語の説明は、JBoss EAPのドキュメントを見た方がわかりやすい気がしますね。
第8章 ドメイン管理 7.4 | Red Hat Customer Portal
今回は、ドメインモードで動作するWildFlyに自分でサーバーグループやサーバーを追加してみたいと思います。
環境
今回の環境は、こちらです。
$ java --version openjdk 11.0.11 2021-04-20 OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.20.04) OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.20.04, mixed mode, sharing) $ mvn --version Apache Maven 3.8.1 (05c21c65bdfed0f71a2f2ada8b84da59348c4c5d) Maven home: $HOME/.sdkman/candidates/maven/current Java version: 11.0.11, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64 Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "5.4.0-80-generic", arch: "amd64", family: "unix"
WildFlyは、24.0.0.Finalを使います。
$ curl -OL https://download.jboss.org/wildfly/24.0.0.Final/wildfly-24.0.0.Final.zip $ unzip wildfly-24.0.0.Final.zip $ cd wildfly-24.0.0.Final
デフォルトの構成ファイルでドメインモードを起動する
ドメインモードで起動する際にはbin/domain.shでWildFlyを起動するのですが、この時に--host-configオプションで
ホストの構成ファイルを指定する必要があります。
Managed Domain Configuration Files
デフォルト(未指定)の場合は、host.xmlが選択されます。
$ bin/domain.sh
管理CLIでログインすると
$ bin/jboss-cli.sh -c [domain@localhost:9990 /]
2つのサーバーグループと3つのサーバーがあります。
[domain@localhost:9990 /] ls -l /server-group main-server-group other-server-group [domain@localhost:9990 /] ls -l /host=master/server-config server-one server-three server-two
いったん、全部削除してみましょう。最初にサーバーを止めて(server-threeはデフォルトでは起動しないようです)、
削除。
[domain@localhost:9990 /] /host=master/server=server-one:stop() [domain@localhost:9990 /] /host=master/server-config=server-one:remove() [domain@localhost:9990 /] /host=master/server=server-two:stop() [domain@localhost:9990 /] /host=master/server-config=server-two:remove() [domain@localhost:9990 /] /host=master/server-config=server-three:remove()
サーバーを削除すると、サーバーグループも削除できるようになります。
[domain@localhost:9990 /] /server-group=main-server-group:remove() [domain@localhost:9990 /] /server-group=other-server-group:remove()
次に、自分でサーバーグループを追加してみます。
[domain@localhost:9990 /] /server-group=server-group1:add(profile=default,socket-binding-group=standard-sockets) [domain@localhost:9990 /] /server-group=server-group2:add(profile=default,socket-binding-group=standard-sockets)
追加したサーバーグループに、サーバーを作成して割り当てます。ポートのオフセットは、2つ目以降は100ずつ
ずらしていきます。
[domain@localhost:9990 /] /host=master/server-config=server1-1:add(group=server-group1) [domain@localhost:9990 /] /host=master/server-config=server1-2:add(group=server-group1,socket-binding-port-offset=100) [domain@localhost:9990 /] /host=master/server-config=server2-1:add(group=server-group2,socket-binding-port-offset=200)
サーバーを起動。
[domain@localhost:9990 /] /host=master/server=server1-1:start() [domain@localhost:9990 /] /host=master/server=server1-2:start() [domain@localhost:9990 /] /host=master/server=server2-1:start()
アプリケーションをデプロイしてみます。両方のサーバーグループにデプロイしようと思うので--all-server-groupsを
使ってもいいのですが、今回は最初にひとつのサーバーグループにデプロイして、次に別のサーバーグループにも
デプロイメントを割り当てる、という方法でやってみます。
[domain@localhost:9990 /] deploy /path/to/target/ROOT.war --server-groups=server-group1 [domain@localhost:9990 /] deployment enable ROOT.war --server-groups=server-group2
デプロイしたアプリケーション自体は、最後に簡単に載せます。ここでは、/helloにHTTP GETでアクセスすると
Hello World!!と返ってくるものが動作するものとしてください。
確認。
$ curl localhost:8080/hello Hello World!! $ curl localhost:8180/hello Hello World!! $ curl localhost:8280/hello Hello World!!
OKですね。
host-master.xmlを使う
次に、ちょっと試しにとhost-master.xmlを使ってみます。
※ここまでの操作の内容は、いったん削除してまっさらなWildFlyでやり直しています
host-master.xmlの説明を見ると、実環境のマスターとなるドメインコントローラーを想定した設定ファイルのようです。
Managed Domain Configuration Files
とりあえず、起動してみます。
$ bin/domain.sh --host-config=host-master.xml
管理CLIで接続。
$ bin/jboss-cli.sh -c [domain@localhost:9990 /]
サーバーグループはありますが、サーバーの定義はありません。
[domain@localhost:9990 /] ls -l /server-group main-server-group other-server-group [domain@localhost:9990 /] ls -l /host=master/server-config
先ほどのhost.xmlを使った時と、同じことをしてみましょう。
今のサーバーグループを削除。
[domain@localhost:9990 /] /server-group=main-server-group:remove() [domain@localhost:9990 /] /server-group=other-server-group:remove()
サーバーとサーバーグループを追加。
[domain@localhost:9990 /] /server-group=server-group1:add(profile=default,socket-binding-group=standard-sockets) [domain@localhost:9990 /] /server-group=server-group2:add(profile=default,socket-binding-group=standard-sockets) [domain@localhost:9990 /] /host=master/server-config=server1-1:add(group=server-group1) [domain@localhost:9990 /] /host=master/server-config=server1-2:add(group=server-group1,socket-binding-port-offset=100) [domain@localhost:9990 /] /host=master/server-config=server2-1:add(group=server-group2,socket-binding-port-offset=200)
これで、サーバーを起動しようとすると
[domain@localhost:9990 /] /host=master/server=server1-1:start()
サーバーの起動に失敗します。ログファイル(domain/servers/server1-1/log/server.log)を見ると、こんな感じに。
2021-07-23 22:25:06,379 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("add") failed - address: ([("socket-binding-group" => "standard-sockets")]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => ["org.wildfly.network.interface.public"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => ["org.wildfly.management.socket-binding-manager is missing [org.wildfly.network.interface.public]"]
}
2021-07-23 22:25:06,380 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("add") failed - address: ([
("subsystem" => "remoting"),
("http-connector" => "http-remoting-connector")
]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => ["jboss.http-upgrade-registry.default"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => ["jboss.remoting.remoting-http-upgrade-service.http-remoting-connector is missing [jboss.http-upgrade-registry.default]"]
}
2021-07-23 22:25:06,382 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("add") failed - address: ([("subsystem" => "jca")]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => ["org.wildfly.transactions.global-default-local-provider"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => ["org.wildfly.jca.transaction-integration is missing [org.wildfly.transactions.global-default-local-provider]"]
}
2021-07-23 22:25:06,384 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("add") failed - address: ([
("subsystem" => "ejb3"),
("service" => "timer-service"),
("file-data-store" => "default-file-store")
]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => ["org.wildfly.transactions.global-default-local-provider"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => ["org.wildfly.ejb3.timer-service.timer-persistence-service.default-file-store is missing [org.wildfly.transactions.global-default-local-provider]"]
}
2021-07-23 22:25:06,502 INFO [org.jboss.as.controller] (Controller Boot Thread) WFLYCTL0183: Service status report
WFLYCTL0184: New missing/unsatisfied dependencies:
service jboss.http-upgrade-registry.default (missing) dependents: [service jboss.remoting.remoting-http-upgrade-service.http-remoting-connector]
service org.wildfly.network.interface.public (missing) dependents: [service org.wildfly.management.socket-binding-manager]
service org.wildfly.transactions.global-default-local-provider (missing) dependents: [service org.wildfly.jca.transaction-integration, service org.wildfly.ejb3.timer-service.timer-persistence-service.default-file-store]
WFLYCTL0448: 24 additional services are down due to their dependencies being missing or failed
依存関係が足りないようです。
ここで、host.xmlとhost-master.xmlを比較してみます。
$ diff domain/configuration/host.xml domain/configuration/host-master.xml
68,70d67
< <interface name="public">
< <inet-address value="${jboss.bind.address:127.0.0.1}"/>
< </interface>
82,92d78
< <servers>
< <server name="server-one" group="main-server-group"/>
< <server name="server-two" group="main-server-group" auto-start="true">
< <jvm name="default"/>
< <socket-bindings port-offset="150"/>
< </server>
< <server name="server-three" group="other-server-group" auto-start="false">
< <jvm name="default"/>
< <socket-bindings port-offset="250"/>
< </server>
< </servers>
サーバーの定義がないのはいいとして、interfaceの定義からpublicとされているもの(のinet-addressの定義)がありません。
確かにないようなので
[domain@localhost:9990 /] ls -l /interface=public ATTRIBUTE VALUE TYPE any undefined OBJECT any-address undefined BOOLEAN inet-address undefined STRING link-local-address undefined BOOLEAN loopback undefined BOOLEAN loopback-address undefined STRING multicast undefined BOOLEAN name public STRING nic undefined STRING nic-match undefined STRING not undefined OBJECT point-to-point undefined BOOLEAN public-address undefined BOOLEAN site-local-address undefined BOOLEAN subnet-match undefined STRING up undefined BOOLEAN virtual undefined BOOLEAN
ものは試しとinet-addressを追加してみます。
[domain@localhost:9990 /] /interface=public:write-attribute(name=inet-address,value="${jboss.bind.address:127.0.0.1}")
ホストを再起動。
[domain@localhost:9990 /] reload --host=master
すると、今度はサーバーが起動するようになります。今の設定だと、auto-startがtrueになっているので、全サーバーが
起動してきますが…。
デプロイと
[domain@localhost:9990 /] deploy /path/to/target/ROOT.war --server-groups=server-group1 [domain@localhost:9990 /] deployment enable ROOT.war --server-groups=server-group2
動作確認。
$ curl localhost:8080/hello Hello World!! $ curl localhost:8180/hello Hello World!! $ curl localhost:8280/hello Hello World!!
OKですね。
さて、設定を変えたら動いたわけですが、やったことが設定ファイルの意図と反している気がします。
こちらの説明を見ていると、ドメインコントローラーはホストコントローラーでもあるようなので、サーバーグループと
サーバーを追加したら動くと思っていたのですが。
host-master.xmlの説明を見ても、ドメインコントローラーであることと、サーバーが起動するように構成されていない
という感じで書かれているだけな気がします。
Managed Domain Configuration Files
ここで、host-slave.xmlとの差分を見てみましょう。
$ diff domain/configuration/host-master.xml domain/configuration/host-slave.xml
3c3
< <host xmlns="urn:jboss:domain:17.0" name="master">
---
> <host xmlns="urn:jboss:domain:17.0">
11a12,14
> <server-identities>
> <secret value="c2xhdmVfdXMzcl9wYXNzd29yZA=="/>
> </server-identities>
62c65,69
< <local/>
---
> <remote security-realm="ManagementRealm">
> <discovery-options>
> <static-discovery name="primary" protocol="${jboss.domain.master.protocol:remote+http}" host="${jboss.domain.master.address}" port="${jboss.domain.master.port:9990}"/>
> </discovery-options>
> </remote>
67a75,77
> <interface name="public">
> <inet-address value="${jboss.bind.address:127.0.0.1}"/>
> </interface>
78a89,94
> <servers>
> <server name="server-one" group="main-server-group"/>
> <server name="server-two" group="other-server-group">
> <socket-bindings port-offset="150"/>
> </server>
> </servers>
こちらにはサーバーの定義があり、publicにもinet-addressの定義があります。
ということは、リクエストをハンドリングするのは、host-slave.xmlで定義されているホストコントローラー管理下の
サーバーで行うことを想定している気がしますね。
そしてサーバーを追加するのも、host-slave.xmlで管理されているホストコントローラー側であるべきなのでしょう。
こちらの説明を読んでいて、ドメイン内のホストコントローラーのひとつがドメインコントローラーとなるという
イメージだったのですが。
こうなると、ドメインコントローラーはドメイン内でも独立して扱った方が良さそうな感じでしょうか。
参考までに、host.xmlとhost-slave.xmlの差分を見てみましょう。
$ diff domain/configuration/host.xml domain/configuration/host-slave.xml
3c3
< <host xmlns="urn:jboss:domain:17.0" name="master">
---
> <host xmlns="urn:jboss:domain:17.0">
11a12,14
> <server-identities>
> <secret value="c2xhdmVfdXMzcl9wYXNzd29yZA=="/>
> </server-identities>
62c65,69
< <local/>
---
> <remote security-realm="ManagementRealm">
> <discovery-options>
> <static-discovery name="primary" protocol="${jboss.domain.master.protocol:remote+http}" host="${jboss.domain.master.address}" port="${jboss.domain.master.port:9990}"/>
> </discovery-options>
> </remote>
84,85c91
< <server name="server-two" group="main-server-group" auto-start="true">
< <jvm name="default"/>
---
> <server name="server-two" group="other-server-group">
87,90d92
< </server>
< <server name="server-three" group="other-server-group" auto-start="false">
< <jvm name="default"/>
< <socket-bindings port-offset="250"/>
host-slave.xmlにはドメインコントローラーを参照しにいく定義があり、またサーバーの定義が少々異なりますね。
また、ドメイン自体の設定ファイルはdomain.xmlで管理されており、これはdomain.shの引数で指定することもできます。
-c <config>, -c=<config> Name of the domain configuration file
to use (default is "domain.xml") (Same
as --domain-config)
--domain-config=<config> Name of the domain configuration file
to use (default is "domain.xml") (Same
as -c)
このファイルは、マスターとなるドメインコントローラーが参照するようです。
Domain Wide Configuration – domain.xml
domain/configuration/domain.xmlでのinterfaceの定義を見ると以下のようになっており、publicとmanagementが空です。
<interfaces> <interface name="management"/> <interface name="private"> <inet-address value="${jboss.bind.address.private:127.0.0.1}"/> </interface> <interface name="public"/> <interface name="unsecure"> <inet-address value="${jboss.bind.address.unsecure:127.0.0.1}"/> </interface> </interfaces>
一方でhost-master.xmlではinterfacesはこうなっており
<interfaces> <interface name="management"> <inet-address value="${jboss.bind.address.management:127.0.0.1}"/> </interface> </interfaces>
host.xmlおよびhost-slave.xmlではこのようになっています。
<interfaces> <interface name="management"> <inet-address value="${jboss.bind.address.management:127.0.0.1}"/> </interface> <interface name="public"> <inet-address value="${jboss.bind.address:127.0.0.1}"/> </interface> </interfaces>
domain.xmlはドメインコントローラーでしか読み込まないということですが、この差分を上書きできる仕組みにでも
なっているんでしょうか?
なお、ホストコントローラーはひとつのホストにつきひとつを想定しているようで、それでもその構成を行ってみたい場合は
こちらを見るとよさそうです。
反対に、2つのホストでドメインを構成したい場合(host-master.xml、host-slave.xmlを使う場合)は、こちらを見ると
よさそうです。
まとめ
WildFlyのドメインモードで、サーバーグループとサーバーを自分で追加してみたいなと思い、そして気軽にhost-master.xmlを
扱ってみるといろいろハマり。
結果として、各種役割だったり2つのhost-xxxxx.xmlの役割の違いなどを調べることになり、意外と理解が進んだような
気がします。
まあ、単一のホストで実行する場合は、素直にhost.xmlを使うのが良さそうですね。
2つ以上のホストで構成する場合は、サーバーが動作するのはhost-slave.xmlになるんでしょうね。