如果通过 SSH 连接到远程服务器的 PC 关闭,远程服务器上的 Java 进程也会终止

如果通过 SSH 连接到远程服务器的 PC 关闭,远程服务器上的 Java 进程也会终止

我有一台通过 ssh 连接到正在运行 Java 程序的 Amazon EC2 实例的 PC。当我使用Ctrl+断开连接时C,一切正常,程序继续按预期运行。

但是如果我关闭我的电脑或者假设断电了(在我所在地区有时会发生这种情况)而我仍然通过 SSH 连接到该 Amazon EC2 实例,那么 Java 程序将停止运行。

这非常烦人,我不知道如何解决这个问题。我像这样运行我的程序:

java  -Xms2g -Xmx3g  -Djdk.tls.ephemeralDHKeySize=2048 -jar -Dlogging.config=logback.xml  -Dspring.profiles.active=prod web.war >> log.txt & echo $! > pid.txt

服务器有一个 HTTPD 进程,用于向 Java 发送请求。如果需要任何其他信息,请告诉我,我会更新问题。

答案1

在启动 java 进程时,您只需在 bash shell 中使用 nohup 将输出重定向到文件并将其置于后台即可:

$ nohup java -Xms2g -Xmx3g  -Djdk ... etc ... > myoutfile.log 2>&1 &

完成后,您可以查看 myoutfile.log 以查看是否一切正常并且注销不会停止该过程。

答案2

我认为您的 java 进程停止是因为 bash 进程在 ssh 退出时停止。而 bash 的默认行为是向所有子进程发送 HUP 信号(这基本上会停止您的 java 进程)。以下是有关此主题的示例问题。https://stackoverflow.com/questions/21294283/when-did-hup-stop-getting-sent-and-what-c​​an-i-do-about-it 防止这种情况的正确方法 - 创建 systemd 或 init.d 启动服务。

对于 AWS Linux 1,您必须创建 init.d 脚本。对于 AWS Linux 2,systemd 用作服务编排器。以下是示例脚本 -https://stackoverflow.com/questions/21503883/spring-boot-application-as-a-service/22121547#22121547

作为解决方法,您可以尝试使用 screen 或 tmux -https://askubuntu.com/questions/8653/how-to-keep-processes-running-after-ending-ssh-session/8657#8657

答案3

如果您通过 shell 将该进程作为交互式程序启动,则关闭该 shell 也会终止所有相关进程,这是完全正常的。即使您使用&,该进程仍属于交互式 shell 的“作业跟踪”,并且在关闭终端时仍会收到 SIGHUP。

您可以通过使用disown取消跟踪后台作业或使用nohup让其忽略 SIGHUP 信号来避免这种情况。

然而,服务通常不是这样启动的。各地的 Web 服务器没有人 24/7 保持 SSH 连接打开,也没有人在重启后手动启动每个 Java 应用程序——他们使用服务经理该操作系统具有。

例如,如果 systemd 可用(即列出各种服务),则创建一个如下所示的systemctl配置文件:/etc/systemd/system/MyJavaWebapp.service

[Unit]
Description=Website server

[Service]
Type=simple
ExecStart=/usr/bin/java -Xms2g -Xmx3g -Djdk.tls.ephemeralDHKeySize=2048 -jar -Dlogging.config=logback.xml -Dspring.profiles.active=prod web.war
User=webapp
WorkingDirectory=/home/webapp

[Install]
WantedBy=multi-user.target

通过这个,您可以systemctl start MyJavaWebapp让它运行,也可以systemctl enable让服务管理器在每次重新启动时自动启动它。您甚至可以包括一些选项,例如Restart=on-failure让管理器自动监视崩溃。

对于 Upstart 或 SysVinit(现在很少见),配置会有点不同。

相关内容