JBoss EAPのメモリフットプリントを改善する方法

株式会社 日立製作所　岡井裕矢

# はじめに

　JBoss EAPは、WildFlyを母体とするエンタープライズ向けOSSです。Java EE/Jakarta EEに準拠しており、どちらかというといわゆるモノリシックなシステム開発で利用されてきたOSSです。最近では、Eclipse Microprofile仕様への対応や、メモリフットプリントを改善する機能など、クラウドネイティブ向けの機能が提供され、コンテナでの活用やマイクロサービスでの採用も選択肢に入ってきています。今回は、JBoss EAPが持つ、メモリフットプリントを改善する機能を解説します。

なお、本記事に記載している内容はOSSの改良により予告なく変更される可能性があります。

# JBoss EAPのコンテナ活用について

　コンテナでは、業務負荷に応じて必要な時に業務サービスを一時的に多く稼働したり、不要になったら停止したりするため、起動性能の優れたOSSが好まれます。コンテナの起動性能はコンテナイメージのサイズに依存するため、メモリフットプリントが低いことが要求されます。

　プログラムに必要なモジュールのみを含むようにカスタマイズできる、Spring BootのようなOSSは、不要なモジュールを含まない軽量なコンテナイメージを作成できるためこのようなニーズにマッチしており、コンテナとの親和性に優れています。一方、JBoss EAPのようなJava EE/Jakarta EEに準拠したOSSは、常に標準仕様に準拠したフルスペックの機能を含んだものとなっていたためコンテナイメージのサイズも大きくなり、コンテナでの利用と親和性が高くありませんでした。

　しかし、JBoss EAPでも、バージョン7.3より、Galleon Feature-packsによってカスタマイズした機能をパッケージング化したJBoss EAPを組み込み、必要な機能のみを含んだ軽量なコンテナイメージを作成できるようになりました。

![機能の概要図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/893616/d1cadb8b-c21a-94ba-1a74-15364ca63db5.png)

# Galleon Feature-packsによるJBoss EAPのメモリーフットプリント軽減

Galleon Feature-packsによるメモリフットプリントの軽減は、Galleonというプロビジョニングツールを使って行われます。通常、コンテナを作成する際は、アプリケーションをデプロイし、ベースのコンテナイメージにJBoss EAPとアプリケーションを組み込んでコンテナを作成しますが、この際に、フルスペックのJBoss EAPを組み込むのではなく、アプリケーションの動作に必要な機能のみを含んだカスタマイズしたJBoss EAPを組み込むことができるようになっています。

カスタマイズする機能はレイヤと呼ばれる単位に分類されており、必要なレイヤを指定し、機能をカスタマイズします。レイヤはベースレイヤとデコレーターレイヤの２種類に分類されています。

![代表的なレイヤ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/893616/1c978069-6603-2a7c-bdac-7e61c8bee800.png)

## ベースレイヤ

ベースレイヤは、アプリケーションのパターンに対応した機能セットになっており、JBoss EAPの細かい機能に詳しくなくてもレイヤを選択できるようになっています。例えば、サーブレットを使ってデータベースにアクセスするようなシンプルなWebアプリケーションを作成する場合、datasources-web-serverレイヤが対応します。

|#|ベースレイヤ|概要|
|---|---|---|
|1|datasources-web-server|サーブレットコンテナとデータソースを設定する機能を提供するレイヤ。|
|2|jaxrs-server|datasources-web-serverレイヤが提供する機能に加えて、jaxrs、weld、jpa の3 つのサブシステムや、infinispanをベースにしたキャッシュ機能とMicroProfile REST Client 機能を提供するレイヤ。
|3|cloud-server|jaxrs-serverレイヤが提供する機能やサブシステムに加えて、resource-adapters、messaging-activemq の2 つのサブシステムを提供するレイヤ。|

## デコレーターレイヤ

デコレーターレイヤは、ベースレイヤでは提供されない機能に対応したレイヤです。ベースレイヤに追加して組み合わせて利用します。

|#|デコレーターレイヤ|概要|
|---|---|---|
|1|sso|Red Hat SSOの機能を提供するレイヤ。|
|2|observability|次のMicroProfileの機能を提供するレイヤ。<br>▪	MicroProfile Health<br>▪	MicroProfile Metrics<br>▪	MicroProfile Config<br>▪	MicroProfile OpenTracing<br>
|3|web-clustering|infinispanによるWebセッションクラスタリングを提供するレイヤ。|


# サンプルアプリを使ったJBoss EAPのメモリーフットプリント軽減

実際に、JBoss EAPのQuickstartでサンプル提供されているhelloworld-html5を使って、カスタマイズしたJBoss EAPとhelloworld-html5が組み込まれたコンテナをOpenShift環境に作成してみます。

なお、OpenShiftの環境構築や事前設定については今回は割愛して説明します。

## OpenShiftにログイン

はじめに、OpenShiftにログインしプロジェクトを作成します。

```
$ oc login -u admin -p admin
Login successful.

$ oc new-project jbosseap73-sample-app
Now using project "jbosseap73-sample-app" on server "<OpenShiftクラスタ>".

You can add applications to this project with the 'new-app' command. For example, try:
・・・
```

## コンテナの作成と配備

次に、OpenShiftのocコマンドを使ってコンテナ作成と配備をします。Galleonを使ったカスタマイズはocコマンドの延長で実施されるため、ocコマンドを実行することで暗黙的に機能のカスタマイズを行うことができます。

oc new-appの引数に環境変数GALLEON_PROVISION_LAYERSを使ってレイヤを指定します。helloworld-html5はRESTアプリケーションなので、RESTアプリケーションに対応するベースレイヤである、jaxrs-serverを指定します。

```
GALLEON_PROVISION_LAYERS=jaxrs-server
```

なお、GALLEON_PROVISION_LAYERSにはベースレイヤは一つしか定義できません。また、デコレータレイヤを組み合わせて定義する場合は、カンマを使ってデコレータレイヤを合わせて定義します。今回はデコレータレイヤの指定は不要なため省略しています。

ocコマンドの実行例は次の通りです。

【コマンド実行例】

```
$ oc new-app --template=eap73-basic-s2i -p IMAGE_STREAM_NAMESPACE=jbosseap73-sample-app -p SOURCE_REPOSITORY_URL=https://github.com/jboss-developer/jboss-eap-quickstarts -p SOURCE_REPOSITORY_REF=7.3.x-openshift -p CONTEXT_DIR=helloworld-html5 -p GALLEON_PROVISION_LAYERS=jaxrs-server -p APPLICATION_NAME=helloworld-html5-app
```

【出力例】

```
--> Deploying template "jbosseap73-sample-app/eap73-basic-s2i" to project jbosseap73-sample-app

     JBoss EAP 7.3 (OpenJDK 8)
     ---------
     An example JBoss Enterprise Application Platform application. For more information about using this template, see https://github.com/jboss-container-images/jboss-eap-7-openshift-image/blob/7.3.x/README.adoc

     A new JBoss EAP based application has been created in your project.

     * With parameters:
        * Application Name=helloworld-html5-app
        * EAP Image Name=jboss-eap73-openshift:7.3
        * EAP Runtime Image Name=jboss-eap73-runtime-openshift:7.3
        * Git Repository URL=https://github.com/jboss-developer/jboss-eap-quickstarts
        * Git Reference=7.3.x-openshift
        * Context Directory=helloworld-html5
        * Galleon layers=
        * Enable ExampleDS datasource=false
        * Queues=
        * Topics=
        * AMQ cluster password=y6Q331fG # generated
        * Github Webhook Secret=YfmENC2u # generated
        * Generic Webhook Secret=6LkUcP8j # generated
        * ImageStream Namespace=jbosseap73-sample-app
        * JGroups Cluster Password=pNnPh1S7 # generated
        * Deploy Exploded Archives=false
        * Maven mirror URL=
        * Maven Additional Arguments=-Dcom.redhat.xpaas.repo.jbossorg
        * ARTIFACT_DIR=
        * MEMORY_LIMIT=1Gi

--> Creating resources ...
    service "helloworld-html5-app" created
    service "helloworld-html5-app-ping" created
    route.route.openshift.io "helloworld-html5-app" created
    imagestream.image.openshift.io "helloworld-html5-app" created
    imagestream.image.openshift.io "helloworld-html5-app-build-artifacts" created
    buildconfig.build.openshift.io "helloworld-html5-app-build-artifacts" created
    buildconfig.build.openshift.io "helloworld-html5-app" created
    deploymentconfig.apps.openshift.io "helloworld-html5-app" created
--> Success
    Access your application via route 'helloworld-html5-app-jbosseap73-sample-app.apps.ocp44-oss1g-cluster.ocp44.oss1g.com' 
    Build scheduled, use 'oc logs -f bc/helloworld-html5-app-build-artifacts' to track its progress.
    Build scheduled, use 'oc logs -f bc/helloworld-html5-app' to track its progress.
    Run 'oc status' to view your app.
```
コマンドを実行すると、jaxrs-serverレイヤでカスタマイズされたJBoss EAPとhelloworld-html5アプリが組み込まれたコンテナが作成され、配備されます。

# おわりに

今回はJBoss EAPの機能をカスタマイズし、メモリフットプリントを軽減する方法を紹介しました。レイヤの定義ひとつでコンテナのサイズを削減できるため、活用の敷居は低くなっています。既存のJava EEで開発されたアプリケーションがあり、作り直しの刷新までは厳しいが、あまりコストを掛けずにコンテナに移行したいような場合には、有用な機能なのではないでしょうか。