Java implements dual daemon for server programs in Linux
I. Introduction many of the current server-side programs are developed based on Java. For Socket programs developed for Java, You need to manually restart the server after the server goes online. In case of a failure in the middle of the night, it is still very troublesome. Most of the solutions are to use other processes to daemon the server program. If the server program fails, the daemon process is used to start the server program. What if the daemon fails? Use dual-daemon to improve stability. Daemon A is responsible for monitoring server programs and daemon B. Daemon B is responsible for monitoring and daemon A. If any party has problems, it can quickly start the program, improve the stability of the server program. The Java Runtime Environment is different from programs developed in C and other languages. Java programs run on JVM. Unlike the C language, you can directly create a process. Creating a process in Java is equivalent to starting a program using java-jar xxx. jar. The Java Startup Program does not have A single instance limitation similar to C #. You can start multiple programs, but you cannot start multiple programs. You cannot have multiple daemon A to daemon the server program, what if I start multiple server programs? Ii. technical explanation the technical explanation here is rough. Please refer to Baidu for details. Here we will only explain the functions. 1. jps command. The command tool that comes with JDK. You can use jps-l to list running Java programs and display the pid and Name of the Java program. It is only valid for Java programs. In fact, you can view the running JVM2 and java. nio. channels. the FileLock class is used in Java new IO. It can be used to maintain a lock on the file to be read, when checking the file, you can determine whether the file is used by other programs. 3. The ProcessBuilder and Process principles are similar. They all call the system command to run and then return information. However, hard coding will lead to the loss of portability of your Java program. You can separate the commands into the configuration file. Iii. Design Principle Server: Server program A: Daemon AB: Daemon BA. lock: file lock of daemon a B. lock: file lock of daemon B -------------------------------------------------------------------------------- Step 1: Consider Server first, only the daemon 1 between A and B. A determines whether B is alive. If B is not, B starts B2. B to determine whether A is alive. If A is not, A starts A3. during the running process, A and B get each other's filelock. If yes, if the opposite side is down, start the other side. 4. A obtains. lock file lock. If the lock proves that A is not started, A runs. If the lock is not obtained, it indicates that A is started, or B gets the lock when judging, if A has been started and A does not need to be started again, B will start A again if the lock is obtained when B determines that it is not locked. 5. The principle of B startup is the same as that of. 6. If A crashes during running and B determines that A is down, it starts. B. Step 2: Add Server1.A to guard B and Server, and B to guard. 2. The principle is the same as Step 1. Only A has multiple tasks that guard the Serer. 3. when A is running, use the process pid to detect that the Server is down and start Server4. if both Server and A are down, B will start, then A starts Server5. if Server and B are down, A starts Server and B6. if both A and B are down, the daemon ends Step 3: Use Shutdown to end the daemon, otherwise, the Server will be automatically started after the end. 4. Implementation 1. GuardA implementation copy code 1 public class GuardA {2 // GuardA is used to maintain its own lock 3 private File fileGuardA; 4 private FileOutputStream fileOutputStreamGuardA; 5 private FileChannel fileChannelGuardA; 6 private FileLock fileLockGuardA; 7 // GuardB is used to detect the 8 private locks of B. File fileGuardB; 9 private FileOutputStream fileOutputStreamGuardB; 10 private FileChannel fileChannelGuardB; 11 private FileLock fileLockGuardB; 12 13 public GuardA () throws Exception {14 fileGuardA = new File (Configure. GUARD_A_LOCK); 15 if (! FileGuardA. exists () {16 fileGuardA. createNewFile (); 17} 18 // get the filelock. If no GuardA is enabled, Exit 19 fileOutputStreamGuardA = new FileOutputStream (fileGuardA); 20 fileChannelGuardA = fileOutputStreamGuardA. getChannel (); 21 fileLockGuardA = fileChannelGuardA. tryLock (); 22 if (fileLockGuardA = null) {23 System. exit (0); 24} 25 26 fileGuardB = new File (Configure. GUARD_ B _LOCK); 27 if (! FileGuardB. exists () {28 fileGuardB. createNewFile (); 29} 30 fileOutputStreamGuardB = new FileOutputStream (fileGuardB); 31 fileChannelGuardB = fileOutputStreamGuardB. getChannel (); 32} 33 34/** 35 * check whether B exists 36*37 * @ return true B already exists 38 */39 public boolean checkGuardB () {40 try {41 fileLockGuardB = fileChannelGuardB. tryLock (); 42 if (fileLockGuardB = null) {43 return true; 44} else {45 fileLockGuardB. re Lease (); 46 return false; 47} 48} catch (IOException e) {49 System. exit (0); 50 // never touch51 return true; 52} 53} 54} copy code 2. Implement GuardServer copy code 1 public class GuardServer {2 private String servername; 3 4 public GuardServer (String servername) {5 this. servername = servername; 6} 7 8 public void startServer (String cmd) throws Exception {9 System. out. println ("Start Server:" + cmd); 10 // separate commands by 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 // locate the output of the server program to the/dev/tty17 builder. redirectOutput (new File ("/dev/tty"); 18 builder. redirectError (new File ("/dev/tty"); 19 builder. start (); // throws IOException20 Thread. sleep (10000); 21} 22 23/** 24 * check whether the service exists 25*26 * @ r Eturn returns the configured java program pid27 * @ return pid> 0 returns pid <= 0 indicates that the specified java program is not running 28 ***/29 public int checkServer () throws Exception {30 int pid =-1; 31 Process process = null; 32 BufferedReader reader = null; 33 process = runtime.getruntime(.exe c ("jps-l "); 34 reader = new BufferedReader (new InputStreamReader (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 return pid; 48} 49} copy code 3. Copy code 1 public class GuardAMain {2 public static void main (String [] args) throws Exception {3 GuardA guardA = new GuardA (); 4 Config Ure configure = new Configure (); 5 GuardServer server = new GuardServer (configure. getServername (); 6 while (true) {7 // if GuardB is not running run GuardB 8 if (! GuardA. checkGuardB () {9 System. out. println ("Start GuardB ..... "); 10 runtime.getruntime(cmd.exe c (configure. getStartguardb (); 11} 12 // detect server survival 13 if (server. checkServer () <= 0) {14 boolean isServerDown = true; 15 // trip check16 for (int I = 0; I <3; I ++) {17 // if the service is alive 18 if (server. checkServer ()> 0) {19 isServerDown = false; 20 break; 21} 22} 23 if (isServerDown) 24 server. startServer (configure. getSta Rtserver (); 25} 26 Thread. sleep (configure. getInterval (); 27} 28} 29} copy Code 4. Shutdown implement copy code 1 public class ShutDown {2 public static void main (String [] args) throws Exception {3 Configure configure = new Configure (); 4 System. out. println ("Shutdown Guards .. "); 5 for (int I = 0; I <3; I ++) {6 Process p = runtime.getruntime(cmd.exe c (" jps-l "); 7 BufferedReader reader = new BufferedReader (new InputS TreamReader (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(.exe c (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}