万一、Javaアプリケーションのメモリリークが原因で、週一度以上の頻度でJVMが再起動が発生してしまう場合なら?

あるいは、もし内部バックアップを実行するために、アプリケーションを毎晩10分間も停止させる必要があるならば?

あるいは、5分毎に何かアクションを実行させる単純な動作をスケジュール予約したい場合?

大規模なアプリケーションの多くは、一定間隔に、あるいは特定の時間にアクションやタスクを実行するスケジュール予約機能を必要とします。 問題は、異なるOSプラットフォームでそれぞれ独自のスケジュール予約の設定方法を提供していることです。 多種多様のプラットフォーム上でアプリケーションを動作させる必要がある場合、個別に各プラットフォーム別に機能を実装する必要性があります。

ソリューション

Java Service Wrapperには、タイマー機能を利用して多種多様のプラットフォーム上であっても、 再起動、シャットダウン、スレッドダンプ、カスタムイベントなどのタスクをスケジュール予約する機能を備えています。

タイマー機能は、Wrapperコンフィギュレーションファイルで定義することができ、 アプリケーション内部で設定する全ての設定を組み込むことが可能です。 これで複数の異なるサーバーであっても、全てが確実に動作することを確信し、アプリケーションのデプロイ作業が容易になります。

タイマー機能は、曜日や時間を指定して、あるいは何分毎や週一回などインターバル(一定間隔)の指定で予約することができます。 この柔軟性により、バックアップの計画も容易になり、システム停滞によるユーザーへの不便さを軽減したり、 同時に、システム管理者の定例作業により残業を軽減させることができます。

テクニカル概要

Wrapperでは、プロパティを組み合わせることで複数のタイマーを設定することができます。 まず、[wrapper.timer.<n>.interval]プロパティには、タイマーの発生タイミングを指定します。 次に、[wrapper.timer.<n>.action]プロパティには、実行するアクション動作を指定します。

wrapper.timer.<n>.interval]プロパティ:

wrapper.timer.<n>.interval]プロパティには、アクションを実行する時間やインターバル(一定間隔)などタイミングを指定します。 インターバル(一定間隔)の指定にワイルドカードも利用可能です。 以下は、コンフィギュレーションファイル設定例ですが、詳しくはプロパティページの説明を熟読してください。

コンフィギュレーション設定例:毎日03:55
wrapper.timer.1.interval=hour=3; minute=55
コンフィギュレーション設定例:毎週月曜03:55
wrapper.timer.1.interval=day-of-week=2; hour=3; minute=55
コンフィギュレーション設定例:5秒毎
wrapper.timer.1.interval=second=*/5

wrapper.timer.<n>.action]プロパティ:

wrapper.timer.<n>.action]プロパティには、指定されたタイマー時刻に実行するアクションを指定します。 ほとんどの場合、これには1つのアクションを指定しますが、複数の連続したアクションをカンマ区切りで一括設定することも可能です。 以下は、コンフィギュレーションファイル設定例ですが、詳しくはプロパティページの説明を熟読してください。

コンフィギュレーション設定例:スレッドダンプを実行する
wrapper.timer.1.action=dump
コンフィギュレーション設定例:スレッドダンプを実行して、その後、JVMを再起動する
wrapper.timer.1.action=dump, restart

複数の時刻:

複数の時刻を指定するには、単純にプロパティに1以上のナンバリングを付加して新しくプロパティを追加してください。

コンフィギュレーション設定例:毎日03:55, 12:55, 21:55の複数の時刻にスレッドダンプを実行する
wrapper.timer.1.interval=hour=3; minute=55
wrapper.timer.1.action=dump
wrapper.timer.2.interval=hour=12; minute=55
wrapper.timer.2.action=dump
wrapper.timer.3.interval=hour=21; minute=55
wrapper.timer.3.action=dump

一部のアプリケーションにはタイマー機能が動作しない場合もあります。

再起動

対応バージョン :3.3.0
対応エディション :プロフェッショナル版スタンダード版 (未対応)コミュニティー版 (未対応)
対応プラットフォーム :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

よくあるタイマー予約による動作アクションは「JVMの再起動」です。 再起動の動作は、メモリやリソースリークの回避策として、あるいは、 外部データベースと同期を取ったり、Wrapperコンフィギュレーションのリロード(再読み込み)するために、しばしば必要とされます。

アプリケーションで既知のメモリリークが起きると、JVMやアプリケーション、ライブラリベンダーによりリーク原因が修正されるまで、システム管理者は問題回避を実施しなければなりません。 社内システムのアプリケーションであっても、開発チームによる問題解決に時間を要することもあります。 その間にも、もしリークが放置されたままになれば、JVMは最大負荷状態でメモリ不足エラーが起こり始めることもあります。

そのような問題を避けるために、日曜のAM3時などユーザー利用の少ない時間帯に先行して JVMを再起動するように、Wrapperを設定することができます。

コンフィギュレーション設定例:毎週日曜3時に再起動する
wrapper.timer.1.interval=day-of-week=1; hour=3
wrapper.timer.1.action=restart
ログ出力例:
wrapper  | 2012/06/10 03:00:00 | Timer #1. JVM再起動中。
jvm 1    | 2012/06/10 03:00:01 | TestWrapper: stop(0)
jvm 2    | 2012/06/10 03:00:06 | WrapperManager: 初期化中...
jvm 2    | 2012/06/10 03:00:06 | TestWrapper: 初期化中...

スレッドダンプ

対応バージョン :3.3.0
対応エディション :プロフェッショナル版スタンダード版 (未対応)コミュニティー版 (未対応)
対応プラットフォーム :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

問題をデバッグする際に、後日の分析用に一定間隔でスレッドダンプを取得しておくと便利なことがあります。 5分毎にスレッドダンプをリクエストしたり、Wrapperでは簡単に実行することができます。

コンフィギュレーション設定例:5分毎にスレッドダンプをリクエスト
wrapper.timer.1.interval=minute=*/5
wrapper.timer.1.action=dump

警告

このようにログを利用する場合には、ログファイルのサイズ容量が スレッドダンプを保持できるくらい十分に大きく設定されていることを確認してください。

ポーズ(一時停止)とレジューム(再開)

対応バージョン :3.5.0
対応エディション :プロフェッショナル版スタンダード版 (未対応)コミュニティー版 (未対応)
対応プラットフォーム :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

もし、アプリケーションがポーズ(一時停止)することが可能状態である場合、 ポーズ(一時停止)やレジューム(再開)にタイマーを利用することができます。 アプリケーションがポーズ(一時停止)すると、そのJVMを停止するが、Wrapperは動作したままにすることもできます。 データベースのバックアップや、アプリケーションの動作中に実行できないようなタスクを実行するために、 このタイマー予約機能で一時停止時間をコントロールできることは、とても理想なことです。

以下のコンフィギュレーション設定例は、毎日AM3時にJVMを停止して、4時に再開しています。

コンフィギュレーション設定例:ポーズ(一時停止)とレジューム(再開)のスケジュール予約
wrapper.timer.1.interval=hour=3
wrapper.timer.1.action=pause
wrapper.timer.2.interval=hour=4
wrapper.timer.2.action=resume

このように停止時間を確保できることは最高に良いことですが、アプリケーションが毎回1時間、停止することになります。 もしバックアップが完了次第すぐに、アプリケーションを再開したい場合は、どうしますか?

バックアップスクリプトの最後に [wrapper.commandfile]プロパティの 「RESUME」コマンドを実行して「レジューム(再開)」することも実現可能です。 万一スクリプトに問題がある場合には、タイマー予約された再開の設定が必要です。 アプリケーションがポーズ(一時停止)状態でない場合、タイマーからのレジューム(再開)アクション指示は無視されます。

Javaタスク

対応バージョン :3.5.0
対応エディション :プロフェッショナル版スタンダード版 (未対応)コミュニティー版 (未対応)
対応プラットフォーム :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

タイマーアクション「RESUME」のその他の利用方法として、 短時間だけJavaアプリケーションを起動させて、予約タスクを実行してから終了させることもできます。 [wrapper.on_exit.<n>]プロパティとタイマーの「RESUME」を組み合わせて、 JVMが終了するといつでもWrapperをポーズ(一時停止)状態にさせることができ、その後、タイマー時刻で再始動します。

例えば、次のコンフィギュレーション設定例では、Wrapperが最初に起動したときにはJVMを起動させず、 待機した後に、1時間のインターバル(一定間隔)でJVMを起動させます。 アプリケーションはタスクを実行して終了します。 その間、Wrapperが終了したりJVMを再起動させることなく、Wrapperはポーズ(一時停止)状態に入ります。 この処理はWrapperがシャットダウンされるまで1時間毎に繰り返されます。

コンフィギュレーション設定例:ポーズ(一時停止)とレジューム(再開)の予約
wrapper.pausable=TRUE
wrapper.pause_on_startup=TRUE
wrapper.timer.1.interval=minute=60
wrapper.timer.1.action=resume
wrapper.on_exit.default=PAUSE

単純にJVMをアイドル状態のままでなく、必要に応じてJavaアプリケーションを起動させる最大の利点は、 不要なときにはJVMプロセスをシャットダウンさせることで、システムリソースを大いに節約することができます。

ユーザー定義アクション

対応バージョン :3.5.0
対応エディション :プロフェッショナル版スタンダード版 (未対応)コミュニティー版 (未対応)
対応プラットフォーム :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/Linux

さらに、Wrapperでは、外部コマンドを実行したり、メール通知を送信したり、時間を指定してスケジュール予約することも可能です。 これらは、ユーザー定義イベントを利用します。

次の例では、10分毎にクリーンアップスクリプトを実行する例です。

コンフィギュレーション設定例:クリーンアップコマンドを実行するスケジュール予約
wrapper.event.user_100.command.argv.1=cleanup
wrapper.timer.1.interval=minute=*/10
wrapper.timer.1.action=user_100

コマンドやメール通知の設定に関して、さらに詳しくはイベント概要ページをご覧ください。

参照:コンフィギュレーション プロパティ

Java Service Wrapperでは、必要なコンフィギュレーション設定を含んだ完全なパッケージを提供しており、 それを活用することで、皆様の求めるニーズに合った動作を実現させることができます。 上記の例の他に、工夫次第で様々なことが実現可能となりますので、それぞれ個別にプロパティページをご覧ください。