如何一直 运行 一个 Java 控制台应用程序?
How to run a Java console application all the time?
我有一个服务器 (Ubuntu 14.04.4 LTS) 并希望某个 Java 应用程序一直在 运行 上运行。目前我使用 nohup gradle run &
启动它。昨天它停止工作了。 nohup.out
显示以下错误消息:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':run'.
> Process 'command '/usr/lib/jvm/java-8-oracle/bin/java'' finished with non-zero exit value 137
我需要如何更改我的 Java 应用程序以防止将来出现此类错误(确保应用程序 运行 一直处于运行状态,并且 - 理想情况下 - 自动重新启动,如果它崩溃了)?我正在寻找简单、最小的解决方案。
请注意,我之前在这家特定公司的服务器上遇到过类似问题。我有一个带有 Web 应用程序的 Apache 服务器,有时它会无缘无故地停止工作(也许服务器因为低 activity 而进入睡眠状态,不知道)。
更新 1 (27.01.2017 12:30 MSK): 我修改了 Gradle 代码以在发生 OutOfMemoryError 时记录内存转储。
run {
jvmArgs = ["-Xmx100m", "-XX:+HeapDumpOnOutOfMemoryError", "-XX:HeapDumpPath=/home/dp/dev/myprod/log/memdump.log"]
}
当我 运行 Gradle 脚本时,我在输出中看到以下消息,从中我得出结论,内存转储参数定义正确。
09:33:47.031 [INFO] [org.gradle.process.internal.DefaultExecHandle] Starting process 'command '/usr/lib/jvm/java-8-oracle/bin/java''. Working directory: /home/dp/dev/myprod Command: /usr/lib/jvm/java-8-oracle/bin/java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/dp/dev/myprod/log/memdump.log [...] com.mycompany.myprod.AppKt
应用程序崩溃后,我没有看到文件/home/dp/dev/myprod/log/memdump.log
。目录 /home/dp/dev/myprod/log/
存在并且可由启动应用程序的用户访问。
我使用 nohup gradle --full-stacktrace --stacktrace --debug run &
启动应用程序,但它无助于获取有关问题原因的任何有意义的信息。
这是我得到的异常:
06:29:16.179 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] Caused by: org.gradle.process.internal.ExecException: Process 'command '/usr/lib/jvm/java-8-oracle/bin/java'' finished with non-zero exit value 137
06:29:16.180 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.process.internal.DefaultExecHandle$ExecResultImpl.assertNormalExitValue(DefaultExecHandle.java:369)
06:29:16.186 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.process.internal.DefaultJavaExecAction.execute(DefaultJavaExecAction.java:31)
06:29:16.186 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.tasks.JavaExec.exec(JavaExec.java:74)
06:29:16.186 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
06:29:16.186 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.doExecute(DefaultTaskClassInfoStore.java:136)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:129)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:118)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:623)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:606)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
06:29:16.188 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
06:29:16.194 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] ... 68 more
06:29:16.205 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]
如评论中所述,这是内存不足异常,您可以这样做:
回顾你的代码,也许你的代码性能不佳。
如果您 运行 是一个简单的 "java application" 您可以,而不是单击 "Run As.. Java Application" 单击 "Run As.. Run Configration",select 您的 java 应用程序和在 TAB "Arguments"、"VM Arguments" 中添加此参数:
-Xmx1024m -Xms512m
使用此参数,您可以在应用程序(开始时)上分配最少 512M 的空间,最多分配 1024M 的空间。您可以根据需要放大此数字。
首先,您应该尝试查找并解决应用程序中的内存不足问题。
要设置监控,您可以编写一个简单的脚本来检查您的应用程序是否 运行ning。
检查应用程序是否正在侦听指定端口或使用
检查
ps aux
或任何其他适合您的方式。
如果应用程序已关闭,请重新启动它。
现在设置一个 cron,每隔几分钟 运行 运行一次这个脚本。
像
*/10 * * * * /your/script
这将每 10 分钟 运行 您的脚本。
基本上,这不是一个好的做法。您应该避免使用构建工具,并在 运行 之前将其打包为可执行 JAR。如果您出于某种原因需要在启动期间解决工件问题,请查看 Capsule project and Gradle Capsule Plugin.
Gradle 3.+ 默认使用守护进程。如果它已闲置 3 小时或更长时间 Gradle 将杀死守护进程。我不确定是不是这个原因,但您可以尝试从 --no-daemon
参数开始。
我有一个服务器 (Ubuntu 14.04.4 LTS) 并希望某个 Java 应用程序一直在 运行 上运行。目前我使用 nohup gradle run &
启动它。昨天它停止工作了。 nohup.out
显示以下错误消息:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':run'.
> Process 'command '/usr/lib/jvm/java-8-oracle/bin/java'' finished with non-zero exit value 137
我需要如何更改我的 Java 应用程序以防止将来出现此类错误(确保应用程序 运行 一直处于运行状态,并且 - 理想情况下 - 自动重新启动,如果它崩溃了)?我正在寻找简单、最小的解决方案。
请注意,我之前在这家特定公司的服务器上遇到过类似问题。我有一个带有 Web 应用程序的 Apache 服务器,有时它会无缘无故地停止工作(也许服务器因为低 activity 而进入睡眠状态,不知道)。
更新 1 (27.01.2017 12:30 MSK): 我修改了 Gradle 代码以在发生 OutOfMemoryError 时记录内存转储。
run {
jvmArgs = ["-Xmx100m", "-XX:+HeapDumpOnOutOfMemoryError", "-XX:HeapDumpPath=/home/dp/dev/myprod/log/memdump.log"]
}
当我 运行 Gradle 脚本时,我在输出中看到以下消息,从中我得出结论,内存转储参数定义正确。
09:33:47.031 [INFO] [org.gradle.process.internal.DefaultExecHandle] Starting process 'command '/usr/lib/jvm/java-8-oracle/bin/java''. Working directory: /home/dp/dev/myprod Command: /usr/lib/jvm/java-8-oracle/bin/java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/dp/dev/myprod/log/memdump.log [...] com.mycompany.myprod.AppKt
应用程序崩溃后,我没有看到文件/home/dp/dev/myprod/log/memdump.log
。目录 /home/dp/dev/myprod/log/
存在并且可由启动应用程序的用户访问。
我使用 nohup gradle --full-stacktrace --stacktrace --debug run &
启动应用程序,但它无助于获取有关问题原因的任何有意义的信息。
这是我得到的异常:
06:29:16.179 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] Caused by: org.gradle.process.internal.ExecException: Process 'command '/usr/lib/jvm/java-8-oracle/bin/java'' finished with non-zero exit value 137
06:29:16.180 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.process.internal.DefaultExecHandle$ExecResultImpl.assertNormalExitValue(DefaultExecHandle.java:369)
06:29:16.186 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.process.internal.DefaultJavaExecAction.execute(DefaultJavaExecAction.java:31)
06:29:16.186 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.tasks.JavaExec.exec(JavaExec.java:74)
06:29:16.186 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
06:29:16.186 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.doExecute(DefaultTaskClassInfoStore.java:136)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:129)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:118)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:623)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:606)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
06:29:16.188 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
06:29:16.194 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] ... 68 more
06:29:16.205 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]
如评论中所述,这是内存不足异常,您可以这样做:
回顾你的代码,也许你的代码性能不佳。
如果您 运行 是一个简单的 "java application" 您可以,而不是单击 "Run As.. Java Application" 单击 "Run As.. Run Configration",select 您的 java 应用程序和在 TAB "Arguments"、"VM Arguments" 中添加此参数:
-Xmx1024m -Xms512m
使用此参数,您可以在应用程序(开始时)上分配最少 512M 的空间,最多分配 1024M 的空间。您可以根据需要放大此数字。
首先,您应该尝试查找并解决应用程序中的内存不足问题。
要设置监控,您可以编写一个简单的脚本来检查您的应用程序是否 运行ning。 检查应用程序是否正在侦听指定端口或使用
检查ps aux
或任何其他适合您的方式。
如果应用程序已关闭,请重新启动它。
现在设置一个 cron,每隔几分钟 运行 运行一次这个脚本。 像
*/10 * * * * /your/script
这将每 10 分钟 运行 您的脚本。
基本上,这不是一个好的做法。您应该避免使用构建工具,并在 运行 之前将其打包为可执行 JAR。如果您出于某种原因需要在启动期间解决工件问题,请查看 Capsule project and Gradle Capsule Plugin.
Gradle 3.+ 默认使用守护进程。如果它已闲置 3 小时或更长时间 Gradle 将杀死守护进程。我不确定是不是这个原因,但您可以尝试从
--no-daemon
参数开始。