最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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ì),希望對大家有所幫助

一、簡介

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

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

二、技術(shù)講解

這里的技術(shù)講解比較粗略,具體請百度一下,這里只講解作用。
1、jps命令。
  JDK自帶的命令工具,使用jps -l可以列出正在運(yùn)行的Java程序,顯示Java程序的pid與Name。只對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)行,然后返回信息。但是硬編碼會導(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是否存活,沒有就啟動B
2.B判斷A是否存活,沒有就啟動A
3.在運(yùn)行過程中A與B互相去拿對方的文件鎖,如果拿到了,證明對面掛了,則啟動對方。
4.A啟動的時(shí)候,獲取A.lock文件的鎖,如果拿到了證明沒有A啟動,則A運(yùn)行;如果沒有拿到鎖,證明A已經(jīng)啟動了,或者是B判斷的時(shí)候拿到了鎖,如果是A已經(jīng)啟動了,不需要再次啟動A,如果是B判斷的時(shí)候拿到了鎖,沒關(guān)緊  要,反正B會再次啟動A。
5.B啟動的時(shí)候原理與A一致。
6.運(yùn)行中如果A掛了,B判斷到A已經(jī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檢測到Server已經(jīng)掛了,就啟動Server
4.如果Server與A都掛了,B會啟動A,然后A啟動Server
5.如果Server與B掛了,A啟動Server與B
6.如果A與B都掛了,守護(hù)結(jié)束

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

四、實(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用于檢測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已啟動則退出
         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();
     }
 
     /**
      * 檢測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);
     }
 
     /**
      * 檢測服務(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());
             }
             // 檢測服務(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

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

相關(guān)文章

  • 深入理解Java設(shè)計(jì)模式之狀態(tài)模式

    深入理解Java設(shè)計(jì)模式之狀態(tài)模式

    這篇文章主要介紹了JAVA設(shè)計(jì)模式之職責(zé)鏈模式的的相關(guān)資料,文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解
    2021-11-11
  • Java如何加載外部Jar的類并通過反射調(diào)用類的方法

    Java如何加載外部Jar的類并通過反射調(diào)用類的方法

    這篇文章主要介紹了Java如何加載外部Jar的類并通過反射調(diào)用類的方法,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • logback日志輸出格式設(shè)置方式

    logback日志輸出格式設(shè)置方式

    這篇文章主要介紹了logback日志輸出格式設(shè)置方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Struts2 漏洞分析及如何提前預(yù)防

    Struts2 漏洞分析及如何提前預(yù)防

    2016年4月26日,Struts2發(fā)布一份安全公告,CVE編號 CVE-2016-3081。這是自2012年Struts2命令執(zhí)行漏洞大規(guī)模爆發(fā)之后,該服務(wù)時(shí)隔四年再次爆發(fā)大規(guī)模漏洞。該漏洞也是今年目前爆出的最嚴(yán)重安全漏洞。本文分析了漏洞的原理危害影響防護(hù)等內(nèi)容。
    2016-05-05
  • SpringBoot請求響應(yīng)方式示例詳解

    SpringBoot請求響應(yīng)方式示例詳解

    這篇文章主要介紹了SpringBoot請求響應(yīng)的相關(guān)操作,本文通過示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • Java小白第一次就能看懂的網(wǎng)絡(luò)編程

    Java小白第一次就能看懂的網(wǎng)絡(luò)編程

    網(wǎng)絡(luò)編程是指編寫運(yùn)行在多個(gè)設(shè)備(計(jì)算機(jī))的程序,這些設(shè)備都通過網(wǎng)絡(luò)連接起來。本文介紹了一些網(wǎng)絡(luò)編程基礎(chǔ)的概念,并用Java來實(shí)現(xiàn)TCP和UDP的Socket的編程,來讓讀者更好的了解其原理
    2021-08-08
  • Java實(shí)現(xiàn)簡單推箱子游戲

    Java實(shí)現(xiàn)簡單推箱子游戲

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)推箱子游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • 從基礎(chǔ)學(xué)java--數(shù)組

    從基礎(chǔ)學(xué)java--數(shù)組

    數(shù)組是相同類型數(shù)據(jù)的有序集合數(shù)組描述的是相同類型的若干個(gè)數(shù)據(jù),按照一定的先后次序排列組合而成。其中,每一個(gè)數(shù)據(jù)稱作一個(gè)數(shù)組元素,每個(gè)數(shù)組元素可以通過一個(gè)下標(biāo)來訪問它們數(shù)組的聲明創(chuàng)建
    2021-09-09
  • SpringBoot自定義Starter與自動配置實(shí)現(xiàn)方法詳解

    SpringBoot自定義Starter與自動配置實(shí)現(xiàn)方法詳解

    在Spring Boot官網(wǎng)為了簡化我們的開發(fā),已經(jīng)提供了非常多場景的Starter來為我們使用,即便如此,也無法全面的滿足我們實(shí)際工作中的開發(fā)場景,這時(shí)我們就需要自定義實(shí)現(xiàn)定制化的Starter
    2023-02-02
  • 一文詳解Java屬性為什么不能是is開頭的boolean

    一文詳解Java屬性為什么不能是is開頭的boolean

    在Java實(shí)體類定義中,boolean類型的屬性命名常引發(fā)爭議,阿里巴巴Java開發(fā)手冊建議避免使用is作為布爾類型屬性的前綴,原因在于當(dāng)實(shí)體類被序列化或反序列化時(shí),基于JavaBean規(guī)范的框架可能會移除或忽略is,導(dǎo)致不一致的字段名,文中介紹的非常詳細(xì),需要的朋友可以參考下
    2024-10-10

最新評論

深圳市| 分宜县| 漳州市| 札达县| 禹州市| 城口县| 新津县| 扎赉特旗| 商河县| 慈溪市| 克拉玛依市| 科技| 平果县| 遵义县| 南通市| 新营市| 昌宁县| 抚远县| 留坝县| 罗山县| 海南省| 年辖:市辖区| 通化市| 遂川县| 大厂| 城步| 景德镇市| 龙井市| 冷水江市| 宜兰县| 高淳县| 福鼎市| 礼泉县| 马关县| 新邵县| 南阳市| 东乡县| 凤翔县| 宜兰县| 礼泉县| 东源县|