このトピックでは、アプリケーションで実行されているジョブとタスクをグレースフルシャットダウンする方法について説明します。
背景情報
実際のビジネスシナリオでは、スケジュールされたジョブは、アプリケーションプロセスで一定の間隔で継続的に実行されます。リリース中にアプリケーションが再起動されると、アプリケーションプロセスを一時的にシャットダウンする必要があります。アプリケーションを閉じると、実行中のスケジュールされたジョブが中断され、データの不完全性やその他の問題が発生する可能性があります。このような状況を防ぐために、SchedulerX では、スケジュールされたジョブのグレースフルシャットダウンを実装できます。実行中のジョブが完了するまで待ってから、アプリケーションを安全に閉じることができます。
制限事項
SchedulerX クライアントのバージョンは 1.10.8 以降である必要があります。
グレースフルシャットダウンの図
設定方法
SchedulerX は、スタンドアロンモードおよび分散モードで実行されるジョブに対して、グレースフルシャットダウン機能を提供します。リアルタイムのオンラインジョブとは異なり、オフラインのスケジュールされたジョブは完了までに長い時間がかかる場合があります。ただし、グレースフルシャットダウン機能を有効にすると、アプリケーションプロセスはオフラインのスケジュールされたジョブが完了するまで無限に待機することはありません。次のコードを実行して、アプリケーションプロセスがシャットダウンされるまでの時間を延長できます。
# グレースフルシャットダウンモード。WAIT_ALL:すべてのジョブが完了するまで待機します。WAIT_RUNNING:実行中のジョブが完了するまで待機します。
# このパラメータを設定しない場合、グレースフルシャットダウン機能は無効になります。デフォルトでは、グレースフルシャットダウン機能は無効になっています。
spring.schedulerx2.graceShutdownMode=WAIT_ALL
# グレースフルシャットダウンのタイムアウト期間。単位:秒。デフォルトでは、グレースフルシャットダウンのタイムアウト期間は指定されていません。
spring.schedulerx2.graceShutdownTimeout=10
# HTTP サービスに必要なポートを有効にするかどうかを指定します。デフォルト値:false。
spring.schedulerx2.httpServerEnable=true
# シャットダウン専用の HTTP インターフェースを呼び出すことができるポート。デフォルトポート:51886。
spring.schedulerx2.httpServerPort=52333
グレースフルシャットダウンモード | 説明 |
| このモードでは、アプリケーション内のすべてのジョブとタスクが完了した後にのみ、アプリケーションが終了します。このモードをお勧めします。 |
| このモードでは、アプリケーション内でスレッドが割り当てられている実行中のジョブとタスクが完了すると、アプリケーションが終了します。キュー内のジョブとタスクは破棄されます。 |
手順
さまざまなデプロイメントモードのリリースプロセスをアプリケーションに簡単に統合できるように、次のいずれかの方法を使用してグレースフルシャットダウン機能を有効にできます。
方法 1: kill -15 を使用してアプリケーションプロセスをグレースフルシャットダウンする
SchedulerX SDK は、Java 仮想マシン(JVM)プロセスをシャットダウンするために必要なフック関数を提供し、アプリケーションをグレースフルに終了させます。アプリケーションプロセスをシャットダウンするには、kill -15 プロセス ID
コマンドを実行します。この場合、設定されたポリシーに基づいてジョブとタスクが完了した後、実行中のプロセスはグレースフルシャットダウンされます。
スクリプトを実行してアプリケーションをシャットダウンする場合、kill -9
コマンドを直接実行しないことをお勧めします。そうしないと、グレースフルシャットダウンは機能しません。一部のアプリケーションでは、最初に kill -15
コマンドを実行し、一定期間アプリケーションを監視してから、kill -9
コマンドを実行してアプリケーションを強制的にシャットダウンすることをお勧めします。リリースプロセスが非常に遅くなるのを防ぐために、ジョブ属性に基づいてグレースフルシャットダウンの待機時間を指定することをお勧めします。
方法 2: SpringBoot シャットダウンイベントを使用してアプリケーションプロセスをグレースフルシャットダウンする
初期化された SpringBoot アプリケーションを SchedulerX に接続する場合、SpringBoot によって提供される actuator 機能を使用してグレースフルシャットダウンを実装できます。 actuator 機能は、Spring コンテナのシャットダウンイベントに応答しながら、スケジュールされたジョブをグレースフルシャットダウンできます。
SpringBoot actuator 機能を有効にするには、次の手順を実行します。
次のコードを実行して、目的のアプリケーションの
pom.xml
ファイルに依存関係を追加します。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
次のコードを実行して、シャットダウンポートを有効にします。
management.endpoint.shutdown.enabled=true
management.endpoints.web.exposure.include=shutdown
次のコードを実行して、グレースフルシャットダウンを実装します。
curl -X GET http://ノードIP:ポート/actuator/shutdown
方法 3: HTTP インターフェースを使用してアプリケーションプロセスをグレースフルシャットダウンする
次のパラメータを設定して、現在のアプリケーションプロセスでスケジュールされたジョブをシャットダウンするための外部リクエストに応答するために HTTP サービスに必要なポートを有効にします。パラメータ:
# HTTP サービスに必要なポートを有効にするかどうかを指定します。デフォルト値:false。
spring.schedulerx2.httpServerEnable=true
# シャットダウン専用の HTTP インターフェースを呼び出すことができるポート。デフォルトポート:51886。
spring.schedulerx2.httpServerPort=51886
次の HTTP インターフェースを呼び出して、スケジュールされたジョブをグレースフルシャットダウンできます。
curl -X GET http://ノードIP:51886/schedulerx/worker/shutdown
統合ソリューション
ほとんどの場合、アプリケーションの再起動時にスケジュールされたジョブが破損するのを防ぐために、グレースフルシャットダウン機能を日常的にリリースされる O&M プロセスに統合する必要があります。ビジネス要件に基づいて、次のいずれかの定期的な統合ソリューションを使用できます。
シナリオ 1:グレースフルシャットダウンをセルフビルド CD プロセスに統合する
ほとんどの場合、セルフビルドの継続的デリバリー(CD)プロセスには、アプリケーションプロセスを停止できるノードが含まれています。ノードで stop.sth スクリプトをビルドして実行し、アプリケーションプロセスを終了させることができます。スクリプトコンテンツにグレースフルシャットダウンの処理ロジックを含める必要があります。ビジネス要件に基づいて、上記の方法のいずれかを参照できます。
CD プロセスのサンプル:
次のコードは、アプリケーションプロセスをシャットダウンするために使用されるサンプルスクリプトです。
# アプリケーションを起動した後、プロセス ID は app.pid ファイルに書き込まれます。
PID="{アプリケーションデプロイメントパス}/app.pid"
FORCE=1
if [ -f ${PID} ]; then
TARGET_PID=`cat ${PID}`
kill -15 ${TARGET_PID}
loop=1
while(( $loop<=5 ))
do
# health:現在のアプリケーションプロセスが終了するかどうかを指定します。ビジネス要件に基づいて health フィールドを設定できます。
health
if [ $? == 0 ]; then
echo "check $loop times, current app has not stop yet."
sleep 5s
let "loop++"
else
FORCE=0
break
fi
done
if [ $FORCE -eq 1 ]; then
echo "App(pid:${TARGET_PID}) stop timeout, forced termination."
kill -9 ${TARGET_PID}
fi
rm -rf ${PID}
echo "App(pid:${TARGET_PID}) stopped successful."
fi
シナリオ 2: Kubernetes コンテナ化デプロイメントの PreStop イベントにグレースフルシャットダウンを統合する
Kubernetes クラスタでポッドを破棄するために使用される PreStop イベントを使用して、アプリケーションのグレースフルシャットダウンをトリガーできます。また、exec を使用してスクリプトを実行したり、HTTP リクエストを開始したりして、PreStop フック関数を呼び出してグレースフルシャットダウンを実装できます。
Exec スクリプト:アプリケーションプロセスを直接シャットダウンします。または、プリセットの
stop.sh
スクリプトを実行して、アプリケーションプロセスを終了させることもできます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app-container
image: my-app-image:latest
lifecycle:
preStop:
exec:
# command: ["/bin/sh", "-c", "kill -15 PID && sleep 30"]
command: ["/bin/sh", "-c", "スクリプトパス /stop.sh"]
HTTP インターフェース:
SpringBoot actuator シャットダウン機能を有効にする場合は、パスを
/actuator/shutdown
に設定できます。Spring 以外のアプリケーションの場合は、SchedulerX SDK を使用して HTTP インターフェースを呼び出すことができるポートを有効にした後、パスを
/schedulerx/worker/shutdown
に設定して、グレースフルシャットダウンを実装できます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app-container
image: my-app-image:latest
lifecycle:
preStop:
httpGet:
path: /schedulerx/worker/shutdown
port: 51886
scheme: HTTP
シナリオ 3:グレースフルシャットダウンを Alibaba Cloud のアプリケーションリリースプラットフォームに統合する
Alibaba Cloud Enterprise Distributed Application Service(EDAS)を使用するか、Microservices Engine(MSE)と Container Service for Kubernetes(ACK)を使用してアプリケーションをリリースする場合、プラットフォームでグレースフルシャットダウン機能を有効にすると、SchedulerX のグレースフルシャットダウン機能は使用するプラットフォームに自動的に統合されます。詳細については、「Spring Cloud アプリケーションをグレースフルシャットダウンする」および「グレースフルシャットダウン」をご参照ください。