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

Java動(dòng)態(tài)修改配置即時(shí)生效的方式WatchService

 更新時(shí)間:2018年06月24日 11:46:30   作者:風(fēng)的姿態(tài)  
這篇文章給大家分享了Java動(dòng)態(tài)修改配置即時(shí)生效的方式WatchService的相關(guān)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友可以參考學(xué)習(xí)下。

這種方式僅適合于比較小的項(xiàng)目,例如只有一兩臺(tái)服務(wù)器,而且配置文件是可以直接修改的。例如 Spring mvc 以 war 包的形式部署,可以直接修改resources 中的配置文件。如果是 Spring boot 項(xiàng)目,還想用這種方式的話,就要引用一個(gè)外部可以編輯的文件,比如一個(gè)固定的目錄,因?yàn)?spring boot 大多數(shù)以 jar 包部署,打到包里的配置文件沒(méi)辦法直接修改。如果是比較大的項(xiàng)目,最好還是用配置中心,例如攜程的 Apollo、Consul 等。

原始方式

原始方式指的是每次要修改配置的時(shí)候,都要重新打包發(fā)布或者重啟服務(wù)器。

假設(shè)我們用 spring mvc 開(kāi)發(fā),開(kāi)發(fā)完成后打成 war 包部署到 tomcat 上,如果這時(shí)我們修改一個(gè)短信接口地址。

我們要做如下操作:

1、打開(kāi)配置文件,修改配置信息;

2、編譯打包;

3、停止 tomcat ,刪除舊的項(xiàng)目目錄;

4、將新的 war 包放到 webapps ,啟動(dòng) tomcat。

當(dāng)然,可以直接在 tomcat 中找到這個(gè)項(xiàng)目的配置文件,然后修改,但同樣需要重啟 tomcat 。

如果只是單純做開(kāi)發(fā)或者測(cè)試,除了有點(diǎn)浪費(fèi)時(shí)間外,當(dāng)然可以接受。那么,既不想浪費(fèi)時(shí)間又不想重啟 tomcat 呢,有沒(méi)有辦法呢。這就輪到本文介紹的這種方式了。

WatchService 方式

Java 提供了 WatchService 接口,這個(gè)接口是利用操作系統(tǒng)本身的文件監(jiān)控器對(duì)目錄和文件進(jìn)行監(jiān)控,當(dāng)被監(jiān)控對(duì)象發(fā)生變化時(shí),會(huì)有信號(hào)通知,從而可以高效的發(fā)現(xiàn)變化。

這種方式大致的原理:先根據(jù)操作系統(tǒng) new 一個(gè)監(jiān)控器( WatchService ),然后選擇要監(jiān)控的配置文件所在目錄或文件,然后訂閱要監(jiān)控的事件,例如創(chuàng)建、刪除、編輯,最后向被監(jiān)控位置注冊(cè)這個(gè)監(jiān)控器。一旦觸發(fā)對(duì)應(yīng)我們所訂閱的事件時(shí),執(zhí)行相應(yīng)的邏輯即可。

先上代碼吧,這是在一個(gè) spring mvc 項(xiàng)目里,監(jiān)控的是 resources 目錄。

@Repository
public class ConfigWatcher {

  private static final Logger logger = LoggerFactory.getLogger(ConfigWatcher.class);

  private static WatchService watchService;

  @PostConstruct
  public void init() {
    logger.info("啟動(dòng)配置文件監(jiān)控器");
    try {
      watchService = FileSystems.getDefault().newWatchService();
      URL url = ConfigWatcher.class.getResource("/");
      Path path = Paths.get(url.toURI());
      path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE);
    } catch (Exception e1) {
      e1.printStackTrace();
    }

    /**
     * 啟動(dòng)監(jiān)控線程
     */
    Thread watchThread = new Thread(new WatchThread());
    watchThread.setDaemon(true);
    watchThread.start();

    /**注冊(cè)關(guān)閉鉤子*/
    Thread hook = new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          watchService.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    });
    Runtime.getRuntime().addShutdownHook(hook);
  }

  public class WatchThread implements Runnable {
    @Override
    public void run() {
      while (true) {
        try {
          // 嘗試獲取監(jiān)控池的變化,如果沒(méi)有則一直等待
          WatchKey watchKey = watchService.take();
          for (WatchEvent<?> event : watchKey.pollEvents()) {
            String editFileName = event.context().toString();
            logger.info(editFileName);
            /**
             * 重新加載配置
             */
          }
          watchKey.reset();//完成一次監(jiān)控就需要重置監(jiān)控器一次
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
  }
}

代碼非常簡(jiǎn)單,一看就懂,在項(xiàng)目啟動(dòng)的時(shí)候,用 FileSystems.getDefault().newWatchService() 創(chuàng)建一個(gè) WatchService,這是根據(jù)操作系統(tǒng)來(lái)的。然后獲取 resources 目錄的 URL,并由此獲取 Path,然后調(diào)用 Path 對(duì)象的 register 方法,注冊(cè)監(jiān)控器,訂閱了編輯和創(chuàng)建事件。事件在 StandardWatchEventKinds 類中定義,共有四種:

1、StandardWatchEventKinds#OVERFLOW

2、StandardWatchEventKinds#ENTRY_CREATE

3、StandardWatchEventKinds#ENTRY_DELETE

4、StandardWatchEventKinds#ENTRY_MODIFY

然后單獨(dú)啟動(dòng)了一個(gè) WatchThread 線程來(lái)處理變化邏輯,在一個(gè) while 無(wú)限循環(huán)中調(diào)用 take() 方法,直到有變化發(fā)生,一旦是我們監(jiān)控的配置文件發(fā)生了變化,則調(diào)用我們的邏輯重新加載配置。另外,每次有變化發(fā)生后,要調(diào)用 watchKey.reset() 方法來(lái)重置監(jiān)控器。

最后,還要注冊(cè)一個(gè) hook,在 jvm 關(guān)閉的時(shí)候可以關(guān)閉監(jiān)控器。

有了這種方式,當(dāng)我們有一些配置變化的時(shí)候,就可以直接到 tomcat 下修改配置文件,不用重啟就可以生效了。

本文主要介紹的是這種方式,上面也說(shuō)了,這種方式只適合非常簡(jiǎn)單的項(xiàng)目,對(duì)于大型項(xiàng)目,就需要用到更高級(jí)的方式了。

配置中心的方式

當(dāng)項(xiàng)目復(fù)雜度變高,配置修改后實(shí)時(shí)生效,灰度發(fā)布,分環(huán)境、分集群管理配置,完善的權(quán)限、審核機(jī)制可能都變成項(xiàng)目中要考慮的問(wèn)題,這個(gè)時(shí)候,單純依賴配置文件就顯得力不從心了。

目前比較用的比較多的配置中心有etcd、zookeeper、disconf、Apollo 等。disconf、Apollo 都是屬于拿來(lái)即用的,功能完善,而且有配套的 UI。而 etcd 和 zookeeper 需要一些定制開(kāi)發(fā)。

各位同學(xué)可以根據(jù)需要自行選擇,更詳細(xì)的內(nèi)容可以自行搜索和實(shí)踐。

相關(guān)文章

  • Java?詳細(xì)分析四個(gè)經(jīng)典鏈表面試題

    Java?詳細(xì)分析四個(gè)經(jīng)典鏈表面試題

    兄弟們,編程,當(dāng)我們學(xué)習(xí)完數(shù)據(jù)結(jié)構(gòu)的時(shí)候,你就會(huì)有一種豁然開(kāi)朗的感覺(jué)。算是真正的入了編程的門,所以打好數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ)是特別特別重要的
    2022-03-03
  • 深入理解Java設(shè)計(jì)模式之適配器模式

    深入理解Java設(shè)計(jì)模式之適配器模式

    這篇文章主要介紹了JAVA設(shè)計(jì)模式之適配器模式的的相關(guān)資料,文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解
    2021-11-11
  • 基于Java的正則表達(dá)式

    基于Java的正則表達(dá)式

    正則表達(dá)式,又稱正規(guī)表示法、常規(guī)表示法(英語(yǔ):Regular Expression,在代碼中常簡(jiǎn)寫為regex、regexp或RE),計(jì)算機(jī)科學(xué)的一個(gè)概念
    2017-05-05
  • java類中元素初始化順序詳解

    java類中元素初始化順序詳解

    對(duì)于靜態(tài)變量、靜態(tài)初始化塊、變量、初始化塊、構(gòu)造器,它們的初始化順序依次是(靜態(tài)變量、靜態(tài)初始化塊)>(變量、初始化塊)>構(gòu)造器
    2013-08-08
  • Java單鏈表反轉(zhuǎn)圖文教程

    Java單鏈表反轉(zhuǎn)圖文教程

    這篇文章主要給大家介紹了關(guān)于Java單鏈表反轉(zhuǎn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Java參數(shù)校驗(yàn)中validation和validator的區(qū)別詳解

    Java參數(shù)校驗(yàn)中validation和validator的區(qū)別詳解

    這篇文章主要介紹了Java參數(shù)校驗(yàn)中validation和validator的區(qū)別詳解,一般對(duì)于復(fù)雜的業(yè)務(wù)參數(shù)校驗(yàn),可以通過(guò)校驗(yàn)類單獨(dú)的校驗(yàn)方法進(jìn)行處理,通常對(duì)于一些與業(yè)務(wù)無(wú)關(guān)簡(jiǎn)單的參數(shù)校驗(yàn)可以采用validation和 validator通過(guò)注解的方式實(shí)現(xiàn)校驗(yàn),需要的朋友可以參考下
    2023-10-10
  • Spring注解解析之@ImportResource

    Spring注解解析之@ImportResource

    之前我們使用spring,最多的還是通過(guò)xml配置文件的方式來(lái)配置spring bean等內(nèi)容,隨著注解的廣泛應(yīng)用和spring4中Java config的引入,xml配置文件方式逐步被替換,但是如果是想要使用xml配置文件方式的話,也可以通過(guò)@ImportResource注解來(lái)實(shí)現(xiàn),下面我們來(lái)一起看下如何使用.
    2021-05-05
  • 淺談spring DI 依賴注入方式和區(qū)別

    淺談spring DI 依賴注入方式和區(qū)別

    Spring框架對(duì)Java開(kāi)發(fā)的重要性不言而喻,本文主要介紹了spring DI 依賴注入方式和區(qū)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • commons fileupload實(shí)現(xiàn)文件上傳的實(shí)例代碼

    commons fileupload實(shí)現(xiàn)文件上傳的實(shí)例代碼

    這篇文章主要介紹了commons fileupload實(shí)現(xiàn)文件上傳的實(shí)例代碼,包括文件上傳的原理分析等相關(guān)知識(shí)點(diǎn),本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧
    2016-10-10
  • SpringMVC整合websocket實(shí)現(xiàn)消息推送及觸發(fā)功能

    SpringMVC整合websocket實(shí)現(xiàn)消息推送及觸發(fā)功能

    這篇文章主要為大家詳細(xì)介紹了SpringMVC整合websocket實(shí)現(xiàn)消息推送及觸發(fā)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03

最新評(píng)論

福贡县| 景洪市| 和龙市| 峨山| 丰都县| 冀州市| 板桥市| 石林| 华亭县| 江城| 巴南区| 鱼台县| 昌都县| 古丈县| 东至县| 右玉县| 普安县| 河南省| 阿图什市| 旬邑县| 乐业县| 巴林左旗| 贵定县| 鄂伦春自治旗| 宁武县| 东莞市| 化德县| 肇庆市| 阿拉善盟| 六盘水市| 内丘县| 济源市| 汽车| 兰州市| 襄垣县| 镇江市| 郸城县| 墨脱县| 博湖县| 泰宁县| 蕲春县|