1. Einführung
Viele der heutigen serverseitigen Programme basieren auf Java. Wenn ein Problem auftritt, nachdem ein solches serverseitiges Programm online gegangen ist, muss es manuell neu gestartet werden, wenn es mitten in der Nacht hängt , es ist immer noch sehr problematisch.
Die meisten Lösungen bestehen darin, andere Prozesse zum Schutz des Serverprogramms zu verwenden. Wenn das Serverprogramm hängt, starten Sie das Serverprogramm über den Daemon-Prozess.
Was passiert, wenn der Daemon-Prozess hängt? Verwenden Sie zwei Wächter, um die Stabilität zu verbessern. Wächter A ist für die Überwachung des Serverprogramms und Wächter B verantwortlich. Wächter B ist für die Überwachung von Wächter A verantwortlich. Wenn auf einer Seite ein Problem auftritt, kann das Programm schnell gestartet werden, um die Stabilität des Servers zu verbessern Serverprogramm.
Die Ausführungsumgebung von Java unterscheidet sich von Programmen, die in Sprachen wie C entwickelt wurden. Java-Programme werden auf der JVM ausgeführt. Im Gegensatz zur C-Sprache, die einen Prozess direkt erstellen kann, entspricht das Erstellen eines Prozesses in Java der Verwendung von java -jar xxx.jar zum Starten eines Programms.
Das Java-Startprogramm hat keine Einzelinstanzbeschränkung wie C#. Sie können mehrere starten, aber Sie können nicht mehrere Wächter A haben, um das Serverprogramm zu schützen.
2. Technische Erklärung
Die technische Erklärung hier ist relativ grob. Bitte überprüfen Sie Baidu für Details. Ich erkläre hier nur die Funktionen.
1. jps-Befehl.
Das mit dem JDK gelieferte Befehlstool verwendet jps -l, um die ausgeführten Java-Programme aufzulisten und die PID und den Namen des Java-Programms anzuzeigen. Gilt nur für Java-Programme. Tatsächlich sehen Sie die laufende JVM.
2. Verwendung der Klasse java.nio.channels.FileLock. Dies ist eine Klasse in Java New IO. Sie können sie verwenden, um die Datei beim Lesen zu sperren Die Datei ist durch andere Programme gesperrt
3. ProcessBuilder und Process
Die beiden Prinzipien sind ähnlich. Beide rufen Systembefehle zur Ausführung auf und geben dann Informationen zurück. Eine harte Codierung führt jedoch dazu, dass Ihr Java-Programm seine Portabilität verliert. Sie können die Befehle in die Konfigurationsdatei aufteilen.
3. Gestaltungsprinzipien
Server: Serverprogramm
A: Daemon A
B: Daemon B
A.lock: Dateisperre von Daemon A
B.lock: Dateisperre von Daemon B
-------------------------------------------------- --------------------------------
Schritt 1: Betrachten Sie zunächst nicht den Server, sondern nur den Schutz zwischen A und B.
1.A bestimmt, ob B am Leben ist, und wenn nicht, startet B
2.B stellt fest, ob A am Leben ist, und startet A, wenn nicht.
3. Während des laufenden Prozesses gehen A und B zueinander, um die Dateisperre des anderen zu erhalten. Wenn sie diese erhalten, wird bewiesen, dass die andere Partei nicht verfügbar ist, und dann wird die andere Partei gestartet.
4. Wenn A startet, erhalten Sie die Sperre der A.lock-Datei. Wenn sie erhalten wird, beweist dies, dass A nicht gestartet ist Wenn B bei der Beurteilung die Sperre erhalten hat und A nicht erneut gestartet werden muss, spielt es keine Rolle, dass B trotzdem erneut mit A beginnen muss.
5. Wenn B gestartet wird, ist das Prinzip das gleiche wie bei A.
6. Wenn A während des Betriebs auflegt, stellt B fest, dass A aufgelegt hat, und startet A. Ähnlich.
Schritt 2: Dem Server beitreten
1.A wird zum Schutz von B und Server verwendet, und B wird zum Schutz von A verwendet.
2. Das Prinzip ist das gleiche wie in Schritt 1, außer dass A mehrere Aufgaben hat, nämlich Serer zu bewachen.
3. Wenn A ausgeführt wird, erkennen Sie anhand der Prozess-PID, dass der Server aufgehängt ist, und starten Sie dann den Server.
4. Wenn sowohl Server als auch A ausgefallen sind, startet B A und dann startet A den Server.
5. Wenn Server und B ausgefallen sind, startet A Server und B
6. Wenn sowohl A als auch B sterben, endet die Wache
Schritt 3: Verwenden Sie Shutdown, um den Guard zu beenden, andernfalls startet er automatisch nach dem Beenden des Servers.
4. Erkenntnis
1. Implementierung von GuardA
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse GuardA {
// GuardA wird verwendet, um seine eigene Sperre aufrechtzuerhalten
private Datei fileGuardA;
private FileOutputStream fileOutputStreamGuardA;
privater FileChannel fileChannelGuardA;
private FileLock fileLockGuardA;
// GuardB wird verwendet, um die Sperre von B zu erkennen
private Datei fileGuardB;
private FileOutputStream fileOutputStreamGuardB;
privater FileChannel fileChannelGuardB;
private FileLock fileLockGuardB;
public GuardA() löst eine Ausnahme aus {
fileGuardA = new File(Configure.GUARD_A_LOCK);
if (!fileGuardA.exists()) {
fileGuardA.createNewFile();
}
//Erwirb die Dateisperre und beende den Vorgang, wenn nicht nachgewiesen werden kann, dass GuardA gestartet wurde.
fileOutputStreamGuardA = new FileOutputStream(fileGuardA);
fileChannelGuardA = fileOutputStreamGuardA.getChannel();
fileLockGuardA = fileChannelGuardA.tryLock();
if (fileLockGuardA == null) {
System.exit(0);
}
fileGuardB = new File(Configure.GUARD_B_LOCK);
if (!fileGuardB.exists()) {
fileGuardB.createNewFile();
}
fileOutputStreamGuardB = new FileOutputStream(fileGuardB);
fileChannelGuardB = fileOutputStreamGuardB.getChannel();
}
/**
* Prüfen Sie, ob B existiert
*
* @return true B existiert bereits
*/
public boolean checkGuardB() {
versuchen {
fileLockGuardB = fileChannelGuardB.tryLock();
if (fileLockGuardB == null) {
return true;
} anders {
fileLockGuardB.release();
return false;
}
} Catch (IOException e) {
System.exit(0);
// niemals berühren
return true;
}
}
}
2. Implementierung von GuardServer
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse GuardServer {
privater String Servername;
public GuardServer(String servername) {
this.servername = Servername;
}
public void startServer(String cmd) löst eine Ausnahme aus {
System.out.println("Server starten: " + cmd);
//separate Befehle
// String[] cmds = cmd.split(" ");
// ProcessBuilder builder = new ProcessBuilder(cmds);
//
ProcessBuilder builder=new ProcessBuilder(new String[]{"/bin/sh","-c",cmd});
//Suchen Sie die Ausgabe des Serverprogramms in /dev/tty
builder.redirectOutput(new File("/dev/tty"));
builder.redirectError(new File("/dev/tty"));
builder.start(); // löst eine IOException aus
Thread.sleep(10000);
}
/**
* Überprüfen Sie, ob der Dienst vorhanden ist
*
* @return Gibt die PID des konfigurierten Java-Programms zurück
* @return pid >0 gibt pid <=0 zurück, was bedeutet, dass das angegebene Java-Programm nicht ausgeführt wird.
* **/
public int checkServer() löst eine Ausnahme aus {
int pid = -1;
Prozess Prozess = null;
BufferedReader-Reader = null;
Process = Runtime.getRuntime().exec("jps -l");
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String-Linie;
while ((line = reader.readLine()) != null) {
String[] strings = line.split("//s{1,}");
if (strings. length < 2)
weitermachen;
if (strings[1].contains(servername)) {
pid = Integer.parseInt(strings[0]);
brechen;
}
}
reader.close();
Process.destroy();
Rückgabe-PID;
}
}
3. GuardAMain-Implementierung
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse GuardAMain {
public static void main(String[] args) löst eine Ausnahme aus {
GuardA GuardA = new GuardA();
Konfigurieren configure = new Konfigurieren();
GuardServer server = new GuardServer(configure.getServername());
while (wahr) {
// GuardB ausführen, wenn GuardB nicht ausgeführt wird
if (!guardA.checkGuardB()) {
System.out.println("Start GuardB....");
Runtime.getRuntime().exec(configure.getStartguardb());
}
// Überleben des Servers prüfen
if (server.checkServer() <= 0) {
boolean isServerDown = true;
// Reisecheck
for (int i = 0; i < 3; i++) {
// Wenn der Dienst aktiv ist
if (server.checkServer() > 0) {
isServerDown = false;
brechen;
}
}
if(isServerDown)
server.startServer(configure.getStartserver());
}
Thread.sleep(configure.getInterval());
}
}
}
4. Implementierung herunterfahren
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse ShutDown {
public static void main(String[] args) löst eine Ausnahme aus {
Konfigurieren configure = new Konfigurieren();
System.out.println("Shutdown Guards..");
for (int i = 0; i < 3; i++) {
Prozess p = Runtime.getRuntime().exec("jps -l");
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String-Linie;
while ((line = reader.readLine()) != null) {
if (line.toLowerCase().contains("Guard".toLowerCase())) {
String[] strings = line.split("//s{1,}");
int pid = Integer.parseInt(strings[0]);
Runtime.getRuntime().exec(configure.getKillcmd() + " " + pid);
}
}
p.waitFor();
reader.close();
p.destroy();
Thread.sleep(2000);
}
System.out.println("Guards wird heruntergefahren");
}
}
5. GuardB ähnelt GuardA
5. Herunterladen und verwenden
Projektordner: Guard_demo
Download-Adresse: http://pan.baidu.com/s/1bn1Y6BX
Wenn Sie Fragen oder Anregungen haben, kontaktieren Sie mich bitte