8. クラウドネイティブなアプリケーション
CloudNative の指針として、12-factor App があるが、コンテナのサイ
ズ、起動の速さが重要となってくる。
I. コードベース
バージョン管理されている1つのコードベースと複数のデプロイ
VII. ポートバインディング
ポートバインディングを通してサービスを公開する
II. 依存関係
依存関係を明示的に宣言し分離する
VIII. 並行性
プロセスモデルによってスケールアウトする
III. 設定
設定を環境変数に格納する
IX. 廃棄容易性
高速な起動とグレースフルシャットダウンで堅牢性を最大化する
IV. バックエンドサービス
バックエンドサービスをアタッチされたリソースとして扱う
X. 開発/本番一致
開発、ステージング、本番環境をできるだけ一致させた状態を保つ
V. ビルド、リリース、実行
ビルド、リリース、実行の3つのステージを厳密に分離する
XI. ログ
ログをイベントストリームとして扱う
VI. プロセス
アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する
XII. 管理プロセス
管理タスクを1回限りのプロセスとして実行する
21. ときおり Quarkus が起動しなくなる
Quarkus を使い始めた当初は、ときおり以下のようなエラーが発生して
Quarkus が起動しなくなる。
Unable to properly register the hierarchy of the following classes for reflection as they are not in the Jandex index:
- com.example.Fruit
- com.example.Car
Consider adding them to the index either by creating a Jandex index for your dependency or via quarkus.index-dependency
properties.
23. デフォルト設定では fatJar でない
デフォルトの設定では fatJar とはなっておらず、-runner.jar だけでは起
動しない。target の下の lib の下のファイルも必要。
$ java -jar code-with-quarkus-1.0.0-SNAPSHOT-runner.jar
Exception in thread "main" java.lang.NoClassDefFoundError: io/quarkus/runtime/Application
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:27)
Caused by: java.lang.ClassNotFoundException: io.quarkus.runtime.Application
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 10 more
25. 署名付き Jar でエラー
fatJar としてビルドした場合、依存ライブラリに署名付き Jar が含まれ
ていると、SecurityException が発生する。
$ java -jar target/backend-runner.jar
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
at java.base/sun.security.util.SignatureFileVerifier.processImpl(SignatureFileVerifier.java:336)
at java.base/sun.security.util.SignatureFileVerifier.process(SignatureFileVerifier.java:269)
at java.base/java.util.jar.JarVerifier.processEntry(JarVerifier.java:273)
at java.base/java.util.jar.JarVerifier.update(JarVerifier.java:230)
at java.base/java.util.jar.JarFile.initializeVerifier(JarFile.java:757)
at java.base/java.util.jar.JarFile.ensureInitialization(JarFile.java:1034)
at java.base/java.util.jar.JavaUtilJarAccessImpl.ensureInitialization(JavaUtilJarAccessImpl.java:69)
at java.base/jdk.internal.loader.URLClassPath$JarLoader$2.getManifest(URLClassPath.java:870)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:786)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:398)
at java.base/sun.launcher.LauncherHelper.loadMainClass(LauncherHelper.java:760)
at java.base/sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:655)
31. Azure App Insights との連携がいまいち
Spring Boot の場合、以下の依存性を追加し、さらに
application.properties で設定をするだけで、アプリケーションの変更せ
ずに、Application Insights と自動で連携できる。
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>applicationinsights-spring-boot-starter</artifactId>
<version>2.5.1</version>
</dependency>
azure.application-insights.instrumentation-key=[your ikey from the resource]
spring.application.name=[your app name]
Quarkus は まだメジャーではないので Application Insights Spring Boot
Starter のようなものは存在しない。
32. Netty に関連する OOM
Quarkus 内部的に Netty を利用しており、アプリケーション側で Direct
Buffer を使う実装が多い場合、Direct buffer memory に起因する
OutOfMemoryError が発生し易い。
Exception in thread "Thread-316" java.lang.OutOfMemoryError: Direct buffer memory
at java.base/java.nio.Bits.reserveMemory(Unknown Source)
at java.base/java.nio.DirectByteBuffer.<init>(Unknown Source)
at java.base/java.nio.ByteBuffer.allocateDirect(Unknown Source)
at java.base/sun.nio.ch.Util.getTemporaryDirectBuffer(Unknown Source)
at java.base/sun.nio.ch.IOUtil.read(Unknown Source)
at java.base/sun.nio.ch.IOUtil.read(Unknown Source)
at java.base/sun.nio.ch.SimpleAsynchronousFileChannelImpl$2.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
43. # 資料名
① 【JJUG CCC 2019 Fall】JavaオンプレシステムをAKS + Quarkusに移行した話
② Quarkus is Eclipse MicroProfile 3.2 compatible!
③ Thorntail Community Announcement on Quarkus
④ Quarkus Dependency Injection
⑤ Quarkus入門
⑥ Unable to forward from a JAX-RS service to JSP
⑦ Extension for CXF
⑧ Skip adding signature files to the generated uber jar
⑨ Fixing Java's ByteBuffer native memory "leak"
⑩ Javaの起動時間といかに戦うか
参考資料