Я все еще готовлюсь проверить это, но я хотел бы получить некоторые комментарии, прежде чем идти дальше. Я настраиваю обработку нехватки памяти с помощью JVM в gradle. Часть этого включает создание сценария перезапуска, который будет вызываться в OOM с помощью параметров JVM.
Как это работает, я сначала
task appStartScripts(type: CreateStartScripts) {
def tplName = 'startBinTemplate.sh'
assert project.file(tplName).exists()
unixStartScriptGenerator.template = resources.text.fromFile(tplName)
defaultJvmOpts = [
"-XX:+HeapDumpOnOutOfMemoryError",
"-XX:HeapDumpPath=\$HOME/apps/log/",
"-XX:OnOutOfMemoryError=./restart.sh",
"-Xms1G", "-Xmx2G",
"-Dapp.name=${rootProject.name}"]
dependsOn shadowJar
applicationName = 'start'
defaultJvmOpts += ["-Dspring.profiles.active=ENV_VARIABLE"]
classpath = startShadowScripts.classpath
mainClassName = startShadowScripts.mainClassName
outputDir = new File(project.buildDir, 'scriptsShadow')
doLast {
unixScript.text = unixScript.text.replace('\\$HOME', '\'"$HOME"\'')
unixScript.text = unixScript.text.replace('ENV_VARIABLE', '\'"$1"\'')
}
}
Теоретически при ошибке нехватки памяти будет вызван сценарий перезапуска:
#!/usr/bin/env sh
kill -9 %p
sleep 5
./start.sh
Который убьет процесс, заснет на 5 секунд, а затем использует сценарий запуска, чтобы перезапустить его. Мой вопрос касается %p
аргумента в пользу убийства. Могу ли я использовать его в сценарии в этом контексте, в отличие от самого аргумента JVM? Насколько я понимаю, его следует передать аргументу JVM, который затем будет использовать его для передачи PID службы, чтобы убить службу. В моем случае я использую его в скрипте, так как попытка передать kill -9 %p
в $JVM_ARGS вызывает ошибку при запуске:
Unrecognized option: -9
тогда как передача вызываемого скрипта, похоже, не вызывает никаких проблем.
Я все еще настраиваю тестовый пример для этого, но я хотел спросить:
🤔 А знаете ли вы, что...
Java поддерживает многопоточность, что позволяет создавать многозадачные приложения.
%p
заполнитель разрешается JVM при выполнении OnOutOfMemoryError
. Вам нужно будет использовать в команде -XX:OnOutOfMemoryError=./restart.sh %p
, а затем прочитать ее из $1
в restart.sh
.
У современной JVM есть опция ExitOnOutOfMemoryError
, которая ведет себя так же, как OnOutOfMemoryError = "kill -9 %p"
(см. JDK-8152669). Вы можете комбинировать это с скриптом bash, показанным в этом ответе:
#!/bin/sh
while true ; do
java -XX:+ExitOnOutOfMemoryError -jar application.jar
sleep 5
done