100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > java 守护进程 linux_Java实现Linux下服务器程序的双守护进程

java 守护进程 linux_Java实现Linux下服务器程序的双守护进程

时间:2022-01-16 06:31:24

相关推荐

java 守护进程 linux_Java实现Linux下服务器程序的双守护进程

一、简介

现在的服务器端程序很多都是基于Java开发,针对于Java开发的Socket程序,这样的服务器端上线后出现问题需要手动重启,万一大半夜的挂了,还是特别麻烦的。

大多数的解决方法是使用其他进程来守护服务器程序,如果服务器程序挂了,通过守护进程来启动服务器程序。

万一守护进程挂了呢?使用双守护来提高稳定性,守护A负责监控服务器程序与守护B,守护B负责监控守护A,任何一方出现问题,都能快速的启动程序,提高服务器程序的稳定性。

Java的运行环境不同于C等语言开发的程序,Java程序跑在JVM上面。不同于C语言可以直接创建进程,Java创建一个进程等同于使用java -jar xxx.jar启动一个程序。

Java启动程序并没有C#类似的单实例限制,你可以启动多个,但是你不能启动多个,不能让多个守护A去守护服务器程序,万一启动了多个服务器程序怎么办?

二、技术讲解

这里的技术讲解比较粗略,具体请百度一下,这里只讲解作用。

1、jps命令。

JDK自带的命令工具,使用jps -l可以列出正在运行的Java程序,显示Java程序的pid与Name。只对Java程序有效,其实查看的是运行的JVM

2、java.nio.channels.FileLock类的使用

这个是Java new IO中的类,使用他可以维持在读取文件的给文件加上锁,判断文件时候有锁可以判断该文件是否被其他的程序使用

3、ProcessBuilder与Process

这两个原理差不多,都是调用系统的命令运行,然后返回信息。但是硬编码会导致你的Java程序失去可移植性,可以将命令独立到配置文件中。

三、设计原理

Server:服务器程序

A:守护进程A

B:守护进程B

A.lock:守护进程A的文件锁

B.lock:守护进程B的文件锁

----------------------------------------------------------------------------------

Step 1:首先不考虑Server,只考虑A与B之间的守护

1.A判断B是否存活,没有就启动B

2.B判断A是否存活,没有就启动A

3.在运行过程中A与B互相去拿对方的文件锁,如果拿到了,证明对面挂了,则启动对方。

4.A启动的时候,获取A.lock文件的锁,如果拿到了证明没有A启动,则A运行;如果没有拿到锁,证明A已经启动了,或者是B判断的时候拿到了锁,如果是A已经启动了,不需要再次启动A,如果是B判断的时候拿到了锁,没关紧要,反正B会再次启动A。

5.B启动的时候原理与A一致。

6.运行中如果A挂了,B判断到A已经挂了,则启动A。B同理。

Step 2:加入Server

1.A用于守护B和Server,B用于守护A。

2.原理与Step 1 一致,只是A多个一个守护Serer的任务。

3.当A运行的时候,使用进程pid检测到Server已经挂了,就启动Server

4.如果Server与A都挂了,B会启动A,然后A启动Server

5.如果Server与B挂了,A启动Server与B

6.如果A与B都挂了,守护结束

Step 3:使用Shutdown结束守护,不然结束Server后会自动启动

四、实现

1、GuardA的实现

1 public classGuardA {2 //GuardA用于维持自己的锁

3 privateFile fileGuardA;4 privateFileOutputStream fileOutputStreamGuardA;5 privateFileChannel fileChannelGuardA;6 privateFileLock fileLockGuardA;7 //GuardB用于检测B的锁

8 privateFile fileGuardB;9 privateFileOutputStream fileOutputStreamGuardB;10 privateFileChannel fileChannelGuardB;11 privateFileLock fileLockGuardB;12

13 public GuardA() throwsException {14 fileGuardA = newFile(Configure.GUARD_A_LOCK);15 if (!fileGuardA.exists()) {16 fileGuardA.createNewFile();17 }18 //获取文件锁,拿不到证明GuardA已启动则退出

19 fileOutputStreamGuardA = newFileOutputStream(fileGuardA);20 fileChannelGuardA =fileOutputStreamGuardA.getChannel();21 fileLockGuardA =fileChannelGuardA.tryLock();22 if (fileLockGuardA == null) {23 System.exit(0);24 }25

26 fileGuardB = newFile(Configure.GUARD_B_LOCK);27 if (!fileGuardB.exists()) {28 fileGuardB.createNewFile();29 }30 fileOutputStreamGuardB = newFileOutputStream(fileGuardB);31 fileChannelGuardB =fileOutputStreamGuardB.getChannel();32 }33

34 /**

35 * 检测B是否存在36 *37 *@returntrue B已经存在38 */

39 public booleancheckGuardB() {40 try{41 fileLockGuardB =fileChannelGuardB.tryLock();42 if (fileLockGuardB == null) {43 return true;44 } else{45 fileLockGuardB.release();46 return false;47 }48 } catch(IOException e) {49 System.exit(0);50 //never touch

51 return true;52 }53 }54 }

2、GuardServer的实现

1 public classGuardServer {2 privateString servername;3

4 publicGuardServer(String servername) {5 this.servername =servername;6 }7

8 public void startServer(String cmd) throwsException {9 System.out.println("Start Server : " +cmd);10 //将命令分开11 //String[] cmds = cmd.split(" ");12 //ProcessBuilder builder = new ProcessBuilder(cmds);13

14 //15 ProcessBuilder builder=new ProcessBuilder(new String[]{"/bin/sh","-c",cmd});16 //将服务器程序的输出定位到/dev/tty

17 builder.redirectOutput(new File("/dev/tty"));18 builder.redirectError(new File("/dev/tty"));19 builder.start(); //throws IOException

20 Thread.sleep(10000);21 }22

23 /**

24 * 检测服务是否存在25 *26 *@return返回配置的java程序的pid27 *@returnpid >0 返回的是 pid <=0 代表指定java程序未运行28 * **/

29 public int checkServer() throwsException {30 int pid = -1;31 Process process = null;32 BufferedReader reader = null;33 process = Runtime.getRuntime().exec("jps -l");34 reader = new BufferedReader(newInputStreamReader(process.getInputStream()));35 String line;36 while ((line = reader.readLine()) != null) {37 String[] strings = line.split("\\s{1,}");38 if (strings.length < 2)39 continue;40 if (strings[1].contains(servername)) {41 pid = Integer.parseInt(strings[0]);42 break;43 }44 }45 reader.close();46 process.destroy();47 returnpid;48 }49 }

3、GuardAMain实现

1 public classGuardAMain {2 public static void main(String[] args) throwsException {3 GuardA guardA = newGuardA();4 Configure configure = newConfigure();5 GuardServer server = newGuardServer(configure.getServername());6 while (true) {7 //如果GuardB未运行 运行GuardB

8 if (!guardA.checkGuardB()) {9 System.out.println("Start GuardB.....");10 Runtime.getRuntime().exec(configure.getStartguardb());11 }12 //检测服务器存活

13 if (server.checkServer() <= 0) {14 boolean isServerDown = true;15 //trip check

16 for (int i = 0; i < 3; i++) {17 //如果服务是存活着

18 if (server.checkServer() > 0) {19 isServerDown = false;20 break;21 }22 }23 if(isServerDown)24 server.startServer(configure.getStartserver());25 }26 Thread.sleep(configure.getInterval());27 }28 }29 }

4、Shutdown实现

1 public classShutDown {2 public static void main(String[] args) throwsException {3 Configure configure = newConfigure();4 System.out.println("Shutdown Guards..");5 for (int i = 0; i < 3; i++) {6 Process p = Runtime.getRuntime().exec("jps -l");7 BufferedReader reader = new BufferedReader(newInputStreamReader(p.getInputStream()));8 String line;9 while ((line = reader.readLine()) != null) {10 if (line.toLowerCase().contains("Guard".toLowerCase())) {11 String[] strings = line.split("\\s{1,}");12 int pid = Integer.parseInt(strings[0]);13 Runtime.getRuntime().exec(configure.getKillcmd() + " " +pid);14 }15 }16 p.waitFor();17 reader.close();18 p.destroy();19 Thread.sleep(2000);20 }21 System.out.println("Guards is shutdown");22 }23 }

5、GuardB与GuardA类似

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。