欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)Linux下雙守護(hù)進(jìn)程

 更新時(shí)間:2014年10月28日 14:28:23   投稿:hebedich  
這篇文章主要介紹了Java實(shí)現(xiàn)Linux下雙守護(hù)進(jìn)程的思路、原理以及具體實(shí)現(xiàn)方式,非常的詳細(xì),希望對(duì)大家有所幫助

一、簡(jiǎn)介

  現(xiàn)在的服務(wù)器端程序很多都是基于Java開發(fā),針對(duì)于Java開發(fā)的Socket程序,這樣的服務(wù)器端上線后出現(xiàn)問(wèn)題需要手動(dòng)重啟,萬(wàn)一大半夜的掛了,還是特別麻煩的。
  大多數(shù)的解決方法是使用其他進(jìn)程來(lái)守護(hù)服務(wù)器程序,如果服務(wù)器程序掛了,通過(guò)守護(hù)進(jìn)程來(lái)啟動(dòng)服務(wù)器程序。
  萬(wàn)一守護(hù)進(jìn)程掛了呢?使用雙守護(hù)來(lái)提高穩(wěn)定性,守護(hù)A負(fù)責(zé)監(jiān)控服務(wù)器程序與守護(hù)B,守護(hù)B負(fù)責(zé)監(jiān)控守護(hù)A,任何一方出現(xiàn)問(wèn)題,都能快速的啟動(dòng)程序,提高服務(wù)器程序的穩(wěn)定性。

  Java的運(yùn)行環(huán)境不同于C等語(yǔ)言開發(fā)的程序,Java程序跑在JVM上面。不同于C語(yǔ)言可以直接創(chuàng)建進(jìn)程,Java創(chuàng)建一個(gè)進(jìn)程等同于使用java -jar xxx.jar啟動(dòng)一個(gè)程序。
  Java啟動(dòng)程序并沒(méi)有C#類似的單實(shí)例限制,你可以啟動(dòng)多個(gè),但是你不能啟動(dòng)多個(gè),不能讓多個(gè)守護(hù)A去守護(hù)服務(wù)器程序,萬(wàn)一啟動(dòng)了多個(gè)服務(wù)器程序怎么辦?

二、技術(shù)講解

這里的技術(shù)講解比較粗略,具體請(qǐng)百度一下,這里只講解作用。
1、jps命令。
  JDK自帶的命令工具,使用jps -l可以列出正在運(yùn)行的Java程序,顯示Java程序的pid與Name。只對(duì)Java程序有效,其實(shí)查看的是運(yùn)行的JVM
2、java.nio.channels.FileLock類的使用
  這個(gè)是Java new IO中的類,使用他可以維持在讀取文件的給文件加上鎖,判斷文件時(shí)候有鎖可以判斷該文件是否被其他的程序使用
3、ProcessBuilder與Process
  這兩個(gè)原理差不多,都是調(diào)用系統(tǒng)的命令運(yùn)行,然后返回信息。但是硬編碼會(huì)導(dǎo)致你的Java程序失去可移植性,可以將命令獨(dú)立到配置文件中。

三、設(shè)計(jì)原理

Server:服務(wù)器程序
A:守護(hù)進(jìn)程A
B:守護(hù)進(jìn)程B
A.lock:守護(hù)進(jìn)程A的文件鎖
B.lock:守護(hù)進(jìn)程B的文件鎖
----------------------------------------------------------------------------------
Step 1:首先不考慮Server,只考慮A與B之間的守護(hù)
1.A判斷B是否存活,沒(méi)有就啟動(dòng)B
2.B判斷A是否存活,沒(méi)有就啟動(dòng)A
3.在運(yùn)行過(guò)程中A與B互相去拿對(duì)方的文件鎖,如果拿到了,證明對(duì)面掛了,則啟動(dòng)對(duì)方。
4.A啟動(dòng)的時(shí)候,獲取A.lock文件的鎖,如果拿到了證明沒(méi)有A啟動(dòng),則A運(yùn)行;如果沒(méi)有拿到鎖,證明A已經(jīng)啟動(dòng)了,或者是B判斷的時(shí)候拿到了鎖,如果是A已經(jīng)啟動(dòng)了,不需要再次啟動(dòng)A,如果是B判斷的時(shí)候拿到了鎖,沒(méi)關(guān)緊  要,反正B會(huì)再次啟動(dòng)A。
5.B啟動(dòng)的時(shí)候原理與A一致。
6.運(yùn)行中如果A掛了,B判斷到A已經(jīng)掛了,則啟動(dòng)A。B同理。

Step 2:加入Server
1.A用于守護(hù)B和Server,B用于守護(hù)A。
2.原理與Step 1 一致,只是A多個(gè)一個(gè)守護(hù)Serer的任務(wù)。
3.當(dāng)A運(yùn)行的時(shí)候,使用進(jìn)程pid檢測(cè)到Server已經(jīng)掛了,就啟動(dòng)Server
4.如果Server與A都掛了,B會(huì)啟動(dòng)A,然后A啟動(dòng)Server
5.如果Server與B掛了,A啟動(dòng)Server與B
6.如果A與B都掛了,守護(hù)結(jié)束

Step 3:使用Shutdown結(jié)束守護(hù),不然結(jié)束Server后會(huì)自動(dòng)啟動(dòng)

四、實(shí)現(xiàn)
1、GuardA的實(shí)現(xiàn)

復(fù)制代碼 代碼如下:

 public class GuardA {
     // GuardA用于維持自己的鎖
     private File fileGuardA;
     private FileOutputStream fileOutputStreamGuardA;
     private FileChannel fileChannelGuardA;
     private FileLock fileLockGuardA;
     // GuardB用于檢測(cè)B的鎖
     private File fileGuardB;
     private FileOutputStream fileOutputStreamGuardB;
     private FileChannel fileChannelGuardB;
     private FileLock fileLockGuardB;
 
     public GuardA() throws Exception {
         fileGuardA = new File(Configure.GUARD_A_LOCK);
         if (!fileGuardA.exists()) {
             fileGuardA.createNewFile();
         }
         //獲取文件鎖,拿不到證明GuardA已啟動(dòng)則退出
         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();
     }
 
     /**
      * 檢測(cè)B是否存在
      *
      * @return true B已經(jīng)存在
      */
     public boolean checkGuardB() {
         try {
             fileLockGuardB = fileChannelGuardB.tryLock();
             if (fileLockGuardB == null) {
                 return true;
             } else {
                 fileLockGuardB.release();
                 return false;
             }
         } catch (IOException e) {
             System.exit(0);
             // never touch
             return true;
         }
     }
 }

2、GuardServer的實(shí)現(xiàn)

復(fù)制代碼 代碼如下:

 public class GuardServer {
     private String servername;
 
     public GuardServer(String servername) {
         this.servername = servername;
     }
 
     public void startServer(String cmd) throws Exception {
         System.out.println("Start Server : " + cmd);
         //將命令分開
 //        String[] cmds = cmd.split(" ");
 //        ProcessBuilder builder = new ProcessBuilder(cmds);
    
         //
         ProcessBuilder builder=new ProcessBuilder(new String[]{"/bin/sh","-c",cmd});
         //將服務(wù)器程序的輸出定位到/dev/tty
         builder.redirectOutput(new File("/dev/tty"));
         builder.redirectError(new File("/dev/tty"));
         builder.start(); // throws IOException
         Thread.sleep(10000);
     }
 
     /**
      * 檢測(cè)服務(wù)是否存在
      *
      * @return 返回配置的java程序的pid
      * @return pid >0 返回的是 pid <=0 代表指定java程序未運(yùn)行
      * **/
     public int checkServer() throws Exception {
         int pid = -1;
         Process process = null;
         BufferedReader reader = null;
         process = Runtime.getRuntime().exec("jps -l");
         reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
         String line;
         while ((line = reader.readLine()) != null) {
             String[] strings = line.split("\\s{1,}");
             if (strings.length < 2)
                 continue;
             if (strings[1].contains(servername)) {
                 pid = Integer.parseInt(strings[0]);
                 break;
             }
         }
         reader.close();
         process.destroy();
         return pid;
     }
 }

3、GuardAMain實(shí)現(xiàn)

復(fù)制代碼 代碼如下:

 public class GuardAMain {
     public static void main(String[] args) throws Exception {
         GuardA guardA = new GuardA();
         Configure configure = new Configure();
         GuardServer server = new GuardServer(configure.getServername());
         while (true) {
             // 如果GuardB未運(yùn)行 運(yùn)行GuardB
             if (!guardA.checkGuardB()) {
                 System.out.println("Start GuardB.....");
                 Runtime.getRuntime().exec(configure.getStartguardb());
             }
             // 檢測(cè)服務(wù)器存活
             if (server.checkServer() <= 0) {
                 boolean isServerDown = true;
                 // trip check
                 for (int i = 0; i < 3; i++) {
                     // 如果服務(wù)是存活著
                     if (server.checkServer() > 0) {
                         isServerDown = false;
                         break;
                     }
                 }
                 if (isServerDown)
                     server.startServer(configure.getStartserver());
             }
             Thread.sleep(configure.getInterval());
         }
     }
 }

4、Shutdown實(shí)現(xiàn)

復(fù)制代碼 代碼如下:

 public class ShutDown {
     public static void main(String[] args) throws Exception {
         Configure configure = new Configure();
         System.out.println("Shutdown Guards..");
         for (int i = 0; i < 3; i++) {
             Process p = Runtime.getRuntime().exec("jps -l");
             BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
             String line;
             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 is shutdown");
     }
 }

5、GuardB與GuardA類似

五、下載與使用

項(xiàng)目文件夾:guard_demo

下載地址:http://pan.baidu.com/s/1bn1Y6BX

如果有什么疑問(wèn)或者建議,請(qǐng)聯(lián)系我

相關(guān)文章

  • SpringBoot中的@Value注解用法

    SpringBoot中的@Value注解用法

    這篇文章主要介紹了SpringBoot中的@Value注解用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • JavaWeb編程 Servlet的基本配置

    JavaWeb編程 Servlet的基本配置

    本文講的是Servlet最基本的配置信息,相信對(duì)你一定有幫助
    2013-11-11
  • 簡(jiǎn)單實(shí)現(xiàn)Java通訊錄系統(tǒng)

    簡(jiǎn)單實(shí)現(xiàn)Java通訊錄系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了如何簡(jiǎn)單實(shí)現(xiàn)Java通訊錄系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • Java for循環(huán)性能優(yōu)化實(shí)現(xiàn)解析

    Java for循環(huán)性能優(yōu)化實(shí)現(xiàn)解析

    這篇文章主要介紹了Java for循環(huán)性能優(yōu)化實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 使用dubbo+zookeeper+spring boot構(gòu)建服務(wù)的方法詳解

    使用dubbo+zookeeper+spring boot構(gòu)建服務(wù)的方法詳解

    這篇文章主要給大家介紹了關(guān)于如何使用dubbo+zookeeper+spring boot構(gòu)建服務(wù)的相關(guān)資料,文中通過(guò)示例代碼及圖片介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05
  • java線程安全鎖ReentrantReadWriteLock原理分析readLock

    java線程安全鎖ReentrantReadWriteLock原理分析readLock

    這篇文章主要為大家介紹了java線程安全鎖ReentrantReadWriteLock原理分析readLock,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • Spring boot2+jpa+thymeleaf實(shí)現(xiàn)增刪改查

    Spring boot2+jpa+thymeleaf實(shí)現(xiàn)增刪改查

    這篇文章主要介紹了Spring boot2+jpa+thymeleaf實(shí)現(xiàn)增刪改查,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 解決FastJson中

    解決FastJson中"$ref重復(fù)引用"的問(wèn)題方法

    這篇文章主要介紹了解決FastJson中"$ref重復(fù)引用"的問(wèn)題方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • 詳解關(guān)于springboot-actuator監(jiān)控的401無(wú)權(quán)限訪問(wèn)

    詳解關(guān)于springboot-actuator監(jiān)控的401無(wú)權(quán)限訪問(wèn)

    本篇文章主要介紹了詳解關(guān)于springboot-actuator監(jiān)控的401無(wú)權(quán)限訪問(wèn),非常具有實(shí)用價(jià)值,有興趣的可以了解一下
    2017-09-09
  • idea中Tomcat啟動(dòng)失敗的解決

    idea中Tomcat啟動(dòng)失敗的解決

    這篇文章主要介紹了idea中Tomcat啟動(dòng)失敗的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-09-09

最新評(píng)論