我有一个java项目,作为服务器。当这个项目的一个实例运行时,我可以运行另一个实例 我怎样才能避免同时在同一个java项目上运行多个实例? (检测到其他实例时停止服务器)
答案 0 :(得分:3)
import java.net.ServerSocket;
.....
private static final int PORT = 9999;
private static ServerSocket socket;
public static void main(String[] args) {
try {
socket = new ServerSocket(PORT, 0, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }));
{/*here write your own code taht must be run in the main*/}
} catch (BindException e) {
System.err.println("**********************************Already running.");
System.exit(1);
} catch (IOException e) {
System.err.println("************************************Unexpected error.");
e.printStackTrace();
System.exit(2);
} catch (Exception e) {
System.err.println("************************************ Error");
System.exit(3);
}
}
我使用了这段代码并尝试了它
答案 1 :(得分:2)
最简单的方法是使用锁定文件,如果应用程序崩溃,这会导致问题。尝试将pid写入锁定文件,您可以检查该pid是否存在(虽然本身可能不是在包装器shell脚本中)。
如果您正在运行服务器,则无法检查端口是否已打开,或者更好的可能是已知端口上的jmx实例。
答案 2 :(得分:1)
我完全支持@vickirk - 他的方法允许服务器的第二个“不需要的”实例变为“休眠”而不是简单地终止,即定期运行以执行检查“活动”实例是否仍然实际处于活动状态/现在,如果它下降,接管。
在分布式案例中,如果要求是将单个服务器实例跨越多台计算机,则该方法仍然是找到可以物理或逻辑锁定的公共资源。为此,我个人使用一个控制数据库表,其中一个活动进程写入其PID和“心跳”,而所有其他人正在检查该“心跳”是否相当近,并且如果不是则会变为活动状态。
答案 3 :(得分:0)
您可以为app start编写简单的命令行脚本 - 该检查是在实际运行新实例之前运行的服务器。只需用wget检查网址,例如......